34 import java.net.URL;
35 import java.net.URLClassLoader;
36 import java.nio.file.InvalidPathException;
37 import java.nio.file.Path;
38 import java.util.Arrays;
39 import java.util.ArrayList;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Objects;
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_ARCHIVE = 1 << 0;
51 private static final int IS_DUMPING_STATIC_ARCHIVE = 1 << 1;
52 private static final int IS_LOGGING_LAMBDA_FORM_INVOKERS = 1 << 2;
53 private static final int IS_USING_ARCHIVE = 1 << 3;
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 private static native int getCDSConfigStatus();
85 private static native void logLambdaFormInvoker(String line);
86
87 /**
88 * Initialize archived static fields in the given Class using archived
89 * values from CDS dump time. Also initialize the classes of objects in
90 * the archived graph referenced by those fields.
91 *
92 * Those static fields remain as uninitialized if there is no mapped CDS
93 * java heap data or there is any error during initialization of the
94 * object class in the archived graph.
95 */
96 public static native void initializeFromArchive(Class<?> c);
97
98 /**
99 * Ensure that the native representation of all archived java.lang.Module objects
100 * are properly restored.
101 */
102 public static native void defineArchivedModules(ClassLoader platformLoader, ClassLoader systemLoader);
103
109 public static native long getRandomSeedForDumping();
110
111 /**
112 * log lambda form invoker holder, name and method type
113 */
114 public static void logLambdaFormInvoker(String prefix, String holder, String name, String type) {
115 if (isLoggingLambdaFormInvokers()) {
116 logLambdaFormInvoker(prefix + " " + holder + " " + name + " " + type);
117 }
118 }
119
120 /**
121 * log species
122 */
123 public static void logSpeciesType(String prefix, String cn) {
124 if (isLoggingLambdaFormInvokers()) {
125 logLambdaFormInvoker(prefix + " " + cn);
126 }
127 }
128
129 static final String DIRECT_HOLDER_CLASS_NAME = "java.lang.invoke.DirectMethodHandle$Holder";
130 static final String DELEGATING_HOLDER_CLASS_NAME = "java.lang.invoke.DelegatingMethodHandle$Holder";
131 static final String BASIC_FORMS_HOLDER_CLASS_NAME = "java.lang.invoke.LambdaForm$Holder";
132 static final String INVOKERS_HOLDER_CLASS_NAME = "java.lang.invoke.Invokers$Holder";
133
134 private static boolean isValidHolderName(String name) {
135 return name.equals(DIRECT_HOLDER_CLASS_NAME) ||
136 name.equals(DELEGATING_HOLDER_CLASS_NAME) ||
137 name.equals(BASIC_FORMS_HOLDER_CLASS_NAME) ||
138 name.equals(INVOKERS_HOLDER_CLASS_NAME);
139 }
140
141 private static boolean isBasicTypeChar(char c) {
142 return "LIJFDV".indexOf(c) >= 0;
143 }
144
145 private static boolean isValidMethodType(String type) {
146 String[] typeParts = type.split("_");
147 // check return type (second part)
148 if (typeParts.length != 2 || typeParts[1].length() != 1
432
433 if (name.equals(currentClassName)) {
434 // Note: the following call will call back to <code>this.findClass(name)</code> to
435 // resolve the super types of the named class.
436 return super.findClass(name);
437 }
438 if (name.equals(currentSuperClass.getName())) {
439 return currentSuperClass;
440 }
441 if (currentInterfaces != null) {
442 for (Class<?> c : currentInterfaces) {
443 if (name.equals(c.getName())) {
444 return c;
445 }
446 }
447 }
448
449 throw new ClassNotFoundException(name);
450 }
451 }
452 }
|
34 import java.net.URL;
35 import java.net.URLClassLoader;
36 import java.nio.file.InvalidPathException;
37 import java.nio.file.Path;
38 import java.util.Arrays;
39 import java.util.ArrayList;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Objects;
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_ARCHIVE = 1 << 0;
51 private static final int IS_DUMPING_STATIC_ARCHIVE = 1 << 1;
52 private static final int IS_LOGGING_LAMBDA_FORM_INVOKERS = 1 << 2;
53 private static final int IS_USING_ARCHIVE = 1 << 3;
54 private static final int IS_DUMPING_HEAP = 1 << 4;
55 private static final int IS_LOGGING_DYNAMIC_PROXIES = 1 << 5;
56 private static final int IS_DUMPING_PACKAGES = 1 << 6;
57 private static final int IS_DUMPING_PROTECTION_DOMAINS = 1 << 7;
58 private static final int configStatus = getCDSConfigStatus();
59
60 /**
61 * Should we log the use of lambda form invokers?
62 */
63 public static boolean isLoggingLambdaFormInvokers() {
64 return (configStatus & IS_LOGGING_LAMBDA_FORM_INVOKERS) != 0;
65 }
66
67 /**
68 * Is the VM writing to a (static or dynamic) CDS archive.
69 */
70 public static boolean isDumpingArchive() {
71 return (configStatus & IS_DUMPING_ARCHIVE) != 0;
72 }
73
74 /**
75 * Is the VM using at least one CDS archive?
76 */
77 public static boolean isUsingArchive() {
78 return (configStatus & IS_USING_ARCHIVE) != 0;
79 }
80
81 /**
82 * Is dumping static archive.
83 */
84 public static boolean isDumpingStaticArchive() {
85 return (configStatus & IS_DUMPING_STATIC_ARCHIVE) != 0;
86 }
87
88 public static boolean isDumpingHeap() {
89 return (configStatus & IS_DUMPING_HEAP) != 0;
90 }
91
92 public static boolean isLoggingDynamicProxies() {
93 return (configStatus & IS_LOGGING_DYNAMIC_PROXIES) != 0;
94 }
95
96 public static boolean isDumpingPackages() {
97 return (configStatus & IS_DUMPING_PACKAGES) != 0;
98 }
99
100 public static boolean isDumpingProtectionDomains() {
101 return (configStatus & IS_DUMPING_PROTECTION_DOMAINS) != 0;
102 }
103
104 private static native int getCDSConfigStatus();
105 private static native void logLambdaFormInvoker(String line);
106
107 /**
108 * Initialize archived static fields in the given Class using archived
109 * values from CDS dump time. Also initialize the classes of objects in
110 * the archived graph referenced by those fields.
111 *
112 * Those static fields remain as uninitialized if there is no mapped CDS
113 * java heap data or there is any error during initialization of the
114 * object class in the archived graph.
115 */
116 public static native void initializeFromArchive(Class<?> c);
117
118 /**
119 * Ensure that the native representation of all archived java.lang.Module objects
120 * are properly restored.
121 */
122 public static native void defineArchivedModules(ClassLoader platformLoader, ClassLoader systemLoader);
123
129 public static native long getRandomSeedForDumping();
130
131 /**
132 * log lambda form invoker holder, name and method type
133 */
134 public static void logLambdaFormInvoker(String prefix, String holder, String name, String type) {
135 if (isLoggingLambdaFormInvokers()) {
136 logLambdaFormInvoker(prefix + " " + holder + " " + name + " " + type);
137 }
138 }
139
140 /**
141 * log species
142 */
143 public static void logSpeciesType(String prefix, String cn) {
144 if (isLoggingLambdaFormInvokers()) {
145 logLambdaFormInvoker(prefix + " " + cn);
146 }
147 }
148
149 public static void logDynamicProxy(ClassLoader loader, String proxyName,
150 Class<?>[] interfaces, int accessFlags) {
151 Objects.requireNonNull(proxyName);
152 Objects.requireNonNull(interfaces);
153 logDynamicProxy0(loader, proxyName, interfaces, accessFlags);
154 }
155 private static native void logDynamicProxy0(ClassLoader loader, String proxyName,
156 Class<?>[] interfaces, int accessFlags);
157
158 static final String DIRECT_HOLDER_CLASS_NAME = "java.lang.invoke.DirectMethodHandle$Holder";
159 static final String DELEGATING_HOLDER_CLASS_NAME = "java.lang.invoke.DelegatingMethodHandle$Holder";
160 static final String BASIC_FORMS_HOLDER_CLASS_NAME = "java.lang.invoke.LambdaForm$Holder";
161 static final String INVOKERS_HOLDER_CLASS_NAME = "java.lang.invoke.Invokers$Holder";
162
163 private static boolean isValidHolderName(String name) {
164 return name.equals(DIRECT_HOLDER_CLASS_NAME) ||
165 name.equals(DELEGATING_HOLDER_CLASS_NAME) ||
166 name.equals(BASIC_FORMS_HOLDER_CLASS_NAME) ||
167 name.equals(INVOKERS_HOLDER_CLASS_NAME);
168 }
169
170 private static boolean isBasicTypeChar(char c) {
171 return "LIJFDV".indexOf(c) >= 0;
172 }
173
174 private static boolean isValidMethodType(String type) {
175 String[] typeParts = type.split("_");
176 // check return type (second part)
177 if (typeParts.length != 2 || typeParts[1].length() != 1
461
462 if (name.equals(currentClassName)) {
463 // Note: the following call will call back to <code>this.findClass(name)</code> to
464 // resolve the super types of the named class.
465 return super.findClass(name);
466 }
467 if (name.equals(currentSuperClass.getName())) {
468 return currentSuperClass;
469 }
470 if (currentInterfaces != null) {
471 for (Class<?> c : currentInterfaces) {
472 if (name.equals(c.getName())) {
473 return c;
474 }
475 }
476 }
477
478 throw new ClassNotFoundException(name);
479 }
480 }
481
482 /**
483 * This class is to ensure that the dynamic CDS archive contains at least one class, so we can avoid
484 * error handling for the degenerative case where the dynamic archive is completely empty (which doesn't
485 * happen for realistic applications).
486 */
487 private static class DummyForDynamicArchive {}
488 }
|