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;
|