1 | /* |
2 | * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP |
26 | #define SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP |
27 | |
28 | #include "oops/klass.hpp" |
29 | #include "classfile/dictionary.hpp" |
30 | #include "classfile/packageEntry.hpp" |
31 | #include "classfile/systemDictionary.hpp" |
32 | #include "memory/filemap.hpp" |
33 | |
34 | |
35 | /*=============================================================================== |
36 | |
37 | Handling of the classes in the AppCDS archive |
38 | |
39 | To ensure safety and to simplify the implementation, archived classes are |
40 | "segregated" into 2 types. The following rules describe how they |
41 | are stored and looked up. |
42 | |
43 | [1] Category of archived classes |
44 | |
45 | There are 2 disjoint groups of classes stored in the AppCDS archive: |
46 | |
47 | BUILTIN: These classes may be defined ONLY by the BOOT/PLATFORM/APP |
48 | loaders. |
49 | |
50 | UNREGISTERED: These classes may be defined ONLY by a ClassLoader |
51 | instance that's not listed above (using fingerprint matching) |
52 | |
53 | [2] How classes from different categories are specified in the classlist: |
54 | |
55 | Starting from JDK9, each class in the classlist may be specified with |
56 | these keywords: "id", "super", "interfaces", "loader" and "source". |
57 | |
58 | |
59 | BUILTIN Only the "id" keyword may be (optionally) specified. All other |
60 | keywords are forbidden. |
61 | |
62 | The named class is looked up from the jimage and from |
63 | Xbootclasspath/a and CLASSPATH. |
64 | |
65 | UNREGISTERED: The "id", "super", and "source" keywords must all be |
66 | specified. |
67 | |
68 | The "interfaces" keyword must be specified if the class implements |
69 | one or more local interfaces. The "interfaces" keyword must not be |
70 | specified if the class does not implement local interfaces. |
71 | |
72 | The named class is looked up from the location specified in the |
73 | "source" keyword. |
74 | |
75 | Example classlist: |
76 | |
77 | # BUILTIN |
78 | java/lang/Object id: 0 |
79 | java/lang/Cloneable id: 1 |
80 | java/lang/String |
81 | |
82 | # UNREGISTERED |
83 | Bar id: 3 super: 0 interfaces: 1 source: /foo.jar |
84 | |
85 | |
86 | [3] Identifying the category of archived classes |
87 | |
88 | BUILTIN: (C->shared_classpath_index() >= 0) |
89 | UNREGISTERED: (C->shared_classpath_index() == UNREGISTERED_INDEX (-9999)) |
90 | |
91 | [4] Lookup of archived classes at run time: |
92 | |
93 | (a) BUILTIN loaders: |
94 | |
95 | search _builtin_dictionary |
96 | |
97 | (b) UNREGISTERED loaders: |
98 | |
99 | search _unregistered_dictionary for an entry that matches the |
100 | (name, clsfile_len, clsfile_crc32). |
101 | |
102 | ===============================================================================*/ |
103 | #define UNREGISTERED_INDEX -9999 |
104 | |
105 | class ClassFileStream; |
106 | class DumpTimeSharedClassInfo; |
107 | class DumpTimeSharedClassTable; |
108 | class RunTimeSharedClassInfo; |
109 | class RunTimeSharedDictionary; |
110 | |
111 | class SystemDictionaryShared: public SystemDictionary { |
112 | friend class ExcludeDumpTimeSharedClasses; |
113 | public: |
114 | enum { |
115 | FROM_FIELD_IS_PROTECTED = 1 << 0, |
116 | FROM_IS_ARRAY = 1 << 1, |
117 | FROM_IS_OBJECT = 1 << 2 |
118 | }; |
119 | |
120 | private: |
121 | // These _shared_xxxs arrays are used to initialize the java.lang.Package and |
122 | // java.security.ProtectionDomain objects associated with each shared class. |
123 | // |
124 | // See SystemDictionaryShared::init_security_info for more info. |
125 | static objArrayOop _shared_protection_domains; |
126 | static objArrayOop _shared_jar_urls; |
127 | static objArrayOop _shared_jar_manifests; |
128 | |
129 | static InstanceKlass* load_shared_class_for_builtin_loader( |
130 | Symbol* class_name, |
131 | Handle class_loader, |
132 | TRAPS); |
133 | static Handle get_package_name(Symbol* class_name, TRAPS); |
134 | |
135 | |
136 | // Package handling: |
137 | // |
138 | // 1. For named modules in the runtime image |
139 | // BOOT classes: Reuses the existing JVM_GetSystemPackage(s) interfaces |
140 | // to get packages in named modules for shared classes. |
141 | // Package for non-shared classes in named module is also |
142 | // handled using JVM_GetSystemPackage(s). |
143 | // |
144 | // APP classes: VM calls ClassLoaders.AppClassLoader::definePackage(String, Module) |
145 | // to define package for shared app classes from named |
146 | // modules. |
147 | // |
148 | // PLATFORM classes: VM calls ClassLoaders.PlatformClassLoader::definePackage(String, Module) |
149 | // to define package for shared platform classes from named |
150 | // modules. |
151 | // |
152 | // 2. For unnamed modules |
153 | // BOOT classes: Reuses the existing JVM_GetSystemPackage(s) interfaces to |
154 | // get packages for shared boot classes in unnamed modules. |
155 | // |
156 | // APP classes: VM calls ClassLoaders.AppClassLoader::defineOrCheckPackage() |
157 | // with with the manifest and url from archived data. |
158 | // |
159 | // PLATFORM classes: No package is defined. |
160 | // |
161 | // The following two define_shared_package() functions are used to define |
162 | // package for shared APP and PLATFORM classes. |
163 | static void define_shared_package(Symbol* class_name, |
164 | Handle class_loader, |
165 | Handle manifest, |
166 | Handle url, |
167 | TRAPS); |
168 | static void define_shared_package(Symbol* class_name, |
169 | Handle class_loader, |
170 | ModuleEntry* mod_entry, |
171 | TRAPS); |
172 | |
173 | static Handle get_shared_jar_manifest(int shared_path_index, TRAPS); |
174 | static Handle get_shared_jar_url(int shared_path_index, TRAPS); |
175 | static Handle get_protection_domain_from_classloader(Handle class_loader, |
176 | Handle url, TRAPS); |
177 | static Handle get_shared_protection_domain(Handle class_loader, |
178 | int shared_path_index, |
179 | Handle url, |
180 | TRAPS); |
181 | static Handle get_shared_protection_domain(Handle class_loader, |
182 | ModuleEntry* mod, TRAPS); |
183 | static Handle init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS); |
184 | |
185 | static void atomic_set_array_index(objArrayOop array, int index, oop o) { |
186 | // Benign race condition: array.obj_at(index) may already be filled in. |
187 | // The important thing here is that all threads pick up the same result. |
188 | // It doesn't matter which racing thread wins, as long as only one |
189 | // result is used by all threads, and all future queries. |
190 | array->atomic_compare_exchange_oop(index, o, NULL); |
191 | } |
192 | |
193 | static oop shared_protection_domain(int index); |
194 | static void atomic_set_shared_protection_domain(int index, oop pd) { |
195 | atomic_set_array_index(_shared_protection_domains, index, pd); |
196 | } |
197 | static void allocate_shared_protection_domain_array(int size, TRAPS); |
198 | static oop shared_jar_url(int index); |
199 | static void atomic_set_shared_jar_url(int index, oop url) { |
200 | atomic_set_array_index(_shared_jar_urls, index, url); |
201 | } |
202 | static void allocate_shared_jar_url_array(int size, TRAPS); |
203 | static oop shared_jar_manifest(int index); |
204 | static void atomic_set_shared_jar_manifest(int index, oop man) { |
205 | atomic_set_array_index(_shared_jar_manifests, index, man); |
206 | } |
207 | static void allocate_shared_jar_manifest_array(int size, TRAPS); |
208 | static InstanceKlass* acquire_class_for_current_thread( |
209 | InstanceKlass *ik, |
210 | Handle class_loader, |
211 | Handle protection_domain, |
212 | const ClassFileStream* cfs, |
213 | TRAPS); |
214 | static DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k); |
215 | static void write_dictionary(RunTimeSharedDictionary* dictionary, |
216 | bool is_builtin, |
217 | bool is_static_archive = true); |
218 | static bool is_jfr_event_class(InstanceKlass *k); |
219 | static void warn_excluded(InstanceKlass* k, const char* reason); |
220 | static bool should_be_excluded(InstanceKlass* k); |
221 | |
222 | DEBUG_ONLY(static bool _no_class_loading_should_happen;) |
223 | public: |
224 | static InstanceKlass* find_builtin_class(Symbol* class_name); |
225 | |
226 | static const RunTimeSharedClassInfo* find_record(RunTimeSharedDictionary* dict, Symbol* name); |
227 | |
228 | static bool has_platform_or_app_classes(); |
229 | |
230 | // Called by PLATFORM/APP loader only |
231 | static InstanceKlass* find_or_load_shared_class(Symbol* class_name, |
232 | Handle class_loader, |
233 | TRAPS); |
234 | |
235 | |
236 | static void allocate_shared_data_arrays(int size, TRAPS); |
237 | static void oops_do(OopClosure* f); |
238 | |
239 | // Check if sharing is supported for the class loader. |
240 | static bool is_sharing_possible(ClassLoaderData* loader_data); |
241 | static bool is_shared_class_visible_for_classloader(InstanceKlass* ik, |
242 | Handle class_loader, |
243 | const char* pkg_string, |
244 | Symbol* pkg_name, |
245 | PackageEntry* pkg_entry, |
246 | ModuleEntry* mod_entry, |
247 | TRAPS); |
248 | static PackageEntry* get_package_entry(Symbol* pkg, |
249 | ClassLoaderData *loader_data) { |
250 | if (loader_data != NULL) { |
251 | PackageEntryTable* pkgEntryTable = loader_data->packages(); |
252 | return pkgEntryTable->lookup_only(pkg); |
253 | } |
254 | return NULL; |
255 | } |
256 | |
257 | static bool add_unregistered_class(InstanceKlass* k, TRAPS); |
258 | static InstanceKlass* dump_time_resolve_super_or_fail(Symbol* child_name, |
259 | Symbol* class_name, |
260 | Handle class_loader, |
261 | Handle protection_domain, |
262 | bool is_superclass, |
263 | TRAPS); |
264 | |
265 | static void init_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN; |
266 | static void remove_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN; |
267 | |
268 | static Dictionary* boot_loader_dictionary() { |
269 | return ClassLoaderData::the_null_class_loader_data()->dictionary(); |
270 | } |
271 | |
272 | static void update_shared_entry(InstanceKlass* klass, int id); |
273 | static void set_shared_class_misc_info(InstanceKlass* k, ClassFileStream* cfs); |
274 | |
275 | static InstanceKlass* lookup_from_stream(Symbol* class_name, |
276 | Handle class_loader, |
277 | Handle protection_domain, |
278 | const ClassFileStream* st, |
279 | TRAPS); |
280 | // "verification_constraints" are a set of checks performed by |
281 | // VerificationType::is_reference_assignable_from when verifying a shared class during |
282 | // dump time. |
283 | // |
284 | // With AppCDS, it is possible to override archived classes by calling |
285 | // ClassLoader.defineClass() directly. SystemDictionary::load_shared_class() already |
286 | // ensures that you cannot load a shared class if its super type(s) are changed. However, |
287 | // we need an additional check to ensure that the verification_constraints did not change |
288 | // between dump time and runtime. |
289 | static bool add_verification_constraint(InstanceKlass* k, Symbol* name, |
290 | Symbol* from_name, bool from_field_is_protected, |
291 | bool from_is_array, bool from_is_object) NOT_CDS_RETURN_(false); |
292 | static void check_verification_constraints(InstanceKlass* klass, |
293 | TRAPS) NOT_CDS_RETURN; |
294 | static bool is_builtin(InstanceKlass* k) { |
295 | return (k->shared_classpath_index() != UNREGISTERED_INDEX); |
296 | } |
297 | static void check_excluded_classes(); |
298 | static void validate_before_archiving(InstanceKlass* k); |
299 | static bool is_excluded_class(InstanceKlass* k); |
300 | static void dumptime_classes_do(class MetaspaceClosure* it); |
301 | static size_t estimate_size_for_archive(); |
302 | static void write_to_archive(bool is_static_archive = true); |
303 | static void (class SerializeClosure* soc, |
304 | bool is_static_archive = true); |
305 | static void print() { return print_on(tty); } |
306 | static void print_on(outputStream* st) NOT_CDS_RETURN; |
307 | static void print_table_statistics(outputStream* st) NOT_CDS_RETURN; |
308 | static bool empty_dumptime_table() NOT_CDS_RETURN_(true); |
309 | |
310 | DEBUG_ONLY(static bool no_class_loading_should_happen() {return _no_class_loading_should_happen;}) |
311 | |
312 | #ifdef ASSERT |
313 | class NoClassLoadingMark: public StackObj { |
314 | public: |
315 | NoClassLoadingMark() { |
316 | assert(!_no_class_loading_should_happen, "must not be nested" ); |
317 | _no_class_loading_should_happen = true; |
318 | } |
319 | ~NoClassLoadingMark() { |
320 | _no_class_loading_should_happen = false; |
321 | } |
322 | }; |
323 | #endif |
324 | |
325 | }; |
326 | |
327 | #endif // SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP |
328 | |