jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java
changeset 20495 6586c2f78d57
parent 16484 f24cb2927b7a
child 24572 5c9e5961d21c
equal deleted inserted replaced
20494:cf77ae5ff678 20495:6586c2f78d57
   255         final int LINKER_CALL = nameCursor++;
   255         final int LINKER_CALL = nameCursor++;
   256         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
   256         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
   257         assert(names.length == nameCursor);
   257         assert(names.length == nameCursor);
   258         if (doesAlloc) {
   258         if (doesAlloc) {
   259             // names = { argx,y,z,... new C, init method }
   259             // names = { argx,y,z,... new C, init method }
   260             names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
   260             names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
   261             names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
   261             names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
   262         } else if (needsInit) {
   262         } else if (needsInit) {
   263             names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
   263             names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
   264         } else {
   264         } else {
   265             names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]);
   265             names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
   266         }
   266         }
   267         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
   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!
   268         assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
   269         int result = LambdaForm.LAST_RESULT;
   269         int result = LambdaForm.LAST_RESULT;
   270         if (doesAlloc) {
   270         if (doesAlloc) {
   635         final int LINKER_CALL = nameCursor++;
   635         final int LINKER_CALL = nameCursor++;
   636         final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
   636         final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
   637         final int RESULT    = nameCursor-1;  // either the call or the cast
   637         final int RESULT    = nameCursor-1;  // either the call or the cast
   638         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
   638         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
   639         if (needsInit)
   639         if (needsInit)
   640             names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
   640             names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]);
   641         if (needsCast && !isGetter)
   641         if (needsCast && !isGetter)
   642             names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
   642             names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
   643         Object[] outArgs = new Object[1 + linkerType.parameterCount()];
   643         Object[] outArgs = new Object[1 + linkerType.parameterCount()];
   644         assert(outArgs.length == (isGetter ? 3 : 4));
   644         assert(outArgs.length == (isGetter ? 3 : 4));
   645         outArgs[0] = UNSAFE;
   645         outArgs[0] = UNSAFE;
   646         if (isStatic) {
   646         if (isStatic) {
   647             outArgs[1] = names[F_HOLDER]  = new Name(NF_staticBase, names[DMH_THIS]);
   647             outArgs[1] = names[F_HOLDER]  = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
   648             outArgs[2] = names[F_OFFSET]  = new Name(NF_staticOffset, names[DMH_THIS]);
   648             outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
   649         } else {
   649         } else {
   650             outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
   650             outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]);
   651             outArgs[2] = names[F_OFFSET]  = new Name(NF_fieldOffset, names[DMH_THIS]);
   651             outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]);
   652         }
   652         }
   653         if (!isGetter) {
   653         if (!isGetter) {
   654             outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
   654             outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
   655         }
   655         }
   656         for (Object a : outArgs)  assert(a != null);
   656         for (Object a : outArgs)  assert(a != null);
   657         names[LINKER_CALL] = new Name(linker, outArgs);
   657         names[LINKER_CALL] = new Name(linker, outArgs);
   658         if (needsCast && isGetter)
   658         if (needsCast && isGetter)
   659             names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
   659             names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
   660         for (Name n : names)  assert(n != null);
   660         for (Name n : names)  assert(n != null);
   661         String fieldOrStatic = (isStatic ? "Static" : "Field");
   661         String fieldOrStatic = (isStatic ? "Static" : "Field");
   662         String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
   662         String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
   663         if (needsCast)  lambdaName += "Cast";
   663         if (needsCast)  lambdaName += "Cast";
   664         if (needsInit)  lambdaName += "Init";
   664         if (needsInit)  lambdaName += "Init";
   665         return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
   665         return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
   666     }
   666     }
   667 
   667 
   668     private static final NamedFunction
   668     /**
   669             NF_internalMemberName,
   669      * Pre-initialized NamedFunctions for bootstrapping purposes.
   670             NF_internalMemberNameEnsureInit,
   670      * Factored in an inner class to delay initialization until first usage.
   671             NF_ensureInitialized,
   671      */
   672             NF_fieldOffset,
   672     private static class Lazy {
   673             NF_checkBase,
   673         static final NamedFunction
   674             NF_staticBase,
   674                 NF_internalMemberName,
   675             NF_staticOffset,
   675                 NF_internalMemberNameEnsureInit,
   676             NF_checkCast,
   676                 NF_ensureInitialized,
   677             NF_allocateInstance,
   677                 NF_fieldOffset,
   678             NF_constructorMethod;
   678                 NF_checkBase,
   679     static {
   679                 NF_staticBase,
   680         try {
   680                 NF_staticOffset,
   681             NamedFunction nfs[] = {
   681                 NF_checkCast,
   682                 NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
   682                 NF_allocateInstance,
   683                     .getDeclaredMethod("internalMemberName", Object.class)),
   683                 NF_constructorMethod;
   684                 NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
   684         static {
   685                     .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
   685             try {
   686                 NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
   686                 NamedFunction nfs[] = {
   687                     .getDeclaredMethod("ensureInitialized", Object.class)),
   687                         NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
   688                 NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
   688                                 .getDeclaredMethod("internalMemberName", Object.class)),
   689                     .getDeclaredMethod("fieldOffset", Object.class)),
   689                         NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
   690                 NF_checkBase = new NamedFunction(DirectMethodHandle.class
   690                                 .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
   691                     .getDeclaredMethod("checkBase", Object.class)),
   691                         NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
   692                 NF_staticBase = new NamedFunction(DirectMethodHandle.class
   692                                 .getDeclaredMethod("ensureInitialized", Object.class)),
   693                     .getDeclaredMethod("staticBase", Object.class)),
   693                         NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
   694                 NF_staticOffset = new NamedFunction(DirectMethodHandle.class
   694                                 .getDeclaredMethod("fieldOffset", Object.class)),
   695                     .getDeclaredMethod("staticOffset", Object.class)),
   695                         NF_checkBase = new NamedFunction(DirectMethodHandle.class
   696                 NF_checkCast = new NamedFunction(DirectMethodHandle.class
   696                                 .getDeclaredMethod("checkBase", Object.class)),
   697                     .getDeclaredMethod("checkCast", Object.class, Object.class)),
   697                         NF_staticBase = new NamedFunction(DirectMethodHandle.class
   698                 NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
   698                                 .getDeclaredMethod("staticBase", Object.class)),
   699                     .getDeclaredMethod("allocateInstance", Object.class)),
   699                         NF_staticOffset = new NamedFunction(DirectMethodHandle.class
   700                 NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
   700                                 .getDeclaredMethod("staticOffset", Object.class)),
   701                     .getDeclaredMethod("constructorMethod", Object.class))
   701                         NF_checkCast = new NamedFunction(DirectMethodHandle.class
   702             };
   702                                 .getDeclaredMethod("checkCast", Object.class, Object.class)),
   703             for (NamedFunction nf : nfs) {
   703                         NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
   704                 // Each nf must be statically invocable or we get tied up in our bootstraps.
   704                                 .getDeclaredMethod("allocateInstance", Object.class)),
   705                 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
   705                         NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
   706                 nf.resolve();
   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);
   707             }
   715             }
   708         } catch (ReflectiveOperationException ex) {
       
   709             throw newInternalError(ex);
       
   710         }
   716         }
   711     }
   717     }
   712 }
   718 }