29 import java.io.File;
30 import java.io.InputStreamReader;
31 import java.io.InputStream;
32 import java.io.IOException;
33 import java.io.PrintStream;
34 import java.util.Arrays;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Objects;
39 import java.util.stream.Stream;
40
41 import jdk.internal.access.SharedSecrets;
42
43 public class CDS {
44 // Must be in sync with cdsConfig.hpp
45 private static final int IS_DUMPING_ARCHIVE = 1 << 0;
46 private static final int IS_DUMPING_STATIC_ARCHIVE = 1 << 1;
47 private static final int IS_LOGGING_LAMBDA_FORM_INVOKERS = 1 << 2;
48 private static final int IS_USING_ARCHIVE = 1 << 3;
49 private static final int configStatus = getCDSConfigStatus();
50
51 /**
52 * Should we log the use of lambda form invokers?
53 */
54 public static boolean isLoggingLambdaFormInvokers() {
55 return (configStatus & IS_LOGGING_LAMBDA_FORM_INVOKERS) != 0;
56 }
57
58 /**
59 * Is the VM writing to a (static or dynamic) CDS archive.
60 */
61 public static boolean isDumpingArchive() {
62 return (configStatus & IS_DUMPING_ARCHIVE) != 0;
63 }
64
65 /**
66 * Is the VM using at least one CDS archive?
67 */
68 public static boolean isUsingArchive() {
69 return (configStatus & IS_USING_ARCHIVE) != 0;
70 }
71
72 /**
73 * Is dumping static archive.
74 */
75 public static boolean isDumpingStaticArchive() {
76 return (configStatus & IS_DUMPING_STATIC_ARCHIVE) != 0;
77 }
78
79 private static native int getCDSConfigStatus();
80 private static native void logLambdaFormInvoker(String line);
81
82 /**
83 * Initialize archived static fields in the given Class using archived
84 * values from CDS dump time. Also initialize the classes of objects in
85 * the archived graph referenced by those fields.
86 *
87 * Those static fields remain as uninitialized if there is no mapped CDS
88 * java heap data or there is any error during initialization of the
89 * object class in the archived graph.
90 */
91 public static native void initializeFromArchive(Class<?> c);
92
93 /**
94 * Ensure that the native representation of all archived java.lang.Module objects
95 * are properly restored.
96 */
97 public static native void defineArchivedModules(ClassLoader platformLoader, ClassLoader systemLoader);
98
104 public static native long getRandomSeedForDumping();
105
106 /**
107 * log lambda form invoker holder, name and method type
108 */
109 public static void logLambdaFormInvoker(String prefix, String holder, String name, String type) {
110 if (isLoggingLambdaFormInvokers()) {
111 logLambdaFormInvoker(prefix + " " + holder + " " + name + " " + type);
112 }
113 }
114
115 /**
116 * log species
117 */
118 public static void logSpeciesType(String prefix, String cn) {
119 if (isLoggingLambdaFormInvokers()) {
120 logLambdaFormInvoker(prefix + " " + cn);
121 }
122 }
123
124 static final String DIRECT_HOLDER_CLASS_NAME = "java.lang.invoke.DirectMethodHandle$Holder";
125 static final String DELEGATING_HOLDER_CLASS_NAME = "java.lang.invoke.DelegatingMethodHandle$Holder";
126 static final String BASIC_FORMS_HOLDER_CLASS_NAME = "java.lang.invoke.LambdaForm$Holder";
127 static final String INVOKERS_HOLDER_CLASS_NAME = "java.lang.invoke.Invokers$Holder";
128
129 private static boolean isValidHolderName(String name) {
130 return name.equals(DIRECT_HOLDER_CLASS_NAME) ||
131 name.equals(DELEGATING_HOLDER_CLASS_NAME) ||
132 name.equals(BASIC_FORMS_HOLDER_CLASS_NAME) ||
133 name.equals(INVOKERS_HOLDER_CLASS_NAME);
134 }
135
136 private static boolean isBasicTypeChar(char c) {
137 return "LIJFDV".indexOf(c) >= 0;
138 }
139
140 private static boolean isValidMethodType(String type) {
141 String[] typeParts = type.split("_");
142 // check return type (second part)
143 if (typeParts.length != 2 || typeParts[1].length() != 1
|
29 import java.io.File;
30 import java.io.InputStreamReader;
31 import java.io.InputStream;
32 import java.io.IOException;
33 import java.io.PrintStream;
34 import java.util.Arrays;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Objects;
39 import java.util.stream.Stream;
40
41 import jdk.internal.access.SharedSecrets;
42
43 public class CDS {
44 // Must be in sync with cdsConfig.hpp
45 private static final int IS_DUMPING_ARCHIVE = 1 << 0;
46 private static final int IS_DUMPING_STATIC_ARCHIVE = 1 << 1;
47 private static final int IS_LOGGING_LAMBDA_FORM_INVOKERS = 1 << 2;
48 private static final int IS_USING_ARCHIVE = 1 << 3;
49 private static final int IS_DUMPING_HEAP = 1 << 4;
50 private static final int IS_LOGGING_DYNAMIC_PROXIES = 1 << 5;
51 private static final int IS_DUMPING_PACKAGES = 1 << 6;
52 private static final int configStatus = getCDSConfigStatus();
53
54 /**
55 * Should we log the use of lambda form invokers?
56 */
57 public static boolean isLoggingLambdaFormInvokers() {
58 return (configStatus & IS_LOGGING_LAMBDA_FORM_INVOKERS) != 0;
59 }
60
61 /**
62 * Is the VM writing to a (static or dynamic) CDS archive.
63 */
64 public static boolean isDumpingArchive() {
65 return (configStatus & IS_DUMPING_ARCHIVE) != 0;
66 }
67
68 /**
69 * Is the VM using at least one CDS archive?
70 */
71 public static boolean isUsingArchive() {
72 return (configStatus & IS_USING_ARCHIVE) != 0;
73 }
74
75 /**
76 * Is dumping static archive.
77 */
78 public static boolean isDumpingStaticArchive() {
79 return (configStatus & IS_DUMPING_STATIC_ARCHIVE) != 0;
80 }
81
82 public static boolean isDumpingHeap() {
83 return (configStatus & IS_DUMPING_HEAP) != 0;
84 }
85
86 public static boolean isLoggingDynamicProxies() {
87 return (configStatus & IS_LOGGING_DYNAMIC_PROXIES) != 0;
88 }
89
90 public static boolean isDumpingPackages() {
91 return (configStatus & IS_DUMPING_PACKAGES) != 0;
92 }
93
94 private static native int getCDSConfigStatus();
95 private static native void logLambdaFormInvoker(String line);
96
97 /**
98 * Initialize archived static fields in the given Class using archived
99 * values from CDS dump time. Also initialize the classes of objects in
100 * the archived graph referenced by those fields.
101 *
102 * Those static fields remain as uninitialized if there is no mapped CDS
103 * java heap data or there is any error during initialization of the
104 * object class in the archived graph.
105 */
106 public static native void initializeFromArchive(Class<?> c);
107
108 /**
109 * Ensure that the native representation of all archived java.lang.Module objects
110 * are properly restored.
111 */
112 public static native void defineArchivedModules(ClassLoader platformLoader, ClassLoader systemLoader);
113
119 public static native long getRandomSeedForDumping();
120
121 /**
122 * log lambda form invoker holder, name and method type
123 */
124 public static void logLambdaFormInvoker(String prefix, String holder, String name, String type) {
125 if (isLoggingLambdaFormInvokers()) {
126 logLambdaFormInvoker(prefix + " " + holder + " " + name + " " + type);
127 }
128 }
129
130 /**
131 * log species
132 */
133 public static void logSpeciesType(String prefix, String cn) {
134 if (isLoggingLambdaFormInvokers()) {
135 logLambdaFormInvoker(prefix + " " + cn);
136 }
137 }
138
139 public static void logDynamicProxy(ClassLoader loader, String proxyName,
140 Class<?>[] interfaces, int accessFlags) {
141 Objects.requireNonNull(proxyName);
142 Objects.requireNonNull(interfaces);
143 logDynamicProxy0(loader, proxyName, interfaces, accessFlags);
144 }
145 private static native void logDynamicProxy0(ClassLoader loader, String proxyName,
146 Class<?>[] interfaces, int accessFlags);
147
148 static final String DIRECT_HOLDER_CLASS_NAME = "java.lang.invoke.DirectMethodHandle$Holder";
149 static final String DELEGATING_HOLDER_CLASS_NAME = "java.lang.invoke.DelegatingMethodHandle$Holder";
150 static final String BASIC_FORMS_HOLDER_CLASS_NAME = "java.lang.invoke.LambdaForm$Holder";
151 static final String INVOKERS_HOLDER_CLASS_NAME = "java.lang.invoke.Invokers$Holder";
152
153 private static boolean isValidHolderName(String name) {
154 return name.equals(DIRECT_HOLDER_CLASS_NAME) ||
155 name.equals(DELEGATING_HOLDER_CLASS_NAME) ||
156 name.equals(BASIC_FORMS_HOLDER_CLASS_NAME) ||
157 name.equals(INVOKERS_HOLDER_CLASS_NAME);
158 }
159
160 private static boolean isBasicTypeChar(char c) {
161 return "LIJFDV".indexOf(c) >= 0;
162 }
163
164 private static boolean isValidMethodType(String type) {
165 String[] typeParts = type.split("_");
166 // check return type (second part)
167 if (typeParts.length != 2 || typeParts[1].length() != 1
|