< prev index next >

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

Print this page

        

@@ -23,25 +23,27 @@
  * questions.
  */
 
 package java.lang.invoke;
 
+import jdk.internal.misc.Unsafe;
 import jdk.internal.org.objectweb.asm.*;
 import sun.invoke.util.BytecodeDescriptor;
-import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 
 import java.io.FilePermission;
 import java.io.Serializable;
+import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.Constructor;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.LinkedHashSet;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.PropertyPermission;
 import java.util.Set;
 
+import static java.lang.invoke.MethodHandles.Lookup.*;
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 /**
  * Lambda metafactory implementation which dynamically creates an
  * inner-class-like class per lambda callsite.

@@ -53,11 +55,10 @@
 
     private static final int CLASSFILE_VERSION = 52;
     private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
     private static final String JAVA_LANG_OBJECT = "java/lang/Object";
     private static final String NAME_CTOR = "<init>";
-    private static final String NAME_FACTORY = "get$Lambda";
 
     //Serialization support
     private static final String NAME_SERIALIZED_LAMBDA = "java/lang/invoke/SerializedLambda";
     private static final String NAME_NOT_SERIALIZABLE_EXCEPTION = "java/io/NotSerializableException";
     private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;";

@@ -214,15 +215,14 @@
                 throw new LambdaConversionException("Exception instantiating lambda object", e);
             }
         } else {
             try {
                 UNSAFE.ensureClassInitialized(innerClass);
-                return new ConstantCallSite(
-                        MethodHandles.Lookup.IMPL_LOOKUP
-                             .findStatic(innerClass, NAME_FACTORY, invokedType));
-            }
-            catch (ReflectiveOperationException e) {
+                Lookup lookup = MethodHandles.privateLookupIn(innerClass, Lookup.IMPL_LOOKUP);
+                MethodHandle mh = lookup.findConstructor(innerClass, invokedType.changeReturnType(void.class));
+                return new ConstantCallSite(mh.asType(invokedType));
+            } catch (ReflectiveOperationException e) {
                 throw new LambdaConversionException("Exception finding constructor", e);
             }
         }
     }
 

@@ -271,14 +271,10 @@
             fv.visitEnd();
         }
 
         generateConstructor();
 
-        if (invokedType.parameterCount() != 0) {
-            generateFactory();
-        }
-
         // Forward the SAM method
         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samMethodName,
                                           samMethodType.toMethodDescriptorString(), null, null);
         mv.visitAnnotation(DESCR_HIDDEN, true);
         new ForwardingMethodGenerator(mv).generate(samMethodType);

@@ -315,32 +311,17 @@
             }, null,
             new FilePermission("<<ALL FILES>>", "read, write"),
             // createDirectories may need it
             new PropertyPermission("user.dir", "read"));
         }
-
-        return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
-    }
-
-    /**
-     * Generate the factory method for the class
-     */
-    private void generateFactory() {
-        MethodVisitor m = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, NAME_FACTORY, invokedType.toMethodDescriptorString(), null, null);
-        m.visitCode();
-        m.visitTypeInsn(NEW, lambdaClassName);
-        m.visitInsn(Opcodes.DUP);
-        int parameterCount = invokedType.parameterCount();
-        for (int typeIndex = 0, varIndex = 0; typeIndex < parameterCount; typeIndex++) {
-            Class<?> argType = invokedType.parameterType(typeIndex);
-            m.visitVarInsn(getLoadOpcode(argType), varIndex);
-            varIndex += getParameterSize(argType);
+        try {
+            Lookup lookup = MethodHandles.privateLookupIn(targetClass, IMPL_LOOKUP);
+            // this class is linked at the indy callsite.  No need to be weak class
+            return lookup.defineClassWithNoCheck(classBytes, HIDDEN_NESTMATE);
+        } catch (ReflectiveOperationException e) {
+            throw new LambdaConversionException(e);
         }
-        m.visitMethodInsn(INVOKESPECIAL, lambdaClassName, NAME_CTOR, constructorType.toMethodDescriptorString(), false);
-        m.visitInsn(ARETURN);
-        m.visitMaxs(-1, -1);
-        m.visitEnd();
     }
 
     /**
      * Generate the constructor for the class
      */
< prev index next >