jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java
changeset 26468 2d57604f9299
parent 26467 d69abed3a07d
child 26472 71b6a6f208c0
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java	Wed Sep 10 19:19:47 2014 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java	Wed Sep 10 19:19:48 2014 +0400
@@ -51,7 +51,13 @@
     final MethodType basicType;         // the canonical erasure, with primitives simplified
 
     // Cached adapter information:
-    @Stable MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction
+    @Stable final MethodHandle[] methodHandles;
+    // Indexes into methodHandles:
+    static final int
+            MH_BASIC_INV      =  0,  // cached instance of MH.invokeBasic
+            MH_NF_INV         =  1,  // cached helper for LF.NamedFunction
+            MH_UNINIT_CS      =  2,  // uninitialized call site
+            MH_LIMIT          =  3;
 
     // Cached lambda form information, for basic types only:
     final @Stable LambdaForm[] lambdaForms;
@@ -98,6 +104,18 @@
         return true;
     }
 
+    public MethodHandle cachedMethodHandle(int which) {
+        assert(assertIsBasicType());
+        return methodHandles[which];
+    }
+
+    synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
+        // Simulate a CAS, to avoid racy duplication of results.
+        MethodHandle prev = methodHandles[which];
+        if (prev != null)  return prev;
+        return methodHandles[which] = mh;
+    }
+
     public LambdaForm cachedLambdaForm(int which) {
         assert(assertIsBasicType());
         return lambdaForms[which];
@@ -169,6 +187,7 @@
             this.argCounts = that.argCounts;
             this.argToSlotTable = that.argToSlotTable;
             this.slotToArgTable = that.slotToArgTable;
+            this.methodHandles = null;
             this.lambdaForms = null;
             return;
         }
@@ -214,6 +233,7 @@
         // Initialize caches, but only for basic types
         assert(basicType == erasedType);
         this.lambdaForms = new LambdaForm[LF_LIMIT];
+        this.methodHandles = new MethodHandle[MH_LIMIT];
     }
 
     private static long pack(int a, int b, int c, int d) {