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