1 /*
2 * Copyright (c) 2024, 2025, 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/aotClassInitializer.hpp"
26 #include "cds/aotClassLinker.hpp"
27 #include "cds/aotLinkedClassBulkLoader.hpp"
28 #include "cds/aotLinkedClassTable.hpp"
29 #include "cds/cdsConfig.hpp"
30 #include "cds/heapShared.hpp"
31 #include "classfile/classLoaderData.hpp"
32 #include "classfile/classLoaderDataShared.hpp"
33 #include "classfile/javaClasses.hpp"
34 #include "classfile/systemDictionary.hpp"
35 #include "classfile/systemDictionaryShared.hpp"
36 #include "classfile/vmClasses.hpp"
37 #include "compiler/compilationPolicy.hpp"
38 #include "gc/shared/gcVMOperations.hpp"
39 #include "memory/resourceArea.hpp"
40 #include "oops/instanceKlass.hpp"
41 #include "oops/klass.inline.hpp"
42 #include "oops/trainingData.hpp"
43 #include "runtime/handles.inline.hpp"
44 #include "runtime/java.hpp"
45 #include "runtime/serviceThread.hpp"
46 #include "utilities/growableArray.hpp"
47
48 void AOTLinkedClassBulkLoader::serialize(SerializeClosure* soc) {
49 AOTLinkedClassTable::get()->serialize(soc);
50 }
51
52 // This function is called before the VM executes any Java code (include AOT-compiled Java methods).
53 //
54 // We populate the boot/platform/app class loaders with classes from the AOT cache. This is a fundamental
55 // step in restoring the JVM's state from the snapshot recorded in the AOT cache: other AOT optimizations
56 // such as AOT compiled methods can make direct references to the preloaded classes, knowing that
57 // these classes are guaranteed to be in at least the "loaded" state.
58 //
59 // Note: we can't link the classes yet because SharedRuntime is not yet ready to generate adapters.
60 void AOTLinkedClassBulkLoader::preload_classes(JavaThread* current) {
61 preload_classes_impl(current);
62 if (current->has_pending_exception()) {
63 exit_on_exception(current);
64 }
65 }
66
67 void AOTLinkedClassBulkLoader::preload_classes_impl(TRAPS) {
68 precond(CDSConfig::is_using_aot_linked_classes());
69
76 preload_classes_in_table(table->boot1(), "boot1", Handle(), CHECK);
77 preload_classes_in_table(table->boot2(), "boot2", Handle(), CHECK);
78
79 initiate_loading(THREAD, "plat", h_platform_loader, table->boot1());
80 initiate_loading(THREAD, "plat", h_platform_loader, table->boot2());
81 preload_classes_in_table(table->platform(), "plat", h_platform_loader, CHECK);
82
83 initiate_loading(THREAD, "app", h_system_loader, table->boot1());
84 initiate_loading(THREAD, "app", h_system_loader, table->boot2());
85 initiate_loading(THREAD, "app", h_system_loader, table->platform());
86 preload_classes_in_table(table->app(), "app", h_system_loader, CHECK);
87 }
88
89 void AOTLinkedClassBulkLoader::preload_classes_in_table(Array<InstanceKlass*>* classes,
90 const char* category_name, Handle loader, TRAPS) {
91 if (classes == nullptr) {
92 return;
93 }
94
95 for (int i = 0; i < classes->length(); i++) {
96 InstanceKlass* ik = classes->at(i);
97 if (log_is_enabled(Info, aot, load)) {
98 ResourceMark rm(THREAD);
99 log_info(aot, load)("%-5s %s%s", category_name, ik->external_name(),
100 ik->is_hidden() ? " (hidden)" : "");
101 }
102
103 SystemDictionary::preload_class(loader, ik, CHECK);
104
105 if (ik->is_hidden()) {
106 DEBUG_ONLY({
107 // Make sure we don't make this hidden class available by name, even if we don't
108 // use any special ClassLoaderData.
109 ResourceMark rm(THREAD);
110 assert(SystemDictionary::find_instance_klass(THREAD, ik->name(), loader) == nullptr,
111 "hidden classes cannot be accessible by name: %s", ik->external_name());
112 });
113 } else {
114 precond(SystemDictionary::find_instance_klass(THREAD, ik->name(), loader) == ik);
115 }
116 }
117 }
118
119 // Some cached heap objects may hold references to methods in aot-linked
120 // classes (via MemberName). We need to make sure all classes are
121 // linked before executing any bytecode.
122 void AOTLinkedClassBulkLoader::link_classes(JavaThread* current) {
123 link_classes_impl(current);
124 if (current->has_pending_exception()) {
125 exit_on_exception(current);
126 }
127 }
128
129 void AOTLinkedClassBulkLoader::link_classes_impl(TRAPS) {
130 precond(CDSConfig::is_using_aot_linked_classes());
131
132 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
133
134 link_classes_in_table(table->boot1(), CHECK);
135 link_classes_in_table(table->boot2(), CHECK);
136 link_classes_in_table(table->platform(), CHECK);
137 link_classes_in_table(table->app(), CHECK);
138 }
139
140 void AOTLinkedClassBulkLoader::link_classes_in_table(Array<InstanceKlass*>* classes, TRAPS) {
141 if (classes != nullptr) {
142 for (int i = 0; i < classes->length(); i++) {
143 // NOTE: CDSConfig::is_preserving_verification_constraints() is required
144 // when storing ik in the AOT cache. This means we don't have to verify
145 // ik at all.
146 //
147 // Without is_preserving_verification_constraints(), ik->link_class() may cause
148 // class loading, which may result in invocation of ClassLoader::loadClass() calls,
149 // which CANNOT happen because we are not ready to execute any Java byecodes yet
150 // at this point.
151 InstanceKlass* ik = classes->at(i);
152 ik->link_class(CHECK);
153 }
154 }
155 }
156
157 #ifdef ASSERT
199
200 if (log_is_enabled(Debug, aot, module)) {
201 ResourceMark rm;
202 log_debug(aot, module)("Validate module of %-5s %s", category_name, k->external_name());
203 }
204 precond(java_lang_Class::module(k->java_mirror()) == module_oop);
205
206 ArrayKlass* ak = k->array_klass_or_null();
207 while (ak != nullptr) {
208 if (log_is_enabled(Debug, aot, module)) {
209 ResourceMark rm;
210 log_debug(aot, module)("Validate module of %-5s %s", category_name, ak->external_name());
211 }
212 precond(java_lang_Class::module(ak->java_mirror()) == module_oop);
213 ak = ak->array_klass_or_null();
214 }
215 }
216 #endif
217
218 void AOTLinkedClassBulkLoader::init_javabase_classes(JavaThread* current) {
219 init_classes_for_loader(Handle(), AOTLinkedClassTable::get()->boot1(), current);
220 if (current->has_pending_exception()) {
221 exit_on_exception(current);
222 }
223 }
224
225 void AOTLinkedClassBulkLoader::init_non_javabase_classes(JavaThread* current) {
226 init_non_javabase_classes_impl(current);
227 if (current->has_pending_exception()) {
228 exit_on_exception(current);
229 }
230 }
231
232 void AOTLinkedClassBulkLoader::init_non_javabase_classes_impl(TRAPS) {
233 assert(CDSConfig::is_using_aot_linked_classes(), "sanity");
234
235 DEBUG_ONLY(validate_module_of_preloaded_classes());
236
237 // is_using_aot_linked_classes() requires is_using_full_module_graph(). As a result,
238 // the platform/system class loader should already have been initialized as part
239 // of the FMG support.
240 assert(CDSConfig::is_using_full_module_graph(), "must be");
241
242 Handle h_platform_loader(THREAD, SystemDictionary::java_platform_loader());
243 Handle h_system_loader(THREAD, SystemDictionary::java_system_loader());
244
245 assert(h_platform_loader() != nullptr, "must be");
246 assert(h_system_loader() != nullptr, "must be");
247
248 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
249 init_classes_for_loader(Handle(), table->boot2(), CHECK);
250 init_classes_for_loader(h_platform_loader, table->platform(), CHECK);
251 init_classes_for_loader(h_system_loader, table->app(), CHECK);
252
253 if (Universe::is_fully_initialized() && VerifyDuringStartup) {
254 // Make sure we're still in a clean state.
255 VM_Verify verify_op;
256 VMThread::execute(&verify_op);
257 }
258
259 if (AOTPrintTrainingInfo) {
260 tty->print_cr("==================== archived_training_data ** after all classes preloaded ====================");
261 TrainingData::print_archived_training_data_on(tty);
262 }
263 }
264
265 // For the AOT cache to function properly, all classes in the AOTLinkedClassTable
266 // must be loaded and linked. In addition, AOT-initialized classes must be moved to
267 // the initialized state.
268 //
269 // We can encounter a failure during the loading, linking, or initialization of
270 // classes in the AOTLinkedClassTable only if:
271 // - We ran out of memory,
307 MonitorLocker mu1(SystemDictionary_lock);
308
309 for (int i = 0; i < classes->length(); i++) {
310 InstanceKlass* ik = classes->at(i);
311 assert(ik->is_loaded(), "must have already been loaded by a parent loader");
312 assert(ik->class_loader() != initiating_loader(), "must be a parent loader");
313 assert(ik->class_loader() == nullptr ||
314 ik->class_loader() == SystemDictionary::java_platform_loader(), "must be");
315 if (ik->is_public() && !ik->is_hidden()) {
316 if (log_is_enabled(Info, aot, load)) {
317 ResourceMark rm(current);
318 const char* defining_loader = (ik->class_loader() == nullptr ? "boot" : "plat");
319 log_info(aot, load)("%-5s %s (initiated, defined by %s)", category_name, ik->external_name(),
320 defining_loader);
321 }
322 SystemDictionary::add_to_initiating_loader(current, ik, loader_data);
323 }
324 }
325 }
326
327 // Some AOT-linked classes for <class_loader> must be initialized early. This includes
328 // - classes that were AOT-initialized by AOTClassInitializer
329 // - the classes of all objects that are reachable from the archived mirrors of
330 // the AOT-linked classes for <class_loader>.
331 void AOTLinkedClassBulkLoader::init_classes_for_loader(Handle class_loader, Array<InstanceKlass*>* classes, TRAPS) {
332 if (classes != nullptr) {
333 for (int i = 0; i < classes->length(); i++) {
334 InstanceKlass* ik = classes->at(i);
335 assert(ik->class_loader_data() != nullptr, "must be");
336 if (ik->has_aot_initialized_mirror()) {
337 ik->initialize_with_aot_initialized_mirror(CHECK);
338 }
339 }
340 }
341
342 HeapShared::init_classes_for_special_subgraph(class_loader, CHECK);
343 }
344
345 void AOTLinkedClassBulkLoader::replay_training_at_init(Array<InstanceKlass*>* classes, TRAPS) {
346 if (classes != nullptr) {
347 for (int i = 0; i < classes->length(); i++) {
348 InstanceKlass* ik = classes->at(i);
349 if (ik->has_aot_initialized_mirror() && ik->is_initialized() && !ik->has_init_deps_processed()) {
350 CompilationPolicy::replay_training_at_init(ik, CHECK);
351 }
352 }
353 }
354 }
355
356 void AOTLinkedClassBulkLoader::replay_training_at_init_for_preloaded_classes(TRAPS) {
357 if (CDSConfig::is_using_aot_linked_classes() && TrainingData::have_data()) {
358 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
359 replay_training_at_init(table->boot1(), CHECK);
360 replay_training_at_init(table->boot2(), CHECK);
361 replay_training_at_init(table->platform(), CHECK);
362 replay_training_at_init(table->app(), CHECK);
363 }
364 }
|
1 /*
2 * Copyright (c) 2024, 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/aotCacheAccess.hpp"
26 #include "cds/aotClassInitializer.hpp"
27 #include "cds/aotClassLinker.hpp"
28 #include "cds/aotLinkedClassBulkLoader.hpp"
29 #include "cds/aotLinkedClassTable.hpp"
30 #include "cds/cdsConfig.hpp"
31 #include "cds/heapShared.hpp"
32 #include "classfile/classLoaderData.hpp"
33 #include "classfile/classLoaderDataShared.hpp"
34 #include "classfile/javaClasses.hpp"
35 #include "classfile/systemDictionary.hpp"
36 #include "classfile/systemDictionaryShared.hpp"
37 #include "classfile/vmClasses.hpp"
38 #include "compiler/compilationPolicy.hpp"
39 #include "gc/shared/gcVMOperations.hpp"
40 #include "memory/resourceArea.hpp"
41 #include "oops/instanceKlass.hpp"
42 #include "oops/klass.inline.hpp"
43 #include "oops/trainingData.hpp"
44 #include "runtime/handles.inline.hpp"
45 #include "runtime/java.hpp"
46 #include "runtime/perfData.inline.hpp"
47 #include "runtime/serviceThread.hpp"
48 #include "utilities/growableArray.hpp"
49
50 static PerfCounter* _perf_classes_preloaded = nullptr;
51 static PerfTickCounters* _perf_class_preload_counters = nullptr;
52
53 void AOTLinkedClassBulkLoader::serialize(SerializeClosure* soc) {
54 AOTLinkedClassTable::get()->serialize(soc);
55
56 if (soc->reading() && UsePerfData) {
57 JavaThread* THREAD = JavaThread::current();
58 NEWPERFEVENTCOUNTER(_perf_classes_preloaded, SUN_CLS, "preloadedClasses");
59 NEWPERFTICKCOUNTERS(_perf_class_preload_counters, SUN_CLS, "classPreload");
60 }
61 }
62
63 // This function is called before the VM executes any Java code (include AOT-compiled Java methods).
64 //
65 // We populate the boot/platform/app class loaders with classes from the AOT cache. This is a fundamental
66 // step in restoring the JVM's state from the snapshot recorded in the AOT cache: other AOT optimizations
67 // such as AOT compiled methods can make direct references to the preloaded classes, knowing that
68 // these classes are guaranteed to be in at least the "loaded" state.
69 //
70 // Note: we can't link the classes yet because SharedRuntime is not yet ready to generate adapters.
71 void AOTLinkedClassBulkLoader::preload_classes(JavaThread* current) {
72 preload_classes_impl(current);
73 if (current->has_pending_exception()) {
74 exit_on_exception(current);
75 }
76 }
77
78 void AOTLinkedClassBulkLoader::preload_classes_impl(TRAPS) {
79 precond(CDSConfig::is_using_aot_linked_classes());
80
87 preload_classes_in_table(table->boot1(), "boot1", Handle(), CHECK);
88 preload_classes_in_table(table->boot2(), "boot2", Handle(), CHECK);
89
90 initiate_loading(THREAD, "plat", h_platform_loader, table->boot1());
91 initiate_loading(THREAD, "plat", h_platform_loader, table->boot2());
92 preload_classes_in_table(table->platform(), "plat", h_platform_loader, CHECK);
93
94 initiate_loading(THREAD, "app", h_system_loader, table->boot1());
95 initiate_loading(THREAD, "app", h_system_loader, table->boot2());
96 initiate_loading(THREAD, "app", h_system_loader, table->platform());
97 preload_classes_in_table(table->app(), "app", h_system_loader, CHECK);
98 }
99
100 void AOTLinkedClassBulkLoader::preload_classes_in_table(Array<InstanceKlass*>* classes,
101 const char* category_name, Handle loader, TRAPS) {
102 if (classes == nullptr) {
103 return;
104 }
105
106 for (int i = 0; i < classes->length(); i++) {
107 if (UsePerfData) {
108 _perf_classes_preloaded->inc();
109 }
110
111 InstanceKlass* ik = classes->at(i);
112 if (log_is_enabled(Info, aot, load)) {
113 ResourceMark rm(THREAD);
114 log_info(aot, load)("%-5s %s%s", category_name, ik->external_name(),
115 ik->is_hidden() ? " (hidden)" : "");
116 }
117
118 SystemDictionary::preload_class(loader, ik, CHECK);
119
120 if (ik->is_hidden()) {
121 DEBUG_ONLY({
122 // Make sure we don't make this hidden class available by name, even if we don't
123 // use any special ClassLoaderData.
124 ResourceMark rm(THREAD);
125 assert(SystemDictionary::find_instance_klass(THREAD, ik->name(), loader) == nullptr,
126 "hidden classes cannot be accessible by name: %s", ik->external_name());
127 });
128 } else {
129 precond(SystemDictionary::find_instance_klass(THREAD, ik->name(), loader) == ik);
130 }
131 }
132 }
133
134 static bool _is_initializing_classes_early = false;
135 bool AOTLinkedClassBulkLoader::is_initializing_classes_early() {
136 return _is_initializing_classes_early;
137 }
138
139 // Some cached heap objects may hold references to methods in aot-linked
140 // classes (via MemberName). We need to make sure all classes are
141 // linked before executing any bytecode.
142 void AOTLinkedClassBulkLoader::link_classes(JavaThread* current) {
143 _is_initializing_classes_early = true;
144 link_classes_impl(current);
145 _is_initializing_classes_early = false;
146
147 if (current->has_pending_exception()) {
148 exit_on_exception(current);
149 }
150 }
151
152 void AOTLinkedClassBulkLoader::link_classes_impl(TRAPS) {
153 precond(CDSConfig::is_using_aot_linked_classes());
154
155 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
156
157 link_classes_in_table(table->boot1(), CHECK);
158 link_classes_in_table(table->boot2(), CHECK);
159 link_classes_in_table(table->platform(), CHECK);
160 link_classes_in_table(table->app(), CHECK);
161
162 init_classes_for_loader(Handle(), AOTLinkedClassTable::get()->boot1(), true, CHECK);
163 init_classes_for_loader(Handle(), AOTLinkedClassTable::get()->boot2(), true, CHECK);
164 init_classes_for_loader(Handle(), AOTLinkedClassTable::get()->platform(), true, CHECK);
165 init_classes_for_loader(Handle(), AOTLinkedClassTable::get()->app(), true, CHECK);
166
167 log_info(aot, init)("------ finished early class init");
168 }
169
170 void AOTLinkedClassBulkLoader::link_classes_in_table(Array<InstanceKlass*>* classes, TRAPS) {
171 if (classes != nullptr) {
172 for (int i = 0; i < classes->length(); i++) {
173 // NOTE: CDSConfig::is_preserving_verification_constraints() is required
174 // when storing ik in the AOT cache. This means we don't have to verify
175 // ik at all.
176 //
177 // Without is_preserving_verification_constraints(), ik->link_class() may cause
178 // class loading, which may result in invocation of ClassLoader::loadClass() calls,
179 // which CANNOT happen because we are not ready to execute any Java byecodes yet
180 // at this point.
181 InstanceKlass* ik = classes->at(i);
182 ik->link_class(CHECK);
183 }
184 }
185 }
186
187 #ifdef ASSERT
229
230 if (log_is_enabled(Debug, aot, module)) {
231 ResourceMark rm;
232 log_debug(aot, module)("Validate module of %-5s %s", category_name, k->external_name());
233 }
234 precond(java_lang_Class::module(k->java_mirror()) == module_oop);
235
236 ArrayKlass* ak = k->array_klass_or_null();
237 while (ak != nullptr) {
238 if (log_is_enabled(Debug, aot, module)) {
239 ResourceMark rm;
240 log_debug(aot, module)("Validate module of %-5s %s", category_name, ak->external_name());
241 }
242 precond(java_lang_Class::module(ak->java_mirror()) == module_oop);
243 ak = ak->array_klass_or_null();
244 }
245 }
246 #endif
247
248 void AOTLinkedClassBulkLoader::init_javabase_classes(JavaThread* current) {
249 init_classes_for_loader(Handle(), AOTLinkedClassTable::get()->boot1(), false, current);
250 if (current->has_pending_exception()) {
251 exit_on_exception(current);
252 }
253 }
254
255 void AOTLinkedClassBulkLoader::init_non_javabase_classes(JavaThread* current) {
256 init_non_javabase_classes_impl(current);
257 if (current->has_pending_exception()) {
258 exit_on_exception(current);
259 }
260 }
261
262 void AOTLinkedClassBulkLoader::init_non_javabase_classes_impl(TRAPS) {
263 assert(CDSConfig::is_using_aot_linked_classes(), "sanity");
264
265 DEBUG_ONLY(validate_module_of_preloaded_classes());
266
267 // is_using_aot_linked_classes() requires is_using_full_module_graph(). As a result,
268 // the platform/system class loader should already have been initialized as part
269 // of the FMG support.
270 assert(CDSConfig::is_using_full_module_graph(), "must be");
271
272 Handle h_platform_loader(THREAD, SystemDictionary::java_platform_loader());
273 Handle h_system_loader(THREAD, SystemDictionary::java_system_loader());
274
275 assert(h_platform_loader() != nullptr, "must be");
276 assert(h_system_loader() != nullptr, "must be");
277
278 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
279 init_classes_for_loader(Handle(), table->boot2(), false, CHECK);
280 init_classes_for_loader(h_platform_loader, table->platform(), false, CHECK);
281 init_classes_for_loader(h_system_loader, table->app(), false, CHECK);
282
283 if (Universe::is_fully_initialized() && VerifyDuringStartup) {
284 // Make sure we're still in a clean state.
285 VM_Verify verify_op;
286 VMThread::execute(&verify_op);
287 }
288
289 if (AOTPrintTrainingInfo) {
290 tty->print_cr("==================== archived_training_data ** after all classes preloaded ====================");
291 TrainingData::print_archived_training_data_on(tty);
292 }
293 }
294
295 // For the AOT cache to function properly, all classes in the AOTLinkedClassTable
296 // must be loaded and linked. In addition, AOT-initialized classes must be moved to
297 // the initialized state.
298 //
299 // We can encounter a failure during the loading, linking, or initialization of
300 // classes in the AOTLinkedClassTable only if:
301 // - We ran out of memory,
337 MonitorLocker mu1(SystemDictionary_lock);
338
339 for (int i = 0; i < classes->length(); i++) {
340 InstanceKlass* ik = classes->at(i);
341 assert(ik->is_loaded(), "must have already been loaded by a parent loader");
342 assert(ik->class_loader() != initiating_loader(), "must be a parent loader");
343 assert(ik->class_loader() == nullptr ||
344 ik->class_loader() == SystemDictionary::java_platform_loader(), "must be");
345 if (ik->is_public() && !ik->is_hidden()) {
346 if (log_is_enabled(Info, aot, load)) {
347 ResourceMark rm(current);
348 const char* defining_loader = (ik->class_loader() == nullptr ? "boot" : "plat");
349 log_info(aot, load)("%-5s %s (initiated, defined by %s)", category_name, ik->external_name(),
350 defining_loader);
351 }
352 SystemDictionary::add_to_initiating_loader(current, ik, loader_data);
353 }
354 }
355 }
356
357 // Can we move ik into fully_initialized state before the JVM is able to execute
358 // bytecodes?
359 static bool is_early_init_possible(InstanceKlass* ik) {
360 if (ik->is_runtime_setup_required()) {
361 // Bytecodes need to be executed in order to initialize this class.
362 if (log_is_enabled(Debug, aot, init)) {
363 ResourceMark rm;
364 log_debug(aot, init)("No early init %s: needs runtimeSetup()",
365 ik->external_name());
366 }
367 return false;
368 }
369
370 if (ik->super() != nullptr && !ik->super()->is_initialized()) {
371 // is_runtime_setup_required() == true for a super type
372 if (log_is_enabled(Debug, aot, init)) {
373 ResourceMark rm;
374 log_debug(aot, init)("No early init %s: super type %s not initialized",
375 ik->external_name(), ik->super()->external_name());
376 }
377 return false;
378 }
379
380 Array<InstanceKlass*>* interfaces = ik->local_interfaces();
381 int num_interfaces = interfaces->length();
382 for (int i = 0; i < num_interfaces; i++) {
383 InstanceKlass* intf = interfaces->at(i);
384 if (!intf->is_initialized() && intf->interface_needs_clinit_execution_as_super(/*also_check_supers*/false)) {
385 // is_runtime_setup_required() == true for a super interface
386 if (log_is_enabled(Debug, aot, init)) {
387 ResourceMark rm;
388 log_debug(aot, init)("No early init %s: super type %s not initialized",
389 ik->external_name(), intf->external_name());
390 }
391 return false;
392 }
393 }
394
395 return true;
396 }
397
398 // Some AOT-linked classes for <class_loader> must be initialized early. This includes
399 // - classes that were AOT-initialized by AOTClassInitializer
400 // - the classes of all objects that are reachable from the archived mirrors of
401 // the AOT-linked classes for <class_loader>.
402 void AOTLinkedClassBulkLoader::init_classes_for_loader(Handle class_loader, Array<InstanceKlass*>* classes, bool early_only, TRAPS) {
403 if (classes != nullptr) {
404 for (int i = 0; i < classes->length(); i++) {
405 InstanceKlass* ik = classes->at(i);
406 assert(ik->class_loader_data() != nullptr, "must be");
407
408 bool do_init = ik->has_aot_initialized_mirror();
409 if (do_init && early_only) {
410 if (is_early_init_possible(ik)) {
411 precond(AOTCacheAccess::is_early_aot_inited_class(ik));
412 } else {
413 do_init = false;
414 }
415 }
416
417 if (do_init) {
418 ik->initialize_with_aot_initialized_mirror(early_only, CHECK);
419 }
420 }
421 }
422
423 if (!early_only) {
424 HeapShared::init_classes_for_special_subgraph(class_loader, CHECK);
425 }
426 }
427
428 void AOTLinkedClassBulkLoader::replay_training_at_init(Array<InstanceKlass*>* classes, TRAPS) {
429 if (classes != nullptr) {
430 for (int i = 0; i < classes->length(); i++) {
431 InstanceKlass* ik = classes->at(i);
432 if (ik->has_aot_initialized_mirror() && ik->is_initialized() && !ik->has_init_deps_processed()) {
433 CompilationPolicy::replay_training_at_init(ik, CHECK);
434 }
435 }
436 }
437 }
438
439 void AOTLinkedClassBulkLoader::replay_training_at_init_for_preloaded_classes(TRAPS) {
440 if (CDSConfig::is_using_aot_linked_classes() && TrainingData::have_data()) {
441 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
442 replay_training_at_init(table->boot1(), CHECK);
443 replay_training_at_init(table->boot2(), CHECK);
444 replay_training_at_init(table->platform(), CHECK);
445 replay_training_at_init(table->app(), CHECK);
446 }
447 }
448
449 void AOTLinkedClassBulkLoader::print_counters_on(outputStream* st) {
450 if (UsePerfData && _perf_class_preload_counters != nullptr) {
451 st->print_cr("AOTLinkedClassBulkLoader:");
452 st->print_cr(" preload: " JLONG_FORMAT_W(6) "us (elapsed) " JLONG_FORMAT_W(6) " (thread) / " JLONG_FORMAT_W(5) " events",
453 _perf_class_preload_counters->elapsed_counter_value_us(),
454 _perf_class_preload_counters->thread_counter_value_us(),
455 _perf_classes_preloaded->get_value());
456 }
457 }
|