36 import java.util.Arrays;
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Objects;
42 import java.util.jar.JarFile;
43 import java.util.stream.Stream;
44
45 import jdk.internal.access.SharedSecrets;
46 import jdk.internal.util.StaticProperty;
47
48 public class CDS {
49 // Must be in sync with cdsConfig.hpp
50 private static final int IS_DUMPING_AOT_LINKED_CLASSES = 1 << 0;
51 private static final int IS_DUMPING_ARCHIVE = 1 << 1;
52 private static final int IS_DUMPING_METHOD_HANDLES = 1 << 2;
53 private static final int IS_DUMPING_STATIC_ARCHIVE = 1 << 3;
54 private static final int IS_LOGGING_LAMBDA_FORM_INVOKERS = 1 << 4;
55 private static final int IS_USING_ARCHIVE = 1 << 5;
56
57 private static final int configStatus = getCDSConfigStatus();
58
59 /**
60 * Should we log the use of lambda form invokers?
61 */
62 public static boolean isLoggingLambdaFormInvokers() {
63 return (configStatus & IS_LOGGING_LAMBDA_FORM_INVOKERS) != 0;
64 }
65
66 /**
67 * Is the VM writing to a (static or dynamic) CDS archive.
68 */
69 public static boolean isDumpingArchive() {
70 return (configStatus & IS_DUMPING_ARCHIVE) != 0;
71 }
72
73 /**
74 * Is the VM using at least one CDS archive?
75 */
76 public static boolean isUsingArchive() {
77 return (configStatus & IS_USING_ARCHIVE) != 0;
78 }
79
80 /**
81 * Is dumping static archive.
82 */
83 public static boolean isDumpingStaticArchive() {
84 return (configStatus & IS_DUMPING_STATIC_ARCHIVE) != 0;
85 }
86
87 public static boolean isDumpingAOTLinkedClasses() {
88 return (configStatus & IS_DUMPING_AOT_LINKED_CLASSES) != 0;
89 }
90
91 public static boolean isSingleThreadVM() {
92 return isDumpingStaticArchive();
93 }
94
95 private static native int getCDSConfigStatus();
96 private static native void logLambdaFormInvoker(String line);
97
98
99 // Used only when dumping static archive to keep weak references alive to
100 // ensure that Soft/Weak Reference objects can be reliably archived.
101 private static ArrayList<Object> keepAliveList;
102
103 public static void keepAlive(Object s) {
104 assert isSingleThreadVM(); // no need for synchronization
105 assert isDumpingStaticArchive();
106 if (keepAliveList == null) {
143 public static native long getRandomSeedForDumping();
144
145 /**
146 * log lambda form invoker holder, name and method type
147 */
148 public static void logLambdaFormInvoker(String prefix, String holder, String name, String type) {
149 if (isLoggingLambdaFormInvokers()) {
150 logLambdaFormInvoker(prefix + " " + holder + " " + name + " " + type);
151 }
152 }
153
154 /**
155 * log species
156 */
157 public static void logSpeciesType(String prefix, String cn) {
158 if (isLoggingLambdaFormInvokers()) {
159 logLambdaFormInvoker(prefix + " " + cn);
160 }
161 }
162
163 static final String DIRECT_HOLDER_CLASS_NAME = "java.lang.invoke.DirectMethodHandle$Holder";
164 static final String DELEGATING_HOLDER_CLASS_NAME = "java.lang.invoke.DelegatingMethodHandle$Holder";
165 static final String BASIC_FORMS_HOLDER_CLASS_NAME = "java.lang.invoke.LambdaForm$Holder";
166 static final String INVOKERS_HOLDER_CLASS_NAME = "java.lang.invoke.Invokers$Holder";
167
168 private static boolean isValidHolderName(String name) {
169 return name.equals(DIRECT_HOLDER_CLASS_NAME) ||
170 name.equals(DELEGATING_HOLDER_CLASS_NAME) ||
171 name.equals(BASIC_FORMS_HOLDER_CLASS_NAME) ||
172 name.equals(INVOKERS_HOLDER_CLASS_NAME);
173 }
174
175 private static boolean isBasicTypeChar(char c) {
176 return "LIJFDV".indexOf(c) >= 0;
177 }
178
179 private static boolean isValidMethodType(String type) {
180 String[] typeParts = type.split("_");
181 // check return type (second part)
182 if (typeParts.length != 2 || typeParts[1].length() != 1
|
36 import java.util.Arrays;
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Objects;
42 import java.util.jar.JarFile;
43 import java.util.stream.Stream;
44
45 import jdk.internal.access.SharedSecrets;
46 import jdk.internal.util.StaticProperty;
47
48 public class CDS {
49 // Must be in sync with cdsConfig.hpp
50 private static final int IS_DUMPING_AOT_LINKED_CLASSES = 1 << 0;
51 private static final int IS_DUMPING_ARCHIVE = 1 << 1;
52 private static final int IS_DUMPING_METHOD_HANDLES = 1 << 2;
53 private static final int IS_DUMPING_STATIC_ARCHIVE = 1 << 3;
54 private static final int IS_LOGGING_LAMBDA_FORM_INVOKERS = 1 << 4;
55 private static final int IS_USING_ARCHIVE = 1 << 5;
56 private static final int IS_DUMPING_HEAP = 1 << 6;
57 private static final int IS_LOGGING_DYNAMIC_PROXIES = 1 << 7;
58
59 private static final int configStatus = getCDSConfigStatus();
60
61 /**
62 * Should we log the use of lambda form invokers?
63 */
64 public static boolean isLoggingLambdaFormInvokers() {
65 return (configStatus & IS_LOGGING_LAMBDA_FORM_INVOKERS) != 0;
66 }
67
68 /**
69 * Is the VM writing to a (static or dynamic) CDS archive.
70 */
71 public static boolean isDumpingArchive() {
72 return (configStatus & IS_DUMPING_ARCHIVE) != 0;
73 }
74
75 /**
76 * Is the VM using at least one CDS archive?
77 */
78 public static boolean isUsingArchive() {
79 return (configStatus & IS_USING_ARCHIVE) != 0;
80 }
81
82 /**
83 * Is dumping static archive.
84 */
85 public static boolean isDumpingStaticArchive() {
86 return (configStatus & IS_DUMPING_STATIC_ARCHIVE) != 0;
87 }
88
89 public static boolean isDumpingHeap() {
90 return (configStatus & IS_DUMPING_HEAP) != 0;
91 }
92
93 public static boolean isLoggingDynamicProxies() {
94 return (configStatus & IS_LOGGING_DYNAMIC_PROXIES) != 0;
95 }
96
97 public static boolean isDumpingAOTLinkedClasses() {
98 return (configStatus & IS_DUMPING_AOT_LINKED_CLASSES) != 0;
99 }
100
101 public static boolean isSingleThreadVM() {
102 return isDumpingStaticArchive();
103 }
104
105 private static native int getCDSConfigStatus();
106 private static native void logLambdaFormInvoker(String line);
107
108
109 // Used only when dumping static archive to keep weak references alive to
110 // ensure that Soft/Weak Reference objects can be reliably archived.
111 private static ArrayList<Object> keepAliveList;
112
113 public static void keepAlive(Object s) {
114 assert isSingleThreadVM(); // no need for synchronization
115 assert isDumpingStaticArchive();
116 if (keepAliveList == null) {
153 public static native long getRandomSeedForDumping();
154
155 /**
156 * log lambda form invoker holder, name and method type
157 */
158 public static void logLambdaFormInvoker(String prefix, String holder, String name, String type) {
159 if (isLoggingLambdaFormInvokers()) {
160 logLambdaFormInvoker(prefix + " " + holder + " " + name + " " + type);
161 }
162 }
163
164 /**
165 * log species
166 */
167 public static void logSpeciesType(String prefix, String cn) {
168 if (isLoggingLambdaFormInvokers()) {
169 logLambdaFormInvoker(prefix + " " + cn);
170 }
171 }
172
173 public static void logDynamicProxy(ClassLoader loader, String proxyName,
174 Class<?>[] interfaces, int accessFlags) {
175 Objects.requireNonNull(proxyName);
176 Objects.requireNonNull(interfaces);
177 logDynamicProxy0(loader, proxyName, interfaces, accessFlags);
178 }
179 private static native void logDynamicProxy0(ClassLoader loader, String proxyName,
180 Class<?>[] interfaces, int accessFlags);
181
182 static final String DIRECT_HOLDER_CLASS_NAME = "java.lang.invoke.DirectMethodHandle$Holder";
183 static final String DELEGATING_HOLDER_CLASS_NAME = "java.lang.invoke.DelegatingMethodHandle$Holder";
184 static final String BASIC_FORMS_HOLDER_CLASS_NAME = "java.lang.invoke.LambdaForm$Holder";
185 static final String INVOKERS_HOLDER_CLASS_NAME = "java.lang.invoke.Invokers$Holder";
186
187 private static boolean isValidHolderName(String name) {
188 return name.equals(DIRECT_HOLDER_CLASS_NAME) ||
189 name.equals(DELEGATING_HOLDER_CLASS_NAME) ||
190 name.equals(BASIC_FORMS_HOLDER_CLASS_NAME) ||
191 name.equals(INVOKERS_HOLDER_CLASS_NAME);
192 }
193
194 private static boolean isBasicTypeChar(char c) {
195 return "LIJFDV".indexOf(c) >= 0;
196 }
197
198 private static boolean isValidMethodType(String type) {
199 String[] typeParts = type.split("_");
200 // check return type (second part)
201 if (typeParts.length != 2 || typeParts[1].length() != 1
|