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

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

*** 189,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];
          } 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);
--- 206,12 ---
  
              if (pslotCount >= 256)  throw newIllegalArgumentException("too many arguments");
  
              this.primitiveCount = primitiveCount;
              this.parameterSlotCount = (short)pslotCount;
!             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 >