jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
changeset 16118 9f3390f42157
parent 14852 d513c47448f4
child 16123 82033940e774
equal deleted inserted replaced
16117:3c521ba54a81 16118:9f3390f42157
   799     // That way we can lazily load the code and set up the constants.
   799     // That way we can lazily load the code and set up the constants.
   800     private static class BindCaller {
   800     private static class BindCaller {
   801         static
   801         static
   802         MethodHandle bindCaller(MethodHandle mh, Class<?> hostClass) {
   802         MethodHandle bindCaller(MethodHandle mh, Class<?> hostClass) {
   803             // Do not use this function to inject calls into system classes.
   803             // Do not use this function to inject calls into system classes.
   804             if (hostClass == null) {
   804             if (hostClass == null
   805                 hostClass = C_Trampoline;
   805                 ||    (hostClass.isArray() ||
   806             } else if (hostClass.isArray() ||
       
   807                        hostClass.isPrimitive() ||
   806                        hostClass.isPrimitive() ||
   808                        hostClass.getName().startsWith("java.") ||
   807                        hostClass.getName().startsWith("java.") ||
   809                        hostClass.getName().startsWith("sun.")) {
   808                        hostClass.getName().startsWith("sun."))) {
   810                 throw new InternalError();  // does not happen, and should not anyway
   809                 throw new InternalError();  // does not happen, and should not anyway
   811             }
   810             }
   812             // For simplicity, convert mh to a varargs-like method.
   811             // For simplicity, convert mh to a varargs-like method.
   813             MethodHandle vamh = prepareForInvoker(mh);
   812             MethodHandle vamh = prepareForInvoker(mh);
   814             // Cache the result of makeInjectedInvoker once per argument class.
   813             // Cache the result of makeInjectedInvoker once per argument class.
   815             MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
   814             MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
   816             return restoreToType(bccInvoker.bindTo(vamh), mh.type());
   815             return restoreToType(bccInvoker.bindTo(vamh), mh.type());
   817         }
       
   818 
       
   819         // This class ("Trampoline") is known to be inside a dead-end class loader.
       
   820         // Inject all doubtful calls into this class.
       
   821         private static Class<?> C_Trampoline;
       
   822         static {
       
   823             Class<?> tramp = null;
       
   824             try {
       
   825                 final int FRAME_COUNT_ARG = 1;  // [0] Reflection [1] Trampoline
       
   826                 java.lang.reflect.Method gcc = sun.reflect.Reflection.class.getMethod("getCallerClass", int.class);
       
   827                 tramp = (Class<?>) sun.reflect.misc.MethodUtil.invoke(gcc, null, new Object[]{ FRAME_COUNT_ARG });
       
   828                 if (tramp.getClassLoader() == BindCaller.class.getClassLoader())
       
   829                     throw new RuntimeException(tramp.getName()+" class loader");
       
   830             } catch (Throwable ex) {
       
   831                 throw new InternalError(ex);
       
   832             }
       
   833             C_Trampoline = tramp;
       
   834         }
   816         }
   835 
   817 
   836         private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
   818         private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
   837             Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null);
   819             Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null);
   838             if (hostClass.getClassLoader() != bcc.getClassLoader())
   820             if (hostClass.getClassLoader() != bcc.getClassLoader())