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/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()); 88 Handle h_system_loader(THREAD, SystemDictionary::java_system_loader()); 89 90 AOTLinkedClassTable* table = AOTLinkedClassTable::get(); 91 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 } 136 } 137 } 138 139 #ifdef ASSERT 140 void AOTLinkedClassBulkLoader::validate_module_of_preloaded_classes() { 141 oop javabase_module_oop = ModuleEntryTable::javabase_moduleEntry()->module_oop(); 142 for (int i = T_BOOLEAN; i < T_LONG+1; i++) { 143 TypeArrayKlass* tak = Universe::typeArrayKlass((BasicType)i); 144 validate_module(tak, "boot1", javabase_module_oop); 145 } 146 147 JavaThread* current = JavaThread::current(); 148 Handle h_platform_loader(current, SystemDictionary::java_platform_loader()); 149 Handle h_system_loader(current, SystemDictionary::java_system_loader()); 150 AOTLinkedClassTable* table = AOTLinkedClassTable::get(); 151 152 validate_module_of_preloaded_classes_in_table(table->boot1(), "boot1", Handle()); 153 validate_module_of_preloaded_classes_in_table(table->boot2(), "boot2", Handle()); 154 validate_module_of_preloaded_classes_in_table(table->platform(), "plat", h_platform_loader); 155 validate_module_of_preloaded_classes_in_table(table->app(), "app", h_system_loader); 156 } 157 158 void AOTLinkedClassBulkLoader::validate_module_of_preloaded_classes_in_table(Array<InstanceKlass*>* classes, 159 const char* category_name, Handle loader) { 160 if (classes == nullptr) { 161 return; 162 } 163 164 ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader()); 165 for (int i = 0; i < classes->length(); i++) { 166 InstanceKlass* ik = classes->at(i); 167 PackageEntry* pkg_entry = ik->package(); 168 oop module_oop; 169 if (pkg_entry == nullptr) { 170 module_oop = loader_data->unnamed_module()->module_oop(); 171 } else { 172 module_oop = pkg_entry->module()->module_oop(); 173 } 174 175 validate_module(ik, category_name, module_oop); 176 } 177 } 178 179 void AOTLinkedClassBulkLoader::validate_module(Klass* k, const char* category_name, oop module_oop) { 180 assert(module_oop != nullptr, "module system must have been initialized"); 181 182 if (log_is_enabled(Debug, aot, module)) { 183 ResourceMark rm; 184 log_debug(aot, module)("Validate module of %-5s %s", category_name, k->external_name()); 185 } 186 precond(java_lang_Class::module(k->java_mirror()) == module_oop); 187 188 ArrayKlass* ak = k->array_klass_or_null(); 189 while (ak != nullptr) { 190 if (log_is_enabled(Debug, aot, module)) { 191 ResourceMark rm; 192 log_debug(aot, module)("Validate module of %-5s %s", category_name, ak->external_name()); 193 } 194 precond(java_lang_Class::module(ak->java_mirror()) == module_oop); 195 ak = ak->array_klass_or_null(); 196 } 197 } 198 #endif 199 200 // Link all java.base classes in the AOTLinkedClassTable. Of those classes, 201 // move the ones that have been AOT-initialized to the "initialized" state. 202 void AOTLinkedClassBulkLoader::link_or_init_javabase_classes(JavaThread* current) { 203 link_or_init_classes_for_loader(Handle(), AOTLinkedClassTable::get()->boot1(), current); 204 if (current->has_pending_exception()) { 205 exit_on_exception(current); 206 } 207 } 208 209 // Do the same thing as link_or_init_javabase_classes(), but for the classes that are not 210 // in the java.base module. 211 void AOTLinkedClassBulkLoader::link_or_init_non_javabase_classes(JavaThread* current) { 212 link_or_init_non_javabase_classes_impl(current); 213 if (current->has_pending_exception()) { 214 exit_on_exception(current); 215 } 216 } 217 218 void AOTLinkedClassBulkLoader::link_or_init_non_javabase_classes_impl(TRAPS) { 219 assert(CDSConfig::is_using_aot_linked_classes(), "sanity"); 220 221 DEBUG_ONLY(validate_module_of_preloaded_classes()); 222 223 // is_using_aot_linked_classes() requires is_using_full_module_graph(). As a result, 224 // the platform/system class loader should already have been initialized as part 225 // of the FMG support. 226 assert(CDSConfig::is_using_full_module_graph(), "must be"); 227 228 Handle h_platform_loader(THREAD, SystemDictionary::java_platform_loader()); 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 { 273 log_error(aot)("%s: %s", current->pending_exception()->klass()->external_name(), 274 java_lang_String::as_utf8_string(java_lang_Throwable::message(current->pending_exception()))); 275 } 276 vm_exit_during_initialization("Unexpected exception when loading aot-linked classes."); 277 } 278 279 // Initiate loading of the <classes> in the <initiating_loader>. The <classes> should have already been loaded 280 // by a parent loader of the <initiating_loader>. This is necessary for handling pre-resolved CP entries. 281 // 282 // For example, we initiate the loading of java/lang/String in the AppClassLoader. This will allow 283 // any App classes to have a pre-resolved ConstantPool entry that references java/lang/String. 284 // 285 // TODO: we can limit the number of initiated classes to only those that are actually referenced by 286 // AOT-linked classes loaded by <initiating_loader>. 287 void AOTLinkedClassBulkLoader::initiate_loading(JavaThread* current, const char* category_name, 288 Handle initiating_loader, Array<InstanceKlass*>* classes) { 289 if (classes == nullptr) { 290 return; 291 } 292 293 assert(initiating_loader() == SystemDictionary::java_platform_loader() || 294 initiating_loader() == SystemDictionary::java_system_loader(), "must be"); 295 ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(initiating_loader()); 296 MonitorLocker mu1(SystemDictionary_lock); 297 298 for (int i = 0; i < classes->length(); i++) { 299 InstanceKlass* ik = classes->at(i); 300 assert(ik->is_loaded(), "must have already been loaded by a parent loader"); 301 assert(ik->class_loader() != initiating_loader(), "must be a parent loader"); 302 assert(ik->class_loader() == nullptr || 303 ik->class_loader() == SystemDictionary::java_platform_loader(), "must be"); 304 if (ik->is_public() && !ik->is_hidden()) { 305 if (log_is_enabled(Info, aot, load)) { 306 ResourceMark rm(current); 307 const char* defining_loader = (ik->class_loader() == nullptr ? "boot" : "plat"); 308 log_info(aot, load)("%-5s %s (initiated, defined by %s)", category_name, ik->external_name(), 309 defining_loader); 310 } 311 SystemDictionary::add_to_initiating_loader(current, ik, loader_data); 312 } 313 } 314 } 315 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 }