src/java.base/share/classes/java/lang/invoke/Invokers.java

Print this page
rev 17771 : 8184777: species logic for BoundMethodHandle doesn't scale, needs refactor


 284         final int ARG_BASE     = CALL_MH + 1;
 285         final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
 286         final int INARG_LIMIT  = OUTARG_LIMIT + (isLinker && !customized ? 1 : 0);
 287         int nameCursor = OUTARG_LIMIT;
 288         final int MTYPE_ARG    = customized ? -1 : nameCursor++;  // might be last in-argument
 289         final int CHECK_TYPE   = nameCursor++;
 290         final int CHECK_CUSTOM = (CUSTOMIZE_THRESHOLD >= 0) ? nameCursor++ : -1;
 291         final int LINKER_CALL  = nameCursor++;
 292         MethodType invokerFormType = mtype.invokerType();
 293         if (isLinker) {
 294             if (!customized)
 295                 invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
 296         } else {
 297             invokerFormType = invokerFormType.invokerType();
 298         }
 299         Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
 300         assert(names.length == nameCursor)
 301                 : Arrays.asList(mtype, customized, which, nameCursor, names.length);
 302         if (MTYPE_ARG >= INARG_LIMIT) {
 303             assert(names[MTYPE_ARG] == null);
 304             BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L();
 305             names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
 306             NamedFunction getter = speciesData.getterFunction(0);
 307             names[MTYPE_ARG] = new Name(getter, names[THIS_MH]);
 308             // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
 309         }
 310 
 311         // Make the final call.  If isGeneric, then prepend the result of type checking.
 312         MethodType outCallType = mtype.basicType();
 313         Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
 314         Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
 315         if (!isGeneric) {
 316             names[CHECK_TYPE] = new Name(getFunction(NF_checkExactType), names[CALL_MH], mtypeArg);
 317             // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
 318         } else {
 319             names[CHECK_TYPE] = new Name(getFunction(NF_checkGenericType), names[CALL_MH], mtypeArg);
 320             // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
 321             outArgs[0] = names[CHECK_TYPE];
 322         }
 323         if (CHECK_CUSTOM != -1) {
 324             names[CHECK_CUSTOM] = new Name(getFunction(NF_checkCustomized), outArgs[0]);


 396     private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode ak,
 397             MethodType mtype, boolean isExact) {
 398         // TODO Cache form?
 399 
 400         final int THIS_MH      = 0;
 401         final int CALL_VH      = THIS_MH + 1;
 402         final int ARG_BASE     = CALL_VH + 1;
 403         final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
 404         int nameCursor = ARG_LIMIT;
 405         final int VAD_ARG      = nameCursor++;
 406         final int CHECK_TYPE   = nameCursor++;
 407         final int LINKER_CALL  = nameCursor++;
 408 
 409         Name[] names = new Name[LINKER_CALL + 1];
 410         names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class));
 411         names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class));
 412         for (int i = 0; i < mtype.parameterCount(); i++) {
 413             names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
 414         }
 415 
 416         BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L();
 417         names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
 418 
 419         NamedFunction getter = speciesData.getterFunction(0);
 420         names[VAD_ARG] = new Name(getter, names[THIS_MH]);
 421 
 422         if (isExact) {
 423             names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleExactType), names[CALL_VH], names[VAD_ARG]);
 424         } else {
 425             names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleGenericType), names[CALL_VH], names[VAD_ARG]);
 426         }
 427         Object[] outArgs = new Object[ARG_LIMIT];
 428         outArgs[0] = names[CHECK_TYPE];
 429         for (int i = 1; i < ARG_LIMIT; i++) {
 430             outArgs[i] = names[i];
 431         }
 432 
 433         MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
 434                 .basicType();
 435         names[LINKER_CALL] = new Name(outCallType, outArgs);
 436         Kind kind = isExact ? VARHANDLE_EXACT_INVOKER : VARHANDLE_INVOKER;




 284         final int ARG_BASE     = CALL_MH + 1;
 285         final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
 286         final int INARG_LIMIT  = OUTARG_LIMIT + (isLinker && !customized ? 1 : 0);
 287         int nameCursor = OUTARG_LIMIT;
 288         final int MTYPE_ARG    = customized ? -1 : nameCursor++;  // might be last in-argument
 289         final int CHECK_TYPE   = nameCursor++;
 290         final int CHECK_CUSTOM = (CUSTOMIZE_THRESHOLD >= 0) ? nameCursor++ : -1;
 291         final int LINKER_CALL  = nameCursor++;
 292         MethodType invokerFormType = mtype.invokerType();
 293         if (isLinker) {
 294             if (!customized)
 295                 invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
 296         } else {
 297             invokerFormType = invokerFormType.invokerType();
 298         }
 299         Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
 300         assert(names.length == nameCursor)
 301                 : Arrays.asList(mtype, customized, which, nameCursor, names.length);
 302         if (MTYPE_ARG >= INARG_LIMIT) {
 303             assert(names[MTYPE_ARG] == null);
 304             BoundMethodHandle.BMHSpecies speciesData = BoundMethodHandle.speciesData_L();
 305             names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
 306             NamedFunction getter = speciesData.getterFunction(0);
 307             names[MTYPE_ARG] = new Name(getter, names[THIS_MH]);
 308             // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
 309         }
 310 
 311         // Make the final call.  If isGeneric, then prepend the result of type checking.
 312         MethodType outCallType = mtype.basicType();
 313         Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
 314         Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
 315         if (!isGeneric) {
 316             names[CHECK_TYPE] = new Name(getFunction(NF_checkExactType), names[CALL_MH], mtypeArg);
 317             // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
 318         } else {
 319             names[CHECK_TYPE] = new Name(getFunction(NF_checkGenericType), names[CALL_MH], mtypeArg);
 320             // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
 321             outArgs[0] = names[CHECK_TYPE];
 322         }
 323         if (CHECK_CUSTOM != -1) {
 324             names[CHECK_CUSTOM] = new Name(getFunction(NF_checkCustomized), outArgs[0]);


 396     private static LambdaForm varHandleMethodInvokerHandleForm(VarHandle.AccessMode ak,
 397             MethodType mtype, boolean isExact) {
 398         // TODO Cache form?
 399 
 400         final int THIS_MH      = 0;
 401         final int CALL_VH      = THIS_MH + 1;
 402         final int ARG_BASE     = CALL_VH + 1;
 403         final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
 404         int nameCursor = ARG_LIMIT;
 405         final int VAD_ARG      = nameCursor++;
 406         final int CHECK_TYPE   = nameCursor++;
 407         final int LINKER_CALL  = nameCursor++;
 408 
 409         Name[] names = new Name[LINKER_CALL + 1];
 410         names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class));
 411         names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class));
 412         for (int i = 0; i < mtype.parameterCount(); i++) {
 413             names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
 414         }
 415 
 416         BoundMethodHandle.BMHSpecies speciesData = BoundMethodHandle.speciesData_L();
 417         names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
 418 
 419         NamedFunction getter = speciesData.getterFunction(0);
 420         names[VAD_ARG] = new Name(getter, names[THIS_MH]);
 421 
 422         if (isExact) {
 423             names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleExactType), names[CALL_VH], names[VAD_ARG]);
 424         } else {
 425             names[CHECK_TYPE] = new Name(getFunction(NF_checkVarHandleGenericType), names[CALL_VH], names[VAD_ARG]);
 426         }
 427         Object[] outArgs = new Object[ARG_LIMIT];
 428         outArgs[0] = names[CHECK_TYPE];
 429         for (int i = 1; i < ARG_LIMIT; i++) {
 430             outArgs[i] = names[i];
 431         }
 432 
 433         MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
 434                 .basicType();
 435         names[LINKER_CALL] = new Name(outCallType, outArgs);
 436         Kind kind = isExact ? VARHANDLE_EXACT_INVOKER : VARHANDLE_INVOKER;