1 /*
  2  * Copyright (c) 2024, 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 "precompiled.hpp"
 26 #include "cds/aotLinkedClassBulkLoader.hpp"
 27 #include "cds/aotLinkedClassTable.hpp"
 28 #include "cds/archiveBuilder.hpp"
 29 #include "cds/archiveUtils.inline.hpp"
 30 #include "cds/cdsAccess.hpp"
 31 #include "cds/cdsConfig.hpp"
 32 #include "cds/cdsProtectionDomain.hpp"
 33 #include "cds/heapShared.hpp"
 34 #include "cds/lambdaFormInvokers.inline.hpp"
 35 #include "classfile/classLoader.hpp"
 36 #include "classfile/classLoaderDataGraph.hpp"
 37 #include "classfile/classLoaderExt.hpp"
 38 #include "classfile/dictionary.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/javaCalls.hpp"
 52 #include "runtime/perfData.inline.hpp"
 53 #include "runtime/timer.hpp"
 54 #include "services/management.hpp"
 55 
 56 Array<InstanceKlass*>* AOTLinkedClassBulkLoader::_unregistered_classes_from_preimage = nullptr;
 57 volatile bool _class_preloading_finished = false;
 58 
 59 static PerfCounter* _perf_classes_preloaded = nullptr;
 60 static PerfTickCounters* _perf_class_preload_counters = nullptr;
 61 
 62 void AOTLinkedClassBulkLoader::record_unregistered_classes() {
 63   if (CDSConfig::is_dumping_preimage_static_archive()) {
 64     GrowableArray<InstanceKlass*> unreg_classes;
 65     GrowableArray<Klass*>* klasses = ArchiveBuilder::current()->klasses();
 66     for (int i = 0; i < klasses->length(); i++) {
 67       Klass* k = klasses->at(i);
 68       if (k->is_instance_klass()) {
 69         InstanceKlass* ik = InstanceKlass::cast(k);
 70         if (ik->is_shared_unregistered_class()) {
 71           unreg_classes.append((InstanceKlass*)ArchiveBuilder::get_buffered_klass(ik));
 72         }
 73       }
 74     }
 75     _unregistered_classes_from_preimage = ArchiveUtils::archive_array(&unreg_classes);
 76   } else {
 77     _unregistered_classes_from_preimage = nullptr;
 78   }
 79 }
 80 
 81 void AOTLinkedClassBulkLoader::serialize(SerializeClosure* soc, bool is_static_archive) {
 82   AOTLinkedClassTable::get(is_static_archive)->serialize(soc);
 83 
 84   if (is_static_archive) {
 85     soc->do_ptr((void**)&_unregistered_classes_from_preimage);
 86 
 87     if (soc->reading() && UsePerfData) {
 88       JavaThread* THREAD = JavaThread::current();
 89       NEWPERFEVENTCOUNTER(_perf_classes_preloaded, SUN_CLS, "preloadedClasses");
 90       NEWPERFTICKCOUNTERS(_perf_class_preload_counters, SUN_CLS, "classPreload");
 91     }
 92   }
 93 }
 94 
 95 bool AOTLinkedClassBulkLoader::class_preloading_finished() {
 96   if (!CDSConfig::is_using_aot_linked_classes()) {
 97     return true;
 98   } else {
 99     // The ConstantPools of preloaded classes have references to other preloaded classes. We don't
100     // want any Java code (including JVMCI compiler) to use these classes until all of them
101     // are loaded.
102     return Atomic::load_acquire(&_class_preloading_finished);
103   }
104 }
105 
106 void AOTLinkedClassBulkLoader::load_javabase_boot_classes(JavaThread* current) {
107   load_classes_in_loader(current, LoaderKind::BOOT, nullptr);
108 }
109 
110 void AOTLinkedClassBulkLoader::load_non_javabase_boot_classes(JavaThread* current) {
111   load_classes_in_loader(current, LoaderKind::BOOT2, nullptr);
112 }
113 
114 void AOTLinkedClassBulkLoader::load_platform_classes(JavaThread* current) {
115   load_classes_in_loader(current, LoaderKind::PLATFORM, SystemDictionary::java_platform_loader());
116 }
117 
118 void AOTLinkedClassBulkLoader::load_app_classes(JavaThread* current) {
119   load_classes_in_loader(current, LoaderKind::APP, SystemDictionary::java_system_loader());
120 
121   if (PrintTrainingInfo) {
122     tty->print_cr("==================== archived_training_data ** after all classes preloaded ====================");
123     TrainingData::print_archived_training_data_on(tty);
124   }
125 
126   if (log_is_enabled(Info, cds, jit)) {
127     CDSAccess::test_heap_access_api();
128   }
129 
130   if (CDSConfig::is_dumping_final_static_archive()) {
131     assert(_unregistered_classes_from_preimage != nullptr, "must be");
132     for (int i = 0; i < _unregistered_classes_from_preimage->length(); i++) {
133       InstanceKlass* ik = _unregistered_classes_from_preimage->at(i);
134       SystemDictionaryShared::init_dumptime_info(ik);
135       SystemDictionaryShared::add_unregistered_class(current, ik);
136     }
137   }
138 
139   Atomic::release_store(&_class_preloading_finished, true);
140 }
141 
142 void AOTLinkedClassBulkLoader::load_classes_in_loader(JavaThread* current, LoaderKind loader_kind, oop class_loader_oop) {
143   if (!CDSConfig::is_using_aot_linked_classes()) {
144     return;
145   }
146 
147   HandleMark hm(current);
148   ResourceMark rm(current);
149   ExceptionMark em(current);
150 
151   Handle h_loader(current, class_loader_oop);
152 
153   load_table(AOTLinkedClassTable::for_static_archive(),  loader_kind, h_loader, current);
154   assert(!current->has_pending_exception(), "VM should have exited due to ExceptionMark");
155 
156   load_table(AOTLinkedClassTable::for_dynamic_archive(), loader_kind, h_loader, current);
157   assert(!current->has_pending_exception(), "VM should have exited due to ExceptionMark");
158 
159   if (loader_kind == LoaderKind::BOOT) {
160     // Delayed until init_javabase_preloaded_classes
161   } else {
162     HeapShared::initialize_default_subgraph_classes(h_loader, current);
163   }
164 
165   if (Universe::is_fully_initialized() && VerifyDuringStartup) {
166     // Make sure we're still in a clean slate.
167     VM_Verify verify_op;
168     VMThread::execute(&verify_op);
169   }
170 }
171 
172 void AOTLinkedClassBulkLoader::load_table(AOTLinkedClassTable* table, LoaderKind loader_kind, Handle loader, TRAPS) {
173   PerfTraceTime timer(_perf_class_preload_counters);
174 
175   if (loader_kind != LoaderKind::BOOT) {
176     assert(Universe::is_module_initialized(), "sanity");
177   }
178 
179   switch (loader_kind) {
180   case LoaderKind::BOOT:
181     load_classes_impl(loader_kind, table->boot(), "boot ", loader, CHECK);
182     break;
183 
184   case LoaderKind::BOOT2:
185     load_classes_impl(loader_kind, table->boot2(), "boot2", loader, CHECK);
186     break;
187 
188   case LoaderKind::PLATFORM:
189     {
190       const char* category = "plat ";
191       initiate_loading(THREAD, category, loader, table->boot());
192       initiate_loading(THREAD, category, loader, table->boot2());
193 
194       load_classes_impl(loader_kind, table->platform(), category, loader, CHECK);
195     }
196     break;
197   case LoaderKind::APP:
198     {
199       const char* category = "app  ";
200       initiate_loading(THREAD, category, loader, table->boot());
201       initiate_loading(THREAD, category, loader, table->boot2());
202       initiate_loading(THREAD, category, loader, table->platform());
203 
204       load_classes_impl(loader_kind, table->app(), category, loader, CHECK);
205     }
206   }
207 }
208 
209 void AOTLinkedClassBulkLoader::load_classes_impl(LoaderKind loader_kind, Array<InstanceKlass*>* classes, const char* category, Handle loader, TRAPS) {
210   if (classes == nullptr) {
211     return;
212   }
213 
214   ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader());
215 
216   for (int i = 0; i < classes->length(); i++) {
217     if (UsePerfData) {
218       _perf_classes_preloaded->inc();
219     }
220     InstanceKlass* ik = classes->at(i);
221     if (log_is_enabled(Info, cds, aot, load)) {
222       ResourceMark rm;
223       log_info(cds, aot, load)("%s %s%s%s", category, ik->external_name(),
224                                ik->is_loaded() ? " (already loaded)" : "",
225                                ik->is_hidden() ? " (hidden)" : "");
226     }
227 
228     if (!ik->is_loaded()) {
229       if (ik->is_hidden()) {
230         load_hidden_class(loader_data, ik, CHECK);
231       } else {
232         InstanceKlass* actual;
233         if (loader_data == ClassLoaderData::the_null_class_loader_data()) {
234           if (!Universe::is_fully_initialized()) {
235             load_class_quick(ik, loader_data, Handle(), CHECK);
236             actual = ik;
237           } else {
238             actual = SystemDictionary::load_instance_class(ik->name(), loader, CHECK);
239           }
240         } else {
241           actual = SystemDictionaryShared::find_or_load_shared_class(ik->name(), loader, CHECK);
242         }
243 
244         if (actual != ik) {
245           ResourceMark rm;
246           log_error(cds)("Unable to resolve %s class from CDS archive: %s", category, ik->external_name());
247           log_error(cds)("Expected: " INTPTR_FORMAT ", actual: " INTPTR_FORMAT, p2i(ik), p2i(actual));
248           log_error(cds)("JVMTI class retransformation is not supported when archive was generated with -XX:+AOTClassLinking.");
249           MetaspaceShared::unrecoverable_loading_error();
250         }
251         assert(actual->is_loaded(), "must be");
252       }
253     }
254   }
255 
256 
257   if (loader_kind == LoaderKind::BOOT) {
258     // Delayed until init_javabase_preloaded_classes
259   } else {
260     maybe_init_or_link(classes, CHECK);
261   }
262 }
263 
264 // Initiate loading of the <classes> in the <loader>. The <classes> should have already been loaded
265 // by a parent loader of the <loader>. This is necessary for handling pre-resolved CP entries.
266 //
267 // For example, we initiate the loading of java/lang/String in the AppClassLoader. This will allow
268 // any App classes to have a pre-resolved ConstantPool entry that references java/lang/String.
269 //
270 // TODO: we can limit the number of initiated classes to only those that are actually referenced by
271 // AOT-linked classes loaded by <loader>.
272 void AOTLinkedClassBulkLoader::initiate_loading(JavaThread* current, const char* category,
273                                                 Handle loader, Array<InstanceKlass*>* classes) {
274   if (classes == nullptr) {
275     return;
276   }
277 
278   ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader());
279   MonitorLocker mu1(SystemDictionary_lock);
280 
281   for (int i = 0; i < classes->length(); i++) {
282     InstanceKlass* ik = classes->at(i);
283     assert(ik->is_loaded(), "must have already been loaded by a parent loader");
284     if (ik->is_public() && !ik->is_hidden()) {
285       if (log_is_enabled(Info, cds, aot, load)) {
286         ResourceMark rm;
287         const char* defining_loader = (ik->class_loader() == nullptr ? "boot" : "plat");
288         log_info(cds, aot, load)("%s %s (initiated, defined by %s)", category, ik->external_name(),
289                                  defining_loader);
290       }
291       SystemDictionary::add_to_initiating_loader(current, ik, loader_data);
292     }
293   }
294 }
295 
296 // FIXME -- is this really correct? Do we need a special ClassLoaderData for each hidden class?
297 void AOTLinkedClassBulkLoader::load_hidden_class(ClassLoaderData* loader_data, InstanceKlass* ik, TRAPS) {
298   DEBUG_ONLY({
299       assert(ik->java_super()->is_loaded(), "must be");
300       for (int i = 0; i < ik->local_interfaces()->length(); i++) {
301         assert(ik->local_interfaces()->at(i)->is_loaded(), "must be");
302       }
303     });
304 
305   ik->restore_unshareable_info(loader_data, Handle(), NULL, CHECK);
306   SystemDictionary::load_shared_class_misc(ik, loader_data);
307   ik->add_to_hierarchy(THREAD);
308   assert(ik->is_loaded(), "Must be in at least loaded state");
309 }
310 
311 void AOTLinkedClassBulkLoader::load_class_quick(InstanceKlass* ik, ClassLoaderData* loader_data, Handle domain, TRAPS) {
312   assert(!ik->is_loaded(), "sanity");
313 
314 #ifdef ASSERT
315   {
316     InstanceKlass* super = ik->java_super();
317     if (super != nullptr) {
318       assert(super->is_loaded(), "must have been loaded");
319     }
320     Array<InstanceKlass*>* intfs = ik->local_interfaces();
321     for (int i = 0; i < intfs->length(); i++) {
322       assert(intfs->at(i)->is_loaded(), "must have been loaded");
323     }
324   }
325 #endif
326 
327   ik->restore_unshareable_info(loader_data, domain, nullptr, CHECK); // TODO: should we use ik->package()?
328   SystemDictionary::load_shared_class_misc(ik, loader_data);
329 
330   // We are adding to the dictionary but can get away without
331   // holding SystemDictionary_lock, as no other threads will be loading
332   // classes at the same time.
333   assert(!Universe::is_fully_initialized(), "sanity");
334   Dictionary* dictionary = loader_data->dictionary();
335   dictionary->add_klass(THREAD, ik->name(), ik);
336   ik->add_to_hierarchy(THREAD);
337   assert(ik->is_loaded(), "Must be in at least loaded state");
338 }
339 
340 void AOTLinkedClassBulkLoader::init_javabase_preloaded_classes(TRAPS) {
341   maybe_init_or_link(AOTLinkedClassTable::for_static_archive()->boot(),  CHECK);
342   //maybe_init_or_link(_dynamic_aot_loading_list._boot, CHECK); // TODO
343 
344   // Initialize java.base classes in the default subgraph.
345   HeapShared::initialize_default_subgraph_classes(Handle(), CHECK);
346 }
347 
348 void AOTLinkedClassBulkLoader::maybe_init_or_link(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_preinitialized_mirror()) {
353         ik->initialize_from_cds(CHECK);
354       } else if (PrelinkSharedClasses && ik->verified_at_dump_time()) {
355         ik->link_class(CHECK);
356       }
357     }
358   }
359 }
360 
361 void AOTLinkedClassBulkLoader::replay_training_at_init(Array<InstanceKlass*>* classes, TRAPS) {
362   if (classes != nullptr) {
363     for (int i = 0; i < classes->length(); i++) {
364       InstanceKlass* ik = classes->at(i);
365       if (ik->has_preinitialized_mirror() && ik->is_initialized() && !ik->has_init_deps_processed()) {
366         CompilationPolicy::replay_training_at_init(ik, CHECK);
367       }
368     }
369   }
370 }
371 
372 void AOTLinkedClassBulkLoader::replay_training_at_init_for_preloaded_classes(TRAPS) {
373   if (CDSConfig::is_using_aot_linked_classes() && TrainingData::have_data()) {
374     AOTLinkedClassTable* table = AOTLinkedClassTable::for_static_archive(); // not applicable for dynamic archive (?? why??)
375     replay_training_at_init(table->boot(),     CHECK);
376     replay_training_at_init(table->boot2(),    CHECK);
377     replay_training_at_init(table->platform(), CHECK);
378     replay_training_at_init(table->app(),      CHECK);
379 
380     CompilationPolicy::replay_training_at_init(false, CHECK);
381   }
382 }
383 
384 void AOTLinkedClassBulkLoader::print_counters() {
385   if (UsePerfData && _perf_class_preload_counters != nullptr) {
386     LogStreamHandle(Info, init) log;
387     if (log.is_enabled()) {
388       log.print_cr("AOTLinkedClassBulkLoader:");
389       log.print_cr("  preload:           " JLONG_FORMAT_W(6) "us (elapsed) " JLONG_FORMAT_W(6) " (thread) / " JLONG_FORMAT_W(5) " events",
390                    _perf_class_preload_counters->elapsed_counter_value_us(),
391                    _perf_class_preload_counters->thread_counter_value_us(),
392                    _perf_classes_preloaded->get_value());
393     }
394   }
395 }