< prev index next >

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

Print this page

        

@@ -63,10 +63,11 @@
 
     private static final String OBJ     = "java/lang/Object";
     private static final String CLASS_PREFIX   = "java/lang/invoke/LambdaForm$Value$";
     private static final String DEFAULT_CLASS  = "MH";
     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
+    private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
 
     private static final String MH           = "java/lang/invoke/MethodHandle";
     private static final String MHARY2       = "[[L" + MH + ";";
 
     static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) {

@@ -92,11 +93,29 @@
     LambdaFormBuilder(LambdaFormCodeBuilder builder, LambdaForm lambdaForm) {
         this.builder = builder;
         this.lambdaForm = lambdaForm;
     }
 
+    /** Generates code to check that actual receiver and LambdaForm matches */
+    private boolean checkActualReceiver() {
+        // Expects MethodHandle on the stack and actual receiver MethodHandle in slot #0
+        builder.dup().load(0).invokestatic(MethodHandleImpl.class, "assertSame", LLV_SIG, false);
+        return true;
+    }
+
     void generateLambdaFormBody() {
+        if (lambdaForm.customized != null && MethodHandleBuilder.ENABLE_POOL_PATCHES) {
+            // Since LambdaForm is customized for a particular MethodHandle, it's safe to substitute
+            // receiver MethodHandle (at slot #0) with an embedded constant and use it instead.
+            // It enables more efficient code generation in some situations, since embedded constants
+            // are compile-time constants for JIT compiler.
+            builder.ldc(lambdaForm.customized)
+                   .checkcast(MethodHandle.class);
+            assert(checkActualReceiver()); // generates runtime check
+            builder.store(0);
+        }
+
         // iterate over the form's names, generating bytecode instructions for each
         // start iterating at the first name following the arguments
         Name onStack = null;
         for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
             Name name = lambdaForm.names[i];
< prev index next >