< prev index next >

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

Print this page
@@ -28,10 +28,11 @@
  import sun.invoke.util.Wrapper;
  
  import java.lang.ref.SoftReference;
  
  import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
+ import static java.lang.invoke.MethodHandleStatics.NO_SOFT_CACHE;
  
  /**
   * Shared information for a group of method types, which differ
   * only by reference types, and therefore share a common erasure
   * and wrapping.

@@ -49,21 +50,21 @@
      final short primitiveCount;
      final MethodType erasedType;        // the canonical erasure
      final MethodType basicType;         // the canonical erasure, with primitives simplified
  
      // Cached adapter information:
-     final SoftReference<MethodHandle>[] methodHandles;
+     private final Object[] 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 SoftReference<LambdaForm>[] lambdaForms;
+     private final Object[] lambdaForms;
  
      // Indexes into lambdaForms:
      static final int
              LF_INVVIRTUAL              =  0,  // DMH invokeVirtual
              LF_INVSTATIC               =  1,

@@ -107,43 +108,59 @@
       */
      public MethodType basicType() {
          return basicType;
      }
  
+     @SuppressWarnings({"rawtypes", "unchecked"})
      public MethodHandle cachedMethodHandle(int which) {
-         SoftReference<MethodHandle> entry = methodHandles[which];
-         return (entry != null) ? entry.get() : null;
+         Object entry = methodHandles[which];
+         if (entry == null) {
+             return null;
+         } else if (entry instanceof MethodHandle) {
+             return (MethodHandle) entry;
+         } else {
+             return ((SoftReference<MethodHandle>)entry).get();
+         }
      }
  
      public synchronized MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
          // Simulate a CAS, to avoid racy duplication of results.
-         SoftReference<MethodHandle> entry = methodHandles[which];
-         if (entry != null) {
-             MethodHandle prev = entry.get();
-             if (prev != null) {
-                 return prev;
-             }
+         MethodHandle prev = cachedMethodHandle(which);
+         if (prev != null) {
+             return prev;
+         }
+         if (NO_SOFT_CACHE) {
+             methodHandles[which] = mh;
+         } else {
+             methodHandles[which] = new SoftReference<>(mh);
          }
-         methodHandles[which] = new SoftReference<>(mh);
          return mh;
      }
  
+     @SuppressWarnings({"rawtypes", "unchecked"})
      public LambdaForm cachedLambdaForm(int which) {
-         SoftReference<LambdaForm> entry = lambdaForms[which];
-         return (entry != null) ? entry.get() : null;
+         Object entry = lambdaForms[which];
+         if (entry == null) {
+             return null;
+         } else if (entry instanceof LambdaForm) {
+             return (LambdaForm) entry;
+         } else {
+             return ((SoftReference<LambdaForm>)entry).get();
+         }
      }
  
      public synchronized LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
          // Simulate a CAS, to avoid racy duplication of results.
-         SoftReference<LambdaForm> entry = lambdaForms[which];
-         if (entry != null) {
-             LambdaForm prev = entry.get();
-             if (prev != null) {
-                 return prev;
-             }
+         LambdaForm prev = cachedLambdaForm(which);
+         if (prev != null) {
+             return prev;
+         }
+         if (NO_SOFT_CACHE) {
+             lambdaForms[which] = form;
+         } else {
+             lambdaForms[which] = new SoftReference<>(form);
          }
-         lambdaForms[which] = new SoftReference<>(form);
          return form;
      }
  
      /**
       * Build an MTF for a given type, which must have all references erased to Object.

@@ -189,12 +206,12 @@
  
              if (pslotCount >= 256)  throw newIllegalArgumentException("too many arguments");
  
              this.primitiveCount = primitiveCount;
              this.parameterSlotCount = (short)pslotCount;
-             this.lambdaForms   = new SoftReference[LF_LIMIT];
-             this.methodHandles = new SoftReference[MH_LIMIT];
+             this.lambdaForms   = new Object[LF_LIMIT];
+             this.methodHandles = new Object[MH_LIMIT];
          } else {
              this.basicType = MethodType.methodType(basicReturnType, basicPtypes, true);
              // fill in rest of data from the basic type:
              MethodTypeForm that = this.basicType.form();
              assert(this != that);
< prev index next >