< prev index next >

src/java.base/share/classes/java/lang/Class.java

Print this page
*** 460,10 ***
--- 460,21 ---
      @CallerSensitiveAdapter
      private static Class<?> forName(String className, Class<?> caller)
              throws ClassNotFoundException {
          ClassLoader loader = (caller == null) ? ClassLoader.getSystemClassLoader()
                                                : ClassLoader.getClassLoader(caller);
+         if (loader instanceof BuiltinClassLoader bcl) {
+             if (bcl.usePositiveCache) {
+                 Class<?> result = bcl.checkPositiveLookupCache(className);
+                 if (result != null) {
+                     return result;
+                 }
+             }
+             if (bcl.useNegativeCache && bcl.checkNegativeLookupCache(className)) {
+                 throw new ClassNotFoundException(className);
+             }
+         }
          return forName0(className, true, loader, caller);
      }
  
      /**
       * Returns the {@code Class} object associated with the class or

*** 540,10 ***
--- 551,21 ---
       * @since     1.2
       */
      public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
          throws ClassNotFoundException
      {
+         if (loader instanceof BuiltinClassLoader bcl) {
+             if (bcl.usePositiveCache) {
+                 Class<?> result = bcl.checkPositiveLookupCache(name);
+                 if (result != null) {
+                     return result;
+                 }
+             }
+            if (bcl.useNegativeCache && bcl.checkNegativeLookupCache(name)) {
+                 throw new ClassNotFoundException(name);
+             }
+         }
          return forName0(name, initialize, loader, null);
      }
  
      /** Called after security check for system loader access checks have been made. */
      private static native Class<?> forName0(String name, boolean initialize,

*** 2783,12 ***
          // offset of Class.annotationData instance field
          private static final long annotationDataOffset
                  = unsafe.objectFieldOffset(Class.class, "annotationData");
  
          static <T> boolean casReflectionData(Class<?> clazz,
!                                              SoftReference<ReflectionData<T>> oldData,
!                                              SoftReference<ReflectionData<T>> newData) {
              return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
          }
  
          static boolean casAnnotationType(Class<?> clazz,
                                           AnnotationType oldType,
--- 2805,12 ---
          // offset of Class.annotationData instance field
          private static final long annotationDataOffset
                  = unsafe.objectFieldOffset(Class.class, "annotationData");
  
          static <T> boolean casReflectionData(Class<?> clazz,
!                                              ReflectionData<T> oldData,
!                                              ReflectionData<T> newData) {
              return unsafe.compareAndSetReference(clazz, reflectionDataOffset, oldData, newData);
          }
  
          static boolean casAnnotationType(Class<?> clazz,
                                           AnnotationType oldType,

*** 2832,45 ***
          ReflectionData(int redefinedCount) {
              this.redefinedCount = redefinedCount;
          }
      }
  
!     private transient volatile SoftReference<ReflectionData<T>> reflectionData;
  
      // Incremented by the VM on each call to JVM TI RedefineClasses()
      // that redefines this class or a superclass.
      private transient volatile int classRedefinedCount;
  
      // Lazily create and cache ReflectionData
      private ReflectionData<T> reflectionData() {
!         SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
          int classRedefinedCount = this.classRedefinedCount;
-         ReflectionData<T> rd;
          if (reflectionData != null &&
!             (rd = reflectionData.get()) != null &&
!             rd.redefinedCount == classRedefinedCount) {
-             return rd;
          }
          // else no SoftReference or cleared SoftReference or stale ReflectionData
          // -> create and replace new instance
          return newReflectionData(reflectionData, classRedefinedCount);
      }
  
!     private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
                                                  int classRedefinedCount) {
          while (true) {
              ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
              // try to CAS it...
!             if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
                  return rd;
              }
              // else retry
              oldReflectionData = this.reflectionData;
              classRedefinedCount = this.classRedefinedCount;
!             if (oldReflectionData != null &&
-                 (rd = oldReflectionData.get()) != null &&
-                 rd.redefinedCount == classRedefinedCount) {
                  return rd;
              }
          }
      }
  
--- 2854,41 ---
          ReflectionData(int redefinedCount) {
              this.redefinedCount = redefinedCount;
          }
      }
  
!     private transient volatile ReflectionData<T> reflectionData;
  
      // Incremented by the VM on each call to JVM TI RedefineClasses()
      // that redefines this class or a superclass.
      private transient volatile int classRedefinedCount;
  
      // Lazily create and cache ReflectionData
      private ReflectionData<T> reflectionData() {
!         ReflectionData<T> reflectionData = this.reflectionData;
          int classRedefinedCount = this.classRedefinedCount;
          if (reflectionData != null &&
!             reflectionData.redefinedCount == classRedefinedCount) {
!             return reflectionData;
          }
          // else no SoftReference or cleared SoftReference or stale ReflectionData
          // -> create and replace new instance
          return newReflectionData(reflectionData, classRedefinedCount);
      }
  
