< prev index next >

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

Print this page
*** 150,16 ***
  
      private static RuntimeException newIAE(String message, Throwable cause) {
          return new IllegalArgumentException(message, cause);
      }
  
!     private static final Function<Object, Object> CREATE_RESERVATION = new Function<>() {
!         @Override
!         public Object apply(Object key) {
!             return new Object();
!         }
!     };
  
      public final S findSpecies(K key) {
          // Note:  Species instantiation may throw VirtualMachineError because of
          // code cache overflow.  If this happens the species bytecode may be
          // loaded but not linked to its species metadata (with MH's etc).
--- 150,18 ---
  
      private static RuntimeException newIAE(String message, Throwable cause) {
          return new IllegalArgumentException(message, cause);
      }
  
!     private static class CacheHolder {
!         static final Function<Object, Object> CREATE = new Function<>() {
!             @Override
!             public Object apply(Object key) {
!                 return new CacheHolder();
!             }
+         };
+     }
  
      public final S findSpecies(K key) {
          // Note:  Species instantiation may throw VirtualMachineError because of
          // code cache overflow.  If this happens the species bytecode may be
          // loaded but not linked to its species metadata (with MH's etc).

*** 178,16 ***
          // In the end, as long as everybody goes through this findSpecies method,
          // it will ensure only one SpeciesData will be set successfully on a
          // concrete class if ever.
          // The concrete class is published via SpeciesData instance
          // returned here only after the class and species data are linked together.
!         Object speciesDataOrReservation = cache.computeIfAbsent(key, CREATE_RESERVATION);
          // Separating the creation of a placeholder SpeciesData instance above
          // from the loading and linking a real one below ensures we can never
          // accidentally call computeIfAbsent recursively.
          S speciesData;
!         if (speciesDataOrReservation.getClass() == Object.class) {
              synchronized (speciesDataOrReservation) {
                  Object existingSpeciesData = cache.get(key);
                  if (existingSpeciesData == speciesDataOrReservation) { // won the race
                      // create a new SpeciesData...
                      speciesData = newSpeciesData(key);
--- 180,16 ---
          // In the end, as long as everybody goes through this findSpecies method,
          // it will ensure only one SpeciesData will be set successfully on a
          // concrete class if ever.
          // The concrete class is published via SpeciesData instance
          // returned here only after the class and species data are linked together.
!         Object speciesDataOrReservation = cache.computeIfAbsent(key, CacheHolder.CREATE);
          // Separating the creation of a placeholder SpeciesData instance above
          // from the loading and linking a real one below ensures we can never
          // accidentally call computeIfAbsent recursively.
          S speciesData;
!         if (speciesDataOrReservation.getClass() == CacheHolder.class) {
              synchronized (speciesDataOrReservation) {
                  Object existingSpeciesData = cache.get(key);
                  if (existingSpeciesData == speciesDataOrReservation) { // won the race
                      // create a new SpeciesData...
                      speciesData = newSpeciesData(key);
< prev index next >