< prev index next >

src/java.base/share/classes/jdk/internal/misc/CDS.java

Print this page
*** 50,10 ***
--- 50,14 ---
      private static final int IS_DUMPING_ARCHIVE              = 1 << 0;
      private static final int IS_DUMPING_METHOD_HANDLES       = 1 << 1;
      private static final int IS_DUMPING_STATIC_ARCHIVE       = 1 << 2;
      private static final int IS_LOGGING_LAMBDA_FORM_INVOKERS = 1 << 3;
      private static final int IS_USING_ARCHIVE                = 1 << 4;
+     private static final int IS_DUMPING_HEAP                 = 1 << 5;
+     private static final int IS_LOGGING_DYNAMIC_PROXIES      = 1 << 6;
+     private static final int IS_DUMPING_PACKAGES             = 1 << 7;
+     private static final int IS_DUMPING_PROTECTION_DOMAINS   = 1 << 8;
      private static final int configStatus = getCDSConfigStatus();
  
      /**
       * Should we log the use of lambda form invokers?
       */

*** 80,10 ***
--- 84,26 ---
        */
      public static boolean isDumpingStaticArchive() {
          return (configStatus & IS_DUMPING_STATIC_ARCHIVE) != 0;
      }
  
+     public static boolean isDumpingHeap() {
+         return (configStatus & IS_DUMPING_HEAP) != 0;
+     }
+ 
+     public static boolean isLoggingDynamicProxies() {
+         return (configStatus & IS_LOGGING_DYNAMIC_PROXIES) != 0;
+     }
+ 
+     public static boolean isDumpingPackages() {
+         return (configStatus & IS_DUMPING_PACKAGES) != 0;
+     }
+ 
+     public static boolean isDumpingProtectionDomains() {
+         return (configStatus & IS_DUMPING_PROTECTION_DOMAINS) != 0;
+     }
+ 
      private static native int getCDSConfigStatus();
      private static native void logLambdaFormInvoker(String line);
  
      /**
       * Initialize archived static fields in the given Class using archived

*** 125,10 ***
--- 145,19 ---
          if (isLoggingLambdaFormInvokers()) {
              logLambdaFormInvoker(prefix + " " + cn);
          }
      }
  
+     public static void logDynamicProxy(ClassLoader loader, String proxyName,
+                                        Class<?>[] interfaces, int accessFlags) {
+         Objects.requireNonNull(proxyName);
+         Objects.requireNonNull(interfaces);
+         logDynamicProxy0(loader, proxyName, interfaces, accessFlags);
+     }
+     private static native void logDynamicProxy0(ClassLoader loader, String proxyName,
+                                                 Class<?>[] interfaces, int accessFlags);
+ 
      static final String DIRECT_HOLDER_CLASS_NAME  = "java.lang.invoke.DirectMethodHandle$Holder";
      static final String DELEGATING_HOLDER_CLASS_NAME = "java.lang.invoke.DelegatingMethodHandle$Holder";
      static final String BASIC_FORMS_HOLDER_CLASS_NAME = "java.lang.invoke.LambdaForm$Holder";
      static final String INVOKERS_HOLDER_CLASS_NAME = "java.lang.invoke.Invokers$Holder";
  

*** 471,6 ***
--- 500,54 ---
              }
  
              throw new ClassNotFoundException(name);
          }
      }
+ 
+     /**
+      * This class is used only by native JVM code to spawn a child JVM process to assemble
+      * the AOT cache. <code>args[]</code> are passed in the <code>JAVA_TOOL_OPTIONS</code>
+      * environment variable as described in
+      * https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#tooloptions
+      */
+     private static class ProcessLauncher {
+         static int execWithJavaToolOptions(String javaLauncher, String args[]) throws IOException, InterruptedException {
+             ProcessBuilder pb = new ProcessBuilder().inheritIO().command(javaLauncher);
+             StringBuilder sb = new StringBuilder();
+             String prefix = "";
+             for (String arg : args) {
+                 sb.append(prefix);
+ 
+                 for (int i = 0; i < arg.length(); i++) {
+                     char c = arg.charAt(i);
+                     if (c == '"' || Character.isWhitespace(c)) {
+                         sb.append('\'');
+                         sb.append(c);
+                         sb.append('\'');
+                     } else if (c == '\'') {
+                         sb.append('"');
+                         sb.append(c);
+                         sb.append('"');
+                     } else {
+                         sb.append(c);
+                     }
+                 }
+ 
+                 prefix = " ";
+             }
+ 
+             Map<String, String> env = pb.environment();
+             env.put("JAVA_TOOL_OPTIONS", sb.toString());
+             env.remove("_JAVA_OPTIONS");
+             env.remove("CLASSPATH");
+             Process process = pb.start();
+             return process.waitFor();
+         }
+     }
+ 
+     /**
+      * This class is to ensure that the dynamic CDS archive contains at least one class, so we can avoid
+      * error handling for the degenerative case where the dynamic archive is completely empty (which doesn't
+      * happen for realistic applications).
+      */
+     private static class DummyForDynamicArchive {}
  }
< prev index next >