src/share/classes/java/lang/invoke/DirectMethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang/invoke

src/share/classes/java/lang/invoke/DirectMethodHandle.java

Print this page
rev 7929 : 8024616: JSR292: lazily initialize core NamedFunctions used for bootstrapping
Reviewed-by: ?


 240             mtypeWithArg = mtypeWithArg
 241                     .insertParameterTypes(0, Object.class)  // insert newly allocated obj
 242                     .changeReturnType(void.class);          // <init> returns void
 243         MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
 244         try {
 245             linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
 246         } catch (ReflectiveOperationException ex) {
 247             throw newInternalError(ex);
 248         }
 249         final int DMH_THIS    = 0;
 250         final int ARG_BASE    = 1;
 251         final int ARG_LIMIT   = ARG_BASE + mtype.parameterCount();
 252         int nameCursor = ARG_LIMIT;
 253         final int NEW_OBJ     = (doesAlloc ? nameCursor++ : -1);
 254         final int GET_MEMBER  = nameCursor++;
 255         final int LINKER_CALL = nameCursor++;
 256         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
 257         assert(names.length == nameCursor);
 258         if (doesAlloc) {
 259             // names = { argx,y,z,... new C, init method }
 260             names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
 261             names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
 262         } else if (needsInit) {
 263             names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
 264         } else {
 265             names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]);
 266         }
 267         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
 268         assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
 269         int result = LambdaForm.LAST_RESULT;
 270         if (doesAlloc) {
 271             assert(outArgs[outArgs.length-2] == names[NEW_OBJ]);  // got to move this one
 272             System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
 273             outArgs[0] = names[NEW_OBJ];
 274             result = NEW_OBJ;
 275         }
 276         names[LINKER_CALL] = new Name(linker, outArgs);
 277         lambdaName += "_" + LambdaForm.basicTypeSignature(mtype);
 278         LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
 279         // This is a tricky bit of code.  Don't send it through the LF interpreter.
 280         lform.compileToBytecode();
 281         return lform;
 282     }
 283 
 284     private static void maybeCompile(LambdaForm lform, MemberName m) {
 285         if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))


 620         if (!isStatic)
 621             mtype = mtype.insertParameterTypes(0, Object.class);
 622         final int DMH_THIS  = 0;
 623         final int ARG_BASE  = 1;
 624         final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
 625         // if this is for non-static access, the base pointer is stored at this index:
 626         final int OBJ_BASE  = isStatic ? -1 : ARG_BASE;
 627         // if this is for write access, the value to be written is stored at this index:
 628         final int SET_VALUE  = isGetter ? -1 : ARG_LIMIT - 1;
 629         int nameCursor = ARG_LIMIT;
 630         final int F_HOLDER  = (isStatic ? nameCursor++ : -1);  // static base if any
 631         final int F_OFFSET  = nameCursor++;  // Either static offset or field offset.
 632         final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
 633         final int INIT_BAR  = (needsInit ? nameCursor++ : -1);
 634         final int PRE_CAST  = (needsCast && !isGetter ? nameCursor++ : -1);
 635         final int LINKER_CALL = nameCursor++;
 636         final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
 637         final int RESULT    = nameCursor-1;  // either the call or the cast
 638         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
 639         if (needsInit)
 640             names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
 641         if (needsCast && !isGetter)
 642             names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
 643         Object[] outArgs = new Object[1 + linkerType.parameterCount()];
 644         assert(outArgs.length == (isGetter ? 3 : 4));
 645         outArgs[0] = UNSAFE;
 646         if (isStatic) {
 647             outArgs[1] = names[F_HOLDER]  = new Name(NF_staticBase, names[DMH_THIS]);
 648             outArgs[2] = names[F_OFFSET]  = new Name(NF_staticOffset, names[DMH_THIS]);
 649         } else {
 650             outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
 651             outArgs[2] = names[F_OFFSET]  = new Name(NF_fieldOffset, names[DMH_THIS]);
 652         }
 653         if (!isGetter) {
 654             outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
 655         }
 656         for (Object a : outArgs)  assert(a != null);
 657         names[LINKER_CALL] = new Name(linker, outArgs);
 658         if (needsCast && isGetter)
 659             names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
 660         for (Name n : names)  assert(n != null);
 661         String fieldOrStatic = (isStatic ? "Static" : "Field");
 662         String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
 663         if (needsCast)  lambdaName += "Cast";
 664         if (needsInit)  lambdaName += "Init";
 665         return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
 666     }
 667 
 668     private static final NamedFunction





 669             NF_internalMemberName,
 670             NF_internalMemberNameEnsureInit,
 671             NF_ensureInitialized,
 672             NF_fieldOffset,
 673             NF_checkBase,
 674             NF_staticBase,
 675             NF_staticOffset,
 676             NF_checkCast,
 677             NF_allocateInstance,
 678             NF_constructorMethod;
 679     static {
 680         try {
 681             NamedFunction nfs[] = {
 682                 NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
 683                     .getDeclaredMethod("internalMemberName", Object.class)),
 684                 NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
 685                     .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
 686                 NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
 687                     .getDeclaredMethod("ensureInitialized", Object.class)),
 688                 NF_fieldOffset = new NamedFunction(DirectMethodHandle.class


 692                 NF_staticBase = new NamedFunction(DirectMethodHandle.class
 693                     .getDeclaredMethod("staticBase", Object.class)),
 694                 NF_staticOffset = new NamedFunction(DirectMethodHandle.class
 695                     .getDeclaredMethod("staticOffset", Object.class)),
 696                 NF_checkCast = new NamedFunction(DirectMethodHandle.class
 697                     .getDeclaredMethod("checkCast", Object.class, Object.class)),
 698                 NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
 699                     .getDeclaredMethod("allocateInstance", Object.class)),
 700                 NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
 701                     .getDeclaredMethod("constructorMethod", Object.class))
 702             };
 703             for (NamedFunction nf : nfs) {
 704                 // Each nf must be statically invocable or we get tied up in our bootstraps.
 705                 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
 706                 nf.resolve();
 707             }
 708         } catch (ReflectiveOperationException ex) {
 709             throw newInternalError(ex);
 710         }
 711     }

 712 }


 240             mtypeWithArg = mtypeWithArg
 241                     .insertParameterTypes(0, Object.class)  // insert newly allocated obj
 242                     .changeReturnType(void.class);          // <init> returns void
 243         MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
 244         try {
 245             linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
 246         } catch (ReflectiveOperationException ex) {
 247             throw newInternalError(ex);
 248         }
 249         final int DMH_THIS    = 0;
 250         final int ARG_BASE    = 1;
 251         final int ARG_LIMIT   = ARG_BASE + mtype.parameterCount();
 252         int nameCursor = ARG_LIMIT;
 253         final int NEW_OBJ     = (doesAlloc ? nameCursor++ : -1);
 254         final int GET_MEMBER  = nameCursor++;
 255         final int LINKER_CALL = nameCursor++;
 256         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
 257         assert(names.length == nameCursor);
 258         if (doesAlloc) {
 259             // names = { argx,y,z,... new C, init method }
 260             names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
 261             names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
 262         } else if (needsInit) {
 263             names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
 264         } else {
 265             names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
 266         }
 267         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
 268         assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
 269         int result = LambdaForm.LAST_RESULT;
 270         if (doesAlloc) {
 271             assert(outArgs[outArgs.length-2] == names[NEW_OBJ]);  // got to move this one
 272             System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
 273             outArgs[0] = names[NEW_OBJ];
 274             result = NEW_OBJ;
 275         }
 276         names[LINKER_CALL] = new Name(linker, outArgs);
 277         lambdaName += "_" + LambdaForm.basicTypeSignature(mtype);
 278         LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
 279         // This is a tricky bit of code.  Don't send it through the LF interpreter.
 280         lform.compileToBytecode();
 281         return lform;
 282     }
 283 
 284     private static void maybeCompile(LambdaForm lform, MemberName m) {
 285         if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))


 620         if (!isStatic)
 621             mtype = mtype.insertParameterTypes(0, Object.class);
 622         final int DMH_THIS  = 0;
 623         final int ARG_BASE  = 1;
 624         final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
 625         // if this is for non-static access, the base pointer is stored at this index:
 626         final int OBJ_BASE  = isStatic ? -1 : ARG_BASE;
 627         // if this is for write access, the value to be written is stored at this index:
 628         final int SET_VALUE  = isGetter ? -1 : ARG_LIMIT - 1;
 629         int nameCursor = ARG_LIMIT;
 630         final int F_HOLDER  = (isStatic ? nameCursor++ : -1);  // static base if any
 631         final int F_OFFSET  = nameCursor++;  // Either static offset or field offset.
 632         final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
 633         final int INIT_BAR  = (needsInit ? nameCursor++ : -1);
 634         final int PRE_CAST  = (needsCast && !isGetter ? nameCursor++ : -1);
 635         final int LINKER_CALL = nameCursor++;
 636         final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
 637         final int RESULT    = nameCursor-1;  // either the call or the cast
 638         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
 639         if (needsInit)
 640             names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]);
 641         if (needsCast && !isGetter)
 642             names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
 643         Object[] outArgs = new Object[1 + linkerType.parameterCount()];
 644         assert(outArgs.length == (isGetter ? 3 : 4));
 645         outArgs[0] = UNSAFE;
 646         if (isStatic) {
 647             outArgs[1] = names[F_HOLDER]  = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
 648             outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
 649         } else {
 650             outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]);
 651             outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]);
 652         }
 653         if (!isGetter) {
 654             outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
 655         }
 656         for (Object a : outArgs)  assert(a != null);
 657         names[LINKER_CALL] = new Name(linker, outArgs);
 658         if (needsCast && isGetter)
 659             names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
 660         for (Name n : names)  assert(n != null);
 661         String fieldOrStatic = (isStatic ? "Static" : "Field");
 662         String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
 663         if (needsCast)  lambdaName += "Cast";
 664         if (needsInit)  lambdaName += "Init";
 665         return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
 666     }
 667 
 668     /**
 669      * Pre-initialized NamedFunctions for bootstrapping purposes.
 670      * Factored in an inner class to delay initialization until first usage.
 671      */
 672     private static class Lazy {
 673         static final NamedFunction
 674                 NF_internalMemberName,
 675                 NF_internalMemberNameEnsureInit,
 676                 NF_ensureInitialized,
 677                 NF_fieldOffset,
 678                 NF_checkBase,
 679                 NF_staticBase,
 680                 NF_staticOffset,
 681                 NF_checkCast,
 682                 NF_allocateInstance,
 683                 NF_constructorMethod;
 684         static {
 685             try {
 686                 NamedFunction nfs[] = {
 687                         NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
 688                                 .getDeclaredMethod("internalMemberName", Object.class)),
 689                         NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
 690                                 .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
 691                         NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
 692                                 .getDeclaredMethod("ensureInitialized", Object.class)),
 693                         NF_fieldOffset = new NamedFunction(DirectMethodHandle.class


 697                         NF_staticBase = new NamedFunction(DirectMethodHandle.class
 698                                 .getDeclaredMethod("staticBase", Object.class)),
 699                         NF_staticOffset = new NamedFunction(DirectMethodHandle.class
 700                                 .getDeclaredMethod("staticOffset", Object.class)),
 701                         NF_checkCast = new NamedFunction(DirectMethodHandle.class
 702                                 .getDeclaredMethod("checkCast", Object.class, Object.class)),
 703                         NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
 704                                 .getDeclaredMethod("allocateInstance", Object.class)),
 705                         NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
 706                                 .getDeclaredMethod("constructorMethod", Object.class))
 707                 };
 708                 for (NamedFunction nf : nfs) {
 709                     // Each nf must be statically invocable or we get tied up in our bootstraps.
 710                     assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
 711                     nf.resolve();
 712                 }
 713             } catch (ReflectiveOperationException ex) {
 714                 throw newInternalError(ex);
 715             }
 716         }
 717     }
 718 }
src/share/classes/java/lang/invoke/DirectMethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File