!     private ReflectionData<T> newReflectionData(ReflectionData<T> oldReflectionData,
                                                  int classRedefinedCount) {
          while (true) {
              ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
              // try to CAS it...
!             if (Atomic.casReflectionData(this, oldReflectionData, rd)) {
                  return rd;
              }
              // else retry
              oldReflectionData = this.reflectionData;
              classRedefinedCount = this.classRedefinedCount;
!             if (oldReflectionData != null && oldReflectionData.redefinedCount == classRedefinedCount) {
                  return rd;
              }
          }
      }
  

*** 4174,6 ***
--- 4192,55 ---
          Class<?> c = isArray() ? elementType() : this;
          return c.getClassAccessFlagsRaw0();
      }
  
      private native int getClassAccessFlagsRaw0();
+ 
+     // Support for "OLD" CDS workflow -- {
+     private static final int RD_PUBLIC_METHODS          = (1 <<  0);
+     private static final int RD_PUBLIC_FIELDS           = (1 <<  1);
+     private static final int RD_DECLARED_CTORS          = (1 <<  2);
+     private static final int RD_PUBLIC_CTORS = (1 <<  3);
+     private static final int RD_DECLARED_METHODS        = (1 <<  4);
+     private static final int RD_DECLARED_PUBLIC_METHODS = (1 <<  5);
+     private static final int RD_DECLARED_FIELDS         = (1 <<  6);
+     private static final int RD_DECLARED_PUBLIC_FIELDS  = (1 <<  7);
+     private static final int RD_DECLARED_INTERFACES     = (1 <<  8);
+     private static final int RD_DECLARED_SIMPLE_NAME    = (1 <<  9);
+     private static final int RD_DECLARED_CANONICAL_NAME = (1 << 10);
+     private static final int CLS_NAME = (1 << 10);
+ 
+ 
+     private int encodeReflectionData() {
+         int flags = CLS_NAME;
+         if (reflectionData != null) {
+             flags = (reflectionData.publicMethods         != null ? RD_PUBLIC_METHODS          : 0) |
+                     (reflectionData.publicFields          != null ? RD_PUBLIC_FIELDS           : 0) |
+                     (reflectionData.declaredConstructors  != null ? RD_DECLARED_CTORS          : 0) |
+                     (reflectionData.publicConstructors    != null ? RD_PUBLIC_CTORS            : 0) |
+                     (reflectionData.declaredMethods       != null ? RD_DECLARED_METHODS        : 0) |
+                     (reflectionData.declaredPublicMethods != null ? RD_DECLARED_PUBLIC_METHODS : 0) |
+                     (reflectionData.declaredFields        != null ? RD_DECLARED_FIELDS         : 0) |
+                     (reflectionData.declaredPublicFields  != null ? RD_DECLARED_PUBLIC_FIELDS  : 0) |
+                     (reflectionData.interfaces            != null ? RD_DECLARED_INTERFACES     : 0) |
+                     (reflectionData.simpleName            != null ? RD_DECLARED_SIMPLE_NAME    : 0) |
+                     (reflectionData.canonicalName         != null ? RD_DECLARED_CANONICAL_NAME : 0);
+         }
+         return flags;
+     }
+     private void generateReflectionData(int flags) {
+         if ((flags & CLS_NAME                  ) != 0) { getName();                             } // String name
+         if ((flags & RD_PUBLIC_METHODS         ) != 0) { privateGetPublicMethods();             } // Method[] publicMethods;
+         if ((flags & RD_PUBLIC_FIELDS          ) != 0) { privateGetPublicFields();              } // Field[] publicFields;
+         if ((flags & RD_DECLARED_CTORS         ) != 0) { privateGetDeclaredConstructors(false); } // Constructor<T>[] declaredConstructors;
+         if ((flags & RD_PUBLIC_CTORS           ) != 0) { privateGetDeclaredConstructors(true);  } // Constructor<T>[] publicConstructors;
+         if ((flags & RD_DECLARED_METHODS       ) != 0) { privateGetDeclaredMethods(false);      } // Method[] declaredMethods;
+         if ((flags & RD_DECLARED_PUBLIC_METHODS) != 0) { privateGetDeclaredMethods(true);       } // Method[] declaredPublicMethods;
+         if ((flags & RD_DECLARED_FIELDS        ) != 0) { privateGetDeclaredFields(false);       } // Field[] declaredFields;
+         if ((flags & RD_DECLARED_PUBLIC_FIELDS ) != 0) { privateGetDeclaredFields(true);        } // Field[] declaredPublicFields;
+         if ((flags & RD_DECLARED_INTERFACES    ) != 0) { getInterfaces(false);                  } // Class<?>[] interfaces;
+         if ((flags & RD_DECLARED_SIMPLE_NAME   ) != 0) { getSimpleName();                       } // String simpleName;
+         if ((flags & RD_DECLARED_CANONICAL_NAME) != 0) { getCanonicalName();                    } // String canonicalName;
+     }
+ 
+     // -- }
  }
< prev index next >