1 /*
2 * Copyright (c) 2020, 2026, 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 #include "cds/aotLogging.hpp"
26 #include "cds/cdsConfig.hpp"
27 #include "cds/heapShared.inline.hpp"
28 #include "cds/serializeClosure.hpp"
29 #include "classfile/classLoaderData.inline.hpp"
30 #include "classfile/classLoaderDataShared.hpp"
31 #include "classfile/moduleEntry.hpp"
32 #include "classfile/modules.hpp"
33 #include "classfile/packageEntry.hpp"
34 #include "classfile/systemDictionary.hpp"
35 #include "logging/log.hpp"
36 #include "memory/metaspaceClosure.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/safepoint.hpp"
39
40 #if INCLUDE_CDS_JAVA_HEAP
41
42 bool ClassLoaderDataShared::_full_module_graph_loaded = false;
43
44 class ArchivedClassLoaderData {
45 Array<PackageEntry*>* _packages;
46 Array<ModuleEntry*>* _modules;
47 ModuleEntry* _unnamed_module;
48
49 void assert_valid(ClassLoaderData* loader_data) {
50 // loader_data may be null if the boot layer has loaded no modules for the platform or
51 // system loaders (e.g., if you create a custom JDK image with only java.base).
52 if (loader_data != nullptr) {
53 assert(!loader_data->has_class_mirror_holder(),
54 "loaders for non-strong hidden classes not supported");
55 }
56 }
57 public:
58 ArchivedClassLoaderData() : _packages(nullptr), _modules(nullptr), _unnamed_module(nullptr) {}
59
60 void iterate_roots(MetaspaceClosure* closure);
61 void build_tables(ClassLoaderData* loader_data, TRAPS);
62 void remove_unshareable_info();
63 ModuleEntry* unnamed_module() {
64 return _unnamed_module;
65 }
66
67 void serialize(SerializeClosure* f) {
68 f->do_ptr(&_packages);
69 f->do_ptr(&_modules);
70 f->do_ptr(&_unnamed_module);
71 }
72
73 void restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops);
74 void clear_archived_oops();
75 };
76
77 static ArchivedClassLoaderData _archived_boot_loader_data;
78 static ArchivedClassLoaderData _archived_platform_loader_data;
79 static ArchivedClassLoaderData _archived_system_loader_data;
80 static ModuleEntry* _archived_javabase_moduleEntry = nullptr;
81 static int _platform_loader_root_index = -1;
82 static int _system_loader_root_index = -1;
83
84 void ArchivedClassLoaderData::iterate_roots(MetaspaceClosure* it) {
85 assert(CDSConfig::is_dumping_full_module_graph(), "must be");
86 it->push(&_packages);
87 it->push(&_modules);
88 it->push(&_unnamed_module);
89 }
90
91 void ArchivedClassLoaderData::build_tables(ClassLoaderData* loader_data, TRAPS) {
92 assert(CDSConfig::is_dumping_full_module_graph(), "must be");
93 assert_valid(loader_data);
94 if (loader_data != nullptr) {
95 // We can't create hashtables at dump time because the hashcode depends on the
96 // address of the Symbols, which may be relocated at runtime due to ASLR.
97 // So we store the packages/modules in Arrays. At runtime, we create
98 // the hashtables using these arrays.
99 _packages = loader_data->packages()->build_aot_table(loader_data, CHECK);
100 _modules = loader_data->modules()->build_aot_table(loader_data, CHECK);
101 _unnamed_module = loader_data->unnamed_module();
102 }
103 }
104
105 void ArchivedClassLoaderData::remove_unshareable_info() {
106 if (_packages != nullptr) {
107 _packages = ArchiveBuilder::current()->get_buffered_addr(_packages);
108 for (int i = 0; i < _packages->length(); i++) {
109 _packages->at(i)->remove_unshareable_info();
110 }
111 }
112 if (_modules != nullptr) {
113 _modules = ArchiveBuilder::current()->get_buffered_addr(_modules);
114 for (int i = 0; i < _modules->length(); i++) {
115 _modules->at(i)->remove_unshareable_info();
116 }
117 }
118 if (_unnamed_module != nullptr) {
119 _unnamed_module = ArchiveBuilder::current()->get_buffered_addr(_unnamed_module);
120 _unnamed_module->remove_unshareable_info();
121 }
122 }
123
124 void ArchivedClassLoaderData::restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops) {
125 assert(CDSConfig::is_using_full_module_graph(), "must be");
126 assert_valid(loader_data);
127 if (_modules != nullptr) { // Could be null if we have archived no modules for platform/system loaders
128 ModuleEntryTable* modules = loader_data->modules();
129 PackageEntryTable* packages = loader_data->packages();
130
131 MutexLocker m1(Module_lock);
132 if (do_entries) {
133 modules->load_archived_entries(loader_data, _modules);
134 packages->load_archived_entries(_packages);
135 }
136 if (do_oops) {
137 modules->restore_archived_oops(loader_data, _modules);
138 if (_unnamed_module != nullptr) {
139 oop module_oop = _unnamed_module->module_oop();
140 assert(module_oop != nullptr, "must be already set");
141 assert(_unnamed_module == java_lang_Module::module_entry(module_oop), "must be already set");
142 assert(loader_data->class_loader() == java_lang_Module::loader(module_oop), "must be set in dump time");
143 }
144 }
145 }
146 }
147
148 void ArchivedClassLoaderData::clear_archived_oops() {
149 assert(!CDSConfig::is_using_full_module_graph(), "must be");
150 if (_modules != nullptr) {
151 for (int i = 0; i < _modules->length(); i++) {
152 _modules->at(i)->clear_archived_oops();
153 }
154 if (_unnamed_module != nullptr) {
155 _unnamed_module->clear_archived_oops();
156 }
157 }
158 }
159
160 // ------------------------------
161
162 void ClassLoaderDataShared::load_archived_platform_and_system_class_loaders() {
163 // The streaming object loader prefers loading the class loader related objects before
164 // the CLD constructor which has a NoSafepointVerifier.
165 if (!HeapShared::is_loading_streaming_mode()) {
166 return;
167 }
168
169 // Ensure these class loaders are eagerly materialized before their CLDs are created.
170 HeapShared::get_root(_platform_loader_root_index, false /* clear */);
171 HeapShared::get_root(_system_loader_root_index, false /* clear */);
172
173 if (Universe::is_module_initialized() || !CDSConfig::is_using_full_module_graph()) {
174 return;
175 }
176
177 // When using the full module graph, we need to load unnamed modules too.
178 ModuleEntry* platform_loader_module_entry = _archived_platform_loader_data.unnamed_module();
179 if (platform_loader_module_entry != nullptr) {
180 platform_loader_module_entry->preload_archived_oops();
181 }
182
183 ModuleEntry* system_loader_module_entry = _archived_system_loader_data.unnamed_module();
184 if (system_loader_module_entry != nullptr) {
185 system_loader_module_entry->preload_archived_oops();
186 }
187 }
188
189 static ClassLoaderData* null_class_loader_data() {
190 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
191 assert(loader_data != nullptr, "must be");
192 return loader_data;
193 }
194
195 static ClassLoaderData* java_platform_loader_data_or_null() {
196 return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader());
197 }
198
199 static ClassLoaderData* java_system_loader_data_or_null() {
200 return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_system_loader());
201 }
202
203 // ModuleEntryTables (even if empty) are required for iterate_symbols() to scan the
204 // platform/system loaders inside the CDS safepoint, but the tables can be created only
205 // when outside of safepoints. Let's do that now.
206 void ClassLoaderDataShared::ensure_module_entry_tables_exist() {
207 assert(!SafepointSynchronize::is_at_safepoint(), "sanity");
208 ensure_module_entry_table_exists(SystemDictionary::java_platform_loader());
209 ensure_module_entry_table_exists(SystemDictionary::java_system_loader());
210 }
211
212 void ClassLoaderDataShared::ensure_module_entry_table_exists(oop class_loader) {
213 Handle h_loader(JavaThread::current(), class_loader);
214 ModuleEntryTable* met = Modules::get_module_entry_table(h_loader);
215 assert(met != nullptr, "sanity");
216 }
217
218 void ClassLoaderDataShared::build_tables(TRAPS) {
219 assert(CDSConfig::is_dumping_full_module_graph(), "must be");
220 _archived_boot_loader_data.build_tables(null_class_loader_data(), CHECK);
221 _archived_platform_loader_data.build_tables(java_platform_loader_data_or_null(), CHECK);
222 _archived_system_loader_data.build_tables(java_system_loader_data_or_null(), CHECK);
223 }
224
225 void ClassLoaderDataShared::iterate_roots(MetaspaceClosure* it) {
226 assert(CDSConfig::is_dumping_full_module_graph(), "must be");
227 _archived_boot_loader_data.iterate_roots(it);
228 _archived_platform_loader_data.iterate_roots(it);
229 _archived_system_loader_data.iterate_roots(it);
230 }
231
232 void ClassLoaderDataShared::remove_unshareable_info() {
233 assert(CDSConfig::is_dumping_full_module_graph(), "must be");
234 _archived_boot_loader_data.remove_unshareable_info();
235 _archived_platform_loader_data.remove_unshareable_info();
236 _archived_system_loader_data.remove_unshareable_info();
237
238 _archived_javabase_moduleEntry = ArchiveBuilder::current()->get_buffered_addr(ModuleEntryTable::javabase_moduleEntry());
239
240 _platform_loader_root_index = HeapShared::append_root(SystemDictionary::java_platform_loader());
241 _system_loader_root_index = HeapShared::append_root(SystemDictionary::java_system_loader());
242 }
243
244 void ClassLoaderDataShared::serialize(SerializeClosure* f) {
245 _archived_boot_loader_data.serialize(f);
246 _archived_platform_loader_data.serialize(f);
247 _archived_system_loader_data.serialize(f);
248 f->do_ptr(&_archived_javabase_moduleEntry);
249 f->do_int(&_platform_loader_root_index);
250 f->do_int(&_system_loader_root_index);
251 }
252
253 ModuleEntry* ClassLoaderDataShared::archived_boot_unnamed_module() {
254 if (CDSConfig::is_using_full_module_graph()) {
255 return _archived_boot_loader_data.unnamed_module();
256 } else {
257 return nullptr;
258 }
259 }
260
261 ModuleEntry* ClassLoaderDataShared::archived_unnamed_module(ClassLoaderData* loader_data) {
262 ModuleEntry* archived_module = nullptr;
263
264 if (!Universe::is_module_initialized() && CDSConfig::is_using_full_module_graph()) {
265 precond(_platform_loader_root_index >= 0);
266 precond(_system_loader_root_index >= 0);
267
268 if (loader_data->class_loader() == HeapShared::get_root(_platform_loader_root_index)) {
269 archived_module = _archived_platform_loader_data.unnamed_module();
270 } else if (loader_data->class_loader() == HeapShared::get_root(_system_loader_root_index)) {
271 archived_module = _archived_system_loader_data.unnamed_module();
272 }
273 }
274
275 return archived_module;
276 }
277
278 void ClassLoaderDataShared::clear_archived_oops() {
279 assert(!CDSConfig::is_using_full_module_graph(), "must be");
280 _archived_boot_loader_data.clear_archived_oops();
281 _archived_platform_loader_data.clear_archived_oops();
282 _archived_system_loader_data.clear_archived_oops();
283 if (_platform_loader_root_index >= 0) {
284 HeapShared::clear_root(_platform_loader_root_index);
285 HeapShared::clear_root(_system_loader_root_index);
286 }
287 }
288
289 // Must be done before ClassLoader::create_javabase()
290 void ClassLoaderDataShared::restore_archived_entries_for_null_class_loader_data() {
291 precond(CDSConfig::is_using_full_module_graph());
292 _archived_boot_loader_data.restore(null_class_loader_data(), true, false);
293 ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry);
294 aot_log_info(aot)("use_full_module_graph = true; java.base = " INTPTR_FORMAT,
295 p2i(_archived_javabase_moduleEntry));
296 }
297
298 oop ClassLoaderDataShared::restore_archived_oops_for_null_class_loader_data() {
299 assert(CDSConfig::is_using_full_module_graph(), "must be");
300 _archived_boot_loader_data.restore(null_class_loader_data(), false, true);
301 return _archived_javabase_moduleEntry->module_oop();
302 }
303
304 void ClassLoaderDataShared::restore_java_platform_loader_from_archive(ClassLoaderData* loader_data) {
305 assert(CDSConfig::is_using_full_module_graph(), "must be");
306 _archived_platform_loader_data.restore(loader_data, true, true);
307 }
308
309 void ClassLoaderDataShared::restore_java_system_loader_from_archive(ClassLoaderData* loader_data) {
310 assert(CDSConfig::is_using_full_module_graph(), "must be");
311 _archived_system_loader_data.restore(loader_data, true, true);
312 _full_module_graph_loaded = true;
313 }
314
315 // This is called before AOTLinkedClassBulkLoader starts preloading classes. It makes sure that
316 // when we preload any class, its module is already valid.
317 void ClassLoaderDataShared::restore_archived_modules_for_preloading_classes(JavaThread* current) {
318 precond(CDSConfig::is_using_aot_linked_classes());
319
320 precond(_platform_loader_root_index >= 0);
321 precond(_system_loader_root_index >= 0);
322
323 Handle h_platform_loader(current, HeapShared::get_root(_platform_loader_root_index));
324 Handle h_system_loader(current, HeapShared::get_root(_system_loader_root_index));
325 Modules::init_archived_modules(current, h_platform_loader, h_system_loader);
326 }
327
328 #endif // INCLUDE_CDS_JAVA_HEAP