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
46 void AOTLinkedClassBulkLoader::serialize(SerializeClosure* soc) {
47 AOTLinkedClassTable::get()->serialize(soc);
48 }
49
50 // This function is called before the VM executes any Java code (include AOT-compiled Java methods).
51 //
52 // We populate the boot/platform/app class loaders with classes from the AOT cache. This is a fundamental
53 // step in restoring the JVM's state from the snapshot recorded in the AOT cache: other AOT optimizations
54 // such as AOT compiled methods can make direct references to the preloaded classes, knowing that
55 // these classes are guaranteed to be in at least the "loaded" state.
56 void AOTLinkedClassBulkLoader::preload_classes(JavaThread* current) {
57 preload_classes_impl(current);
58 if (current->has_pending_exception()) {
59 exit_on_exception(current);
60 }
61 }
62
63 void AOTLinkedClassBulkLoader::preload_classes_impl(TRAPS) {
64 precond(CDSConfig::is_using_aot_linked_classes());
65
66 ClassLoaderDataShared::restore_archived_modules_for_preloading_classes(THREAD);
67 Handle h_platform_loader(THREAD, SystemDictionary::java_platform_loader());
72 preload_classes_in_table(table->boot1(), "boot1", Handle(), CHECK);
73 preload_classes_in_table(table->boot2(), "boot2", Handle(), CHECK);
74
75 initiate_loading(THREAD, "plat", h_platform_loader, table->boot1());
76 initiate_loading(THREAD, "plat", h_platform_loader, table->boot2());
77 preload_classes_in_table(table->platform(), "plat", h_platform_loader, CHECK);
78
79 initiate_loading(THREAD, "app", h_system_loader, table->boot1());
80 initiate_loading(THREAD, "app", h_system_loader, table->boot2());
81 initiate_loading(THREAD, "app", h_system_loader, table->platform());
82 preload_classes_in_table(table->app(), "app", h_system_loader, CHECK);
83 }
84
85 void AOTLinkedClassBulkLoader::preload_classes_in_table(Array<InstanceKlass*>* classes,
86 const char* category_name, Handle loader, TRAPS) {
87 if (classes == nullptr) {
88 return;
89 }
90
91 for (int i = 0; i < classes->length(); i++) {
92 InstanceKlass* ik = classes->at(i);
93 if (log_is_enabled(Info, aot, load)) {
94 ResourceMark rm(THREAD);
95 log_info(aot, load)("%-5s %s%s", category_name, ik->external_name(),
96 ik->is_hidden() ? " (hidden)" : "");
97 }
98
99 SystemDictionary::preload_class(loader, ik, CHECK);
100
101 if (ik->is_hidden()) {
102 DEBUG_ONLY({
103 // Make sure we don't make this hidden class available by name, even if we don't
104 // use any special ClassLoaderData.
105 ResourceMark rm(THREAD);
106 assert(SystemDictionary::find_instance_klass(THREAD, ik->name(), loader) == nullptr,
107 "hidden classes cannot be accessible by name: %s", ik->external_name());
108 });
109 } else {
110 precond(SystemDictionary::find_instance_klass(THREAD, ik->name(), loader) == ik);
111 }
205 Handle h_system_loader(THREAD, SystemDictionary::java_system_loader());
206
207 assert(h_platform_loader() != nullptr, "must be");
208 assert(h_system_loader() != nullptr, "must be");
209
210 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
211 link_or_init_classes_for_loader(Handle(), table->boot2(), CHECK);
212 link_or_init_classes_for_loader(h_platform_loader, table->platform(), CHECK);
213 link_or_init_classes_for_loader(h_system_loader, table->app(), CHECK);
214
215 if (Universe::is_fully_initialized() && VerifyDuringStartup) {
216 // Make sure we're still in a clean state.
217 VM_Verify verify_op;
218 VMThread::execute(&verify_op);
219 }
220
221 if (AOTPrintTrainingInfo) {
222 tty->print_cr("==================== archived_training_data ** after all classes preloaded ====================");
223 TrainingData::print_archived_training_data_on(tty);
224 }
225 }
226
227 // For the AOT cache to function properly, all classes in the AOTLinkedClassTable
228 // must be loaded and linked. In addition, AOT-initialized classes must be moved to
229 // the initialized state.
230 //
231 // We can encounter a failure during the loading, linking, or initialization of
232 // classes in the AOTLinkedClassTable only if:
233 // - We ran out of memory,
234 // - There is a serious error in the VM implemenation
235 // When this happens, the VM may be in an inconsistent state (e.g., we have a cached
236 // heap object of class X, but X is not linked). We must exit the JVM now.
237
238 void AOTLinkedClassBulkLoader::exit_on_exception(JavaThread* current) {
239 assert(current->has_pending_exception(), "precondition");
240 ResourceMark rm(current);
241 if (current->pending_exception()->is_a(vmClasses::OutOfMemoryError_klass())) {
242 log_error(aot)("Out of memory. Please run with a larger Java heap, current MaxHeapSize = "
243 "%zuM", MaxHeapSize/M);
244 } else {
288 // Some AOT-linked classes for <class_loader> must be initialized early. This includes
289 // - classes that were AOT-initialized by AOTClassInitializer
290 // - the classes of all objects that are reachable from the archived mirrors of
291 // the AOT-linked classes for <class_loader>.
292 void AOTLinkedClassBulkLoader::link_or_init_classes_for_loader(Handle class_loader, Array<InstanceKlass*>* classes, TRAPS) {
293 if (classes != nullptr) {
294 for (int i = 0; i < classes->length(); i++) {
295 InstanceKlass* ik = classes->at(i);
296 if (ik->class_loader_data() == nullptr) {
297 // This class is not yet loaded. We will initialize it in a later phase.
298 // For example, we have loaded only AOTLinkedClassCategory::BOOT1 classes
299 // but k is part of AOTLinkedClassCategory::BOOT2.
300 continue;
301 }
302 if (ik->has_aot_initialized_mirror()) {
303 ik->initialize_with_aot_initialized_mirror(CHECK);
304 } else {
305 // Some cached heap objects may hold references to methods in aot-linked
306 // classes (via MemberName). We need to make sure all classes are
307 // linked to allow such MemberNames to be invoked.
308 ik->link_class(CHECK);
309 }
310 }
311 }
312
313 HeapShared::init_classes_for_special_subgraph(class_loader, CHECK);
314 }
315
316 void AOTLinkedClassBulkLoader::replay_training_at_init(Array<InstanceKlass*>* classes, TRAPS) {
317 if (classes != nullptr) {
318 for (int i = 0; i < classes->length(); i++) {
319 InstanceKlass* ik = classes->at(i);
320 if (ik->has_aot_initialized_mirror() && ik->is_initialized() && !ik->has_init_deps_processed()) {
321 CompilationPolicy::replay_training_at_init(ik, CHECK);
322 }
323 }
324 }
325 }
326
327 void AOTLinkedClassBulkLoader::replay_training_at_init_for_preloaded_classes(TRAPS) {
328 if (CDSConfig::is_using_aot_linked_classes() && TrainingData::have_data()) {
329 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
330 replay_training_at_init(table->boot1(), CHECK);
331 replay_training_at_init(table->boot2(), CHECK);
332 replay_training_at_init(table->platform(), CHECK);
333 replay_training_at_init(table->app(), CHECK);
334 }
335 }
|
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/archiveBuilder.hpp"
31 #include "cds/archiveUtils.inline.hpp"
32 #include "cds/cdsConfig.hpp"
33 #include "cds/cdsProtectionDomain.hpp"
34 #include "cds/heapShared.hpp"
35 #include "cds/lambdaFormInvokers.inline.hpp"
36 #include "classfile/classLoader.hpp"
37 #include "classfile/classLoaderData.hpp"
38 #include "classfile/classLoaderDataShared.hpp"
39 #include "classfile/javaClasses.hpp"
40 #include "classfile/systemDictionary.hpp"
41 #include "classfile/systemDictionaryShared.hpp"
42 #include "classfile/vmClasses.hpp"
43 #include "compiler/compilationPolicy.hpp"
44 #include "gc/shared/gcVMOperations.hpp"
45 #include "memory/resourceArea.hpp"
46 #include "oops/constantPool.inline.hpp"
47 #include "oops/instanceKlass.hpp"
48 #include "oops/klass.inline.hpp"
49 #include "oops/trainingData.hpp"
50 #include "runtime/handles.inline.hpp"
51 #include "runtime/java.hpp"
52 #include "runtime/javaCalls.hpp"
53 #include "runtime/perfData.inline.hpp"
54 #include "runtime/timer.hpp"
55 #include "services/management.hpp"
56
57 static PerfCounter* _perf_classes_preloaded = nullptr;
58 static PerfTickCounters* _perf_class_preload_counters = nullptr;
59
60 void AOTLinkedClassBulkLoader::serialize(SerializeClosure* soc) {
61 AOTLinkedClassTable::get()->serialize(soc);
62
63 if (soc->reading() && UsePerfData) {
64 JavaThread* THREAD = JavaThread::current();
65 NEWPERFEVENTCOUNTER(_perf_classes_preloaded, SUN_CLS, "preloadedClasses");
66 NEWPERFTICKCOUNTERS(_perf_class_preload_counters, SUN_CLS, "classPreload");
67 }
68 }
69
70 // This function is called before the VM executes any Java code (include AOT-compiled Java methods).
71 //
72 // We populate the boot/platform/app class loaders with classes from the AOT cache. This is a fundamental
73 // step in restoring the JVM's state from the snapshot recorded in the AOT cache: other AOT optimizations
74 // such as AOT compiled methods can make direct references to the preloaded classes, knowing that
75 // these classes are guaranteed to be in at least the "loaded" state.
76 void AOTLinkedClassBulkLoader::preload_classes(JavaThread* current) {
77 preload_classes_impl(current);
78 if (current->has_pending_exception()) {
79 exit_on_exception(current);
80 }
81 }
82
83 void AOTLinkedClassBulkLoader::preload_classes_impl(TRAPS) {
84 precond(CDSConfig::is_using_aot_linked_classes());
85
86 ClassLoaderDataShared::restore_archived_modules_for_preloading_classes(THREAD);
87 Handle h_platform_loader(THREAD, SystemDictionary::java_platform_loader());
92 preload_classes_in_table(table->boot1(), "boot1", Handle(), CHECK);
93 preload_classes_in_table(table->boot2(), "boot2", Handle(), CHECK);
94
95 initiate_loading(THREAD, "plat", h_platform_loader, table->boot1());
96 initiate_loading(THREAD, "plat", h_platform_loader, table->boot2());
97 preload_classes_in_table(table->platform(), "plat", h_platform_loader, CHECK);
98
99 initiate_loading(THREAD, "app", h_system_loader, table->boot1());
100 initiate_loading(THREAD, "app", h_system_loader, table->boot2());
101 initiate_loading(THREAD, "app", h_system_loader, table->platform());
102 preload_classes_in_table(table->app(), "app", h_system_loader, CHECK);
103 }
104
105 void AOTLinkedClassBulkLoader::preload_classes_in_table(Array<InstanceKlass*>* classes,
106 const char* category_name, Handle loader, TRAPS) {
107 if (classes == nullptr) {
108 return;
109 }
110
111 for (int i = 0; i < classes->length(); i++) {
112 if (UsePerfData) {
113 _perf_classes_preloaded->inc();
114 }
115
116 InstanceKlass* ik = classes->at(i);
117 if (log_is_enabled(Info, aot, load)) {
118 ResourceMark rm(THREAD);
119 log_info(aot, load)("%-5s %s%s", category_name, ik->external_name(),
120 ik->is_hidden() ? " (hidden)" : "");
121 }
122
123 SystemDictionary::preload_class(loader, ik, CHECK);
124
125 if (ik->is_hidden()) {
126 DEBUG_ONLY({
127 // Make sure we don't make this hidden class available by name, even if we don't
128 // use any special ClassLoaderData.
129 ResourceMark rm(THREAD);
130 assert(SystemDictionary::find_instance_klass(THREAD, ik->name(), loader) == nullptr,
131 "hidden classes cannot be accessible by name: %s", ik->external_name());
132 });
133 } else {
134 precond(SystemDictionary::find_instance_klass(THREAD, ik->name(), loader) == ik);
135 }
229 Handle h_system_loader(THREAD, SystemDictionary::java_system_loader());
230
231 assert(h_platform_loader() != nullptr, "must be");
232 assert(h_system_loader() != nullptr, "must be");
233
234 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
235 link_or_init_classes_for_loader(Handle(), table->boot2(), CHECK);
236 link_or_init_classes_for_loader(h_platform_loader, table->platform(), CHECK);
237 link_or_init_classes_for_loader(h_system_loader, table->app(), CHECK);
238
239 if (Universe::is_fully_initialized() && VerifyDuringStartup) {
240 // Make sure we're still in a clean state.
241 VM_Verify verify_op;
242 VMThread::execute(&verify_op);
243 }
244
245 if (AOTPrintTrainingInfo) {
246 tty->print_cr("==================== archived_training_data ** after all classes preloaded ====================");
247 TrainingData::print_archived_training_data_on(tty);
248 }
249
250 if (log_is_enabled(Info, cds, jit)) {
251 AOTCacheAccess::test_heap_access_api();
252 }
253 }
254
255 // For the AOT cache to function properly, all classes in the AOTLinkedClassTable
256 // must be loaded and linked. In addition, AOT-initialized classes must be moved to
257 // the initialized state.
258 //
259 // We can encounter a failure during the loading, linking, or initialization of
260 // classes in the AOTLinkedClassTable only if:
261 // - We ran out of memory,
262 // - There is a serious error in the VM implemenation
263 // When this happens, the VM may be in an inconsistent state (e.g., we have a cached
264 // heap object of class X, but X is not linked). We must exit the JVM now.
265
266 void AOTLinkedClassBulkLoader::exit_on_exception(JavaThread* current) {
267 assert(current->has_pending_exception(), "precondition");
268 ResourceMark rm(current);
269 if (current->pending_exception()->is_a(vmClasses::OutOfMemoryError_klass())) {
270 log_error(aot)("Out of memory. Please run with a larger Java heap, current MaxHeapSize = "
271 "%zuM", MaxHeapSize/M);
272 } else {
316 // Some AOT-linked classes for <class_loader> must be initialized early. This includes
317 // - classes that were AOT-initialized by AOTClassInitializer
318 // - the classes of all objects that are reachable from the archived mirrors of
319 // the AOT-linked classes for <class_loader>.
320 void AOTLinkedClassBulkLoader::link_or_init_classes_for_loader(Handle class_loader, Array<InstanceKlass*>* classes, TRAPS) {
321 if (classes != nullptr) {
322 for (int i = 0; i < classes->length(); i++) {
323 InstanceKlass* ik = classes->at(i);
324 if (ik->class_loader_data() == nullptr) {
325 // This class is not yet loaded. We will initialize it in a later phase.
326 // For example, we have loaded only AOTLinkedClassCategory::BOOT1 classes
327 // but k is part of AOTLinkedClassCategory::BOOT2.
328 continue;
329 }
330 if (ik->has_aot_initialized_mirror()) {
331 ik->initialize_with_aot_initialized_mirror(CHECK);
332 } else {
333 // Some cached heap objects may hold references to methods in aot-linked
334 // classes (via MemberName). We need to make sure all classes are
335 // linked to allow such MemberNames to be invoked.
336 if (ik->is_rewritten()) {
337 // (ik->is_rewritten() == false) means the class failed verification
338 // during the assembly phase, so there's no need to link it here.
339 ik->link_class(CHECK);
340 }
341 }
342 }
343 }
344
345 HeapShared::init_classes_for_special_subgraph(class_loader, CHECK);
346 }
347
348 void AOTLinkedClassBulkLoader::replay_training_at_init(Array<InstanceKlass*>* classes, TRAPS) {
349 if (classes != nullptr) {
350 for (int i = 0; i < classes->length(); i++) {
351 InstanceKlass* ik = classes->at(i);
352 if (ik->has_aot_initialized_mirror() && ik->is_initialized() && !ik->has_init_deps_processed()) {
353 CompilationPolicy::replay_training_at_init(ik, CHECK);
354 }
355 }
356 }
357 }
358
359 void AOTLinkedClassBulkLoader::replay_training_at_init_for_preloaded_classes(TRAPS) {
360 if (CDSConfig::is_using_aot_linked_classes() && TrainingData::have_data()) {
361 AOTLinkedClassTable* table = AOTLinkedClassTable::get();
362 replay_training_at_init(table->boot1(), CHECK);
363 replay_training_at_init(table->boot2(), CHECK);
364 replay_training_at_init(table->platform(), CHECK);
365 replay_training_at_init(table->app(), CHECK);
366 }
367 }
368
369 void AOTLinkedClassBulkLoader::print_counters_on(outputStream* st) {
370 if (UsePerfData && _perf_class_preload_counters != nullptr) {
371 st->print_cr("AOTLinkedClassBulkLoader:");
372 st->print_cr(" preload: " JLONG_FORMAT_W(6) "us (elapsed) " JLONG_FORMAT_W(6) " (thread) / " JLONG_FORMAT_W(5) " events",
373 _perf_class_preload_counters->elapsed_counter_value_us(),
374 _perf_class_preload_counters->thread_counter_value_us(),
375 _perf_classes_preloaded->get_value());
376 }
377 }
|