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