1 /*
2 * Copyright (c) 2018, 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/aotArtifactFinder.hpp"
26 #include "cds/aotClassInitializer.hpp"
27 #include "cds/aotClassLocation.hpp"
28 #include "cds/aotCompressedPointers.hpp"
29 #include "cds/aotLogging.hpp"
30 #include "cds/aotMappedHeapLoader.hpp"
31 #include "cds/aotMappedHeapWriter.hpp"
32 #include "cds/aotMetaspace.hpp"
33 #include "cds/aotOopChecker.hpp"
34 #include "cds/aotReferenceObjSupport.hpp"
35 #include "cds/aotStreamedHeapLoader.hpp"
36 #include "cds/aotStreamedHeapWriter.hpp"
37 #include "cds/archiveBuilder.hpp"
38 #include "cds/archiveUtils.hpp"
39 #include "cds/cds_globals.hpp"
40 #include "cds/cdsConfig.hpp"
41 #include "cds/cdsEnumKlass.hpp"
42 #include "cds/cdsHeapVerifier.hpp"
43 #include "cds/heapShared.inline.hpp"
44 #include "cds/regeneratedClasses.hpp"
45 #include "classfile/classLoaderData.hpp"
46 #include "classfile/javaClasses.inline.hpp"
47 #include "classfile/modules.hpp"
48 #include "classfile/stringTable.hpp"
49 #include "classfile/symbolTable.hpp"
50 #include "classfile/systemDictionary.hpp"
51 #include "classfile/systemDictionaryShared.hpp"
52 #include "classfile/vmClasses.hpp"
53 #include "classfile/vmSymbols.hpp"
54 #include "gc/shared/collectedHeap.hpp"
55 #include "gc/shared/gcLocker.hpp"
56 #include "gc/shared/gcVMOperations.hpp"
57 #include "logging/log.hpp"
58 #include "logging/logStream.hpp"
59 #include "memory/iterator.inline.hpp"
60 #include "memory/resourceArea.hpp"
61 #include "memory/universe.hpp"
62 #include "oops/compressedOops.inline.hpp"
63 #include "oops/fieldStreams.inline.hpp"
64 #include "oops/objArrayOop.inline.hpp"
65 #include "oops/oop.inline.hpp"
66 #include "oops/oopCast.inline.hpp"
67 #include "oops/oopHandle.inline.hpp"
68 #include "oops/typeArrayOop.inline.hpp"
69 #include "prims/jvmtiExport.hpp"
70 #include "runtime/arguments.hpp"
71 #include "runtime/fieldDescriptor.inline.hpp"
72 #include "runtime/globals_extension.hpp"
73 #include "runtime/init.hpp"
74 #include "runtime/javaCalls.hpp"
75 #include "runtime/mutexLocker.hpp"
76 #include "runtime/safepointVerifiers.hpp"
77 #include "utilities/bitMap.inline.hpp"
78 #include "utilities/copy.hpp"
79 #if INCLUDE_G1GC
80 #include "gc/g1/g1CollectedHeap.hpp"
81 #endif
82
83 #if INCLUDE_CDS_JAVA_HEAP
84
85 struct ArchivableStaticFieldInfo {
86 const char* klass_name;
87 const char* field_name;
88 InstanceKlass* klass;
89 int offset;
90 BasicType type;
91
92 ArchivableStaticFieldInfo(const char* k, const char* f)
93 : klass_name(k), field_name(f), klass(nullptr), offset(0), type(T_ILLEGAL) {}
94
95 bool valid() {
96 return klass_name != nullptr;
97 }
98 };
99
100 HeapArchiveMode HeapShared::_heap_load_mode = HeapArchiveMode::_uninitialized;
101 HeapArchiveMode HeapShared::_heap_write_mode = HeapArchiveMode::_uninitialized;
102
103 size_t HeapShared::_alloc_count[HeapShared::ALLOC_STAT_SLOTS];
104 size_t HeapShared::_alloc_size[HeapShared::ALLOC_STAT_SLOTS];
105 size_t HeapShared::_total_obj_count;
106 size_t HeapShared::_total_obj_size;
107
108 #ifndef PRODUCT
109 #define ARCHIVE_TEST_FIELD_NAME "archivedObjects"
110 static Array<char>* _archived_ArchiveHeapTestClass = nullptr;
111 static const char* _test_class_name = nullptr;
112 static Klass* _test_class = nullptr;
113 static const ArchivedKlassSubGraphInfoRecord* _test_class_record = nullptr;
114 #endif
115
116 #ifdef ASSERT
117 // All classes that have at least one instance in the cached heap.
118 static ArchivableKlassTable* _dumptime_classes_with_cached_oops = nullptr;
119 static Array<Klass*>* _runtime_classes_with_cached_oops = nullptr;
120 #endif
121
122 //
123 // If you add new entries to the following tables, you should know what you're doing!
124 //
125
126 static ArchivableStaticFieldInfo archive_subgraph_entry_fields[] = {
127 {"java/lang/Integer$IntegerCache", "archivedCache"},
128 {"java/lang/Long$LongCache", "archivedCache"},
129 {"java/lang/Byte$ByteCache", "archivedCache"},
130 {"java/lang/Short$ShortCache", "archivedCache"},
131 {"java/lang/Character$CharacterCache", "archivedCache"},
132 {"java/util/jar/Attributes$Name", "KNOWN_NAMES"},
133 {"sun/util/locale/BaseLocale", "constantBaseLocales"},
134 {"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"},
135 {"java/util/ImmutableCollections", "archivedObjects"},
136 {"java/lang/ModuleLayer", "EMPTY_LAYER"},
137 {"java/lang/module/Configuration", "EMPTY_CONFIGURATION"},
138 {"jdk/internal/math/FDBigInteger", "archivedCaches"},
139
140 // full module graph support
141 {"jdk/internal/loader/ArchivedClassLoaders", "archivedClassLoaders"},
142 {ARCHIVED_BOOT_LAYER_CLASS, ARCHIVED_BOOT_LAYER_FIELD},
143 {"java/lang/Module$ArchivedData", "archivedData"},
144
145 #ifndef PRODUCT
146 {nullptr, nullptr}, // Extra slot for -XX:ArchiveHeapTestClass
147 #endif
148 {nullptr, nullptr},
149 };
150
151 KlassSubGraphInfo* HeapShared::_dump_time_special_subgraph;
152 ArchivedKlassSubGraphInfoRecord* HeapShared::_run_time_special_subgraph;
153 GrowableArrayCHeap<oop, mtClassShared>* HeapShared::_pending_roots = nullptr;
154 OopHandle HeapShared::_scratch_basic_type_mirrors[T_VOID+1];
155 MetaspaceObjToOopHandleTable* HeapShared::_scratch_objects_table = nullptr;
156
157 static bool is_subgraph_root_class_of(ArchivableStaticFieldInfo fields[], InstanceKlass* ik) {
158 for (int i = 0; fields[i].valid(); i++) {
159 if (fields[i].klass == ik) {
160 return true;
161 }
162 }
163 return false;
164 }
165
166 bool HeapShared::is_subgraph_root_class(InstanceKlass* ik) {
167 assert(CDSConfig::is_dumping_heap(), "dump-time only");
168 if (CDSConfig::is_dumping_klass_subgraphs()) {
169 // Legacy CDS archive support (to be deprecated)
170 return is_subgraph_root_class_of(archive_subgraph_entry_fields, ik);
171 } else {
172 return false;
173 }
174 }
175
176 oop HeapShared::CachedOopInfo::orig_referrer() const {
177 return _orig_referrer.resolve();
178 }
179
180 // This is a simple hashing of the oop's address. This function is used
181 // while copying the oops into the AOT heap region. We don't want to
182 // have any side effects during the copying, so we avoid calling
183 // p->identity_hash() which can update the object header.
184 unsigned HeapShared::oop_address_hash(oop const& p) {
185 assert(SafepointSynchronize::is_at_safepoint() ||
186 JavaThread::current()->is_in_no_safepoint_scope(), "sanity");
187 return primitive_hash(cast_from_oop<intptr_t>(p));
188 }
189
190 // About the hashcode in the cached objects:
191 // - If a source object has a hashcode, it must be copied into the cache.
192 // That's because some cached hashtables are laid out using this hashcode.
193 // - If a source object doesn't have a hashcode, we avoid computing it while
194 // copying the objects into the cache. This will allow the hashcode to be
195 // dynamically and randomly computed in each production, which generally
196 // desirable to make the hashcodes more random between runs.
197 unsigned HeapShared::archived_object_cache_hash(OopHandle const& oh) {
198 oop o = oh.resolve();
199 if (o == nullptr) {
200 return 0;
201 }
202 if (!_use_identity_hash_for_archived_object_cache) {
203 // This is called while we are copying the objects. Don't call o->identity_hash()
204 // as that will update the object header.
205 return oop_address_hash(o);
206 } else {
207 // This is called after all objects are copied. It's OK to update
208 // the object's hashcode.
209 //
210 // This may be called after we have left the AOT dumping safepoint.
211 // Objects in archived_object_cache() may be moved by the GC, so we
212 // can't use the address of o for computing the hash.
213 return o->identity_hash();
214 }
215 }
216
217 bool HeapShared::oop_handle_equals(const OopHandle& a, const OopHandle& b) {
218 return a.resolve() == b.resolve();
219 }
220
221 static void reset_states(oop obj, TRAPS) {
222 Handle h_obj(THREAD, obj);
223 InstanceKlass* klass = InstanceKlass::cast(obj->klass());
224 TempNewSymbol method_name = SymbolTable::new_symbol("resetArchivedStates");
225 Symbol* method_sig = vmSymbols::void_method_signature();
226
227 while (klass != nullptr) {
228 Method* method = klass->find_method(method_name, method_sig);
229 if (method != nullptr) {
230 assert(method->is_private(), "must be");
231 if (log_is_enabled(Debug, aot)) {
232 ResourceMark rm(THREAD);
233 log_debug(aot)(" calling %s", method->name_and_sig_as_C_string());
234 }
235 JavaValue result(T_VOID);
236 JavaCalls::call_special(&result, h_obj, klass,
237 method_name, method_sig, CHECK);
238 }
239 klass = klass->super();
240 }
241 }
242
243 void HeapShared::reset_archived_object_states(TRAPS) {
244 assert(CDSConfig::is_dumping_heap(), "dump-time only");
245 log_debug(aot)("Resetting platform loader");
246 reset_states(SystemDictionary::java_platform_loader(), CHECK);
247 log_debug(aot)("Resetting system loader");
248 reset_states(SystemDictionary::java_system_loader(), CHECK);
249
250 // Clean up jdk.internal.loader.ClassLoaders::bootLoader(), which is not
251 // directly used for class loading, but rather is used by the core library
252 // to keep track of resources, etc, loaded by the null class loader.
253 //
254 // Note, this object is non-null, and is not the same as
255 // ClassLoaderData::the_null_class_loader_data()->class_loader(),
256 // which is null.
257 log_debug(aot)("Resetting boot loader");
258 JavaValue result(T_OBJECT);
259 JavaCalls::call_static(&result,
260 vmClasses::jdk_internal_loader_ClassLoaders_klass(),
261 vmSymbols::bootLoader_name(),
262 vmSymbols::void_BuiltinClassLoader_signature(),
263 CHECK);
264 Handle boot_loader(THREAD, result.get_oop());
265 reset_states(boot_loader(), CHECK);
266 }
267
268 void HeapShared::ensure_determinism(TRAPS) {
269 TempNewSymbol class_name = SymbolTable::new_symbol("jdk/internal/util/WeakReferenceKey");
270 TempNewSymbol method_name = SymbolTable::new_symbol("ensureDeterministicAOTCache");
271
272 Klass* weak_ref_key_class = SystemDictionary::resolve_or_fail(class_name, true, CHECK);
273 precond(weak_ref_key_class != nullptr);
274
275 log_debug(aot)("Calling WeakReferenceKey::ensureDeterministicAOTCache(Object.class)");
276 JavaValue result(T_BOOLEAN);
277 JavaCalls::call_static(&result,
278 weak_ref_key_class,
279 method_name,
280 vmSymbols::void_boolean_signature(),
281 CHECK);
282 assert(result.get_jboolean() == false, "sanity");
283 }
284
285 void HeapShared::prepare_for_archiving(TRAPS) {
286 reset_archived_object_states(CHECK);
287 ensure_determinism(CHECK);
288 }
289
290 HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = nullptr;
291
292 // Controls the hashing method for the _archived_object_cache.
293 // Changes from false to true once, after all objects are copied,
294 // inside make_archived_object_cache_gc_safe().
295 // See archived_object_cache_hash() for more details.
296 bool HeapShared::_use_identity_hash_for_archived_object_cache = false;
297
298 bool HeapShared::is_archived_heap_in_use() {
299 if (HeapShared::is_loading()) {
300 if (HeapShared::is_loading_streaming_mode()) {
301 return AOTStreamedHeapLoader::is_in_use();
302 } else {
303 return AOTMappedHeapLoader::is_in_use();
304 }
305 }
306
307 return false;
308 }
309
310 bool HeapShared::can_use_archived_heap() {
311 FileMapInfo* static_mapinfo = FileMapInfo::current_info();
312 if (static_mapinfo == nullptr) {
313 return false;
314 }
315 if (!static_mapinfo->has_heap_region()) {
316 return false;
317 }
318 if (!static_mapinfo->object_streaming_mode() &&
319 !Universe::heap()->can_load_archived_objects() &&
320 !UseG1GC) {
321 // Incompatible object format
322 return false;
323 }
324
325 return true;
326 }
327
328 bool HeapShared::is_too_large_to_archive(size_t size) {
329 if (HeapShared::is_writing_streaming_mode()) {
330 return false;
331 } else {
332 return AOTMappedHeapWriter::is_too_large_to_archive(size);
333 }
334 }
335
336 bool HeapShared::is_too_large_to_archive(oop obj) {
337 if (HeapShared::is_writing_streaming_mode()) {
338 return false;
339 } else {
340 return AOTMappedHeapWriter::is_too_large_to_archive(obj);
341 }
342 }
343
344 bool HeapShared::is_string_too_large_to_archive(oop string) {
345 typeArrayOop value = java_lang_String::value_no_keepalive(string);
346 return is_too_large_to_archive(value);
347 }
348
349 void HeapShared::initialize_loading_mode(HeapArchiveMode mode) {
350 assert(_heap_load_mode == HeapArchiveMode::_uninitialized, "already set?");
351 assert(mode != HeapArchiveMode::_uninitialized, "sanity");
352 _heap_load_mode = mode;
353 };
354
355 void HeapShared::initialize_writing_mode() {
356 assert(!FLAG_IS_ERGO(AOTStreamableObjects), "Should not have been ergonomically set yet");
357
358 if (!CDSConfig::is_dumping_archive()) {
359 // We use FLAG_IS_CMDLINE below because we are specifically looking to warn
360 // a user that explicitly sets the flag on the command line for a JVM that is
361 // not dumping an archive.
362 if (FLAG_IS_CMDLINE(AOTStreamableObjects)) {
363 log_warning(cds)("-XX:%cAOTStreamableObjects was specified, "
364 "AOTStreamableObjects is only used for writing "
365 "the AOT cache.",
366 AOTStreamableObjects ? '+' : '-');
367 }
368 }
369
370 // The below checks use !FLAG_IS_DEFAULT instead of FLAG_IS_CMDLINE
371 // because the one step AOT cache creation transfers the AOTStreamableObjects
372 // flag value from the training JVM to the assembly JVM using an environment
373 // variable that sets the flag as ERGO in the assembly JVM.
374 if (FLAG_IS_DEFAULT(AOTStreamableObjects)) {
375 // By default, the value of AOTStreamableObjects should match !UseCompressedOops.
376 FLAG_SET_DEFAULT(AOTStreamableObjects, !UseCompressedOops);
377 } else if (!AOTStreamableObjects && UseZGC) {
378 // Never write mapped heap with ZGC
379 if (CDSConfig::is_dumping_archive()) {
380 log_warning(cds)("Heap archiving without streaming not supported for -XX:+UseZGC");
381 }
382 FLAG_SET_ERGO(AOTStreamableObjects, true);
383 }
384
385 if (CDSConfig::is_dumping_archive()) {
386 // Select default mode
387 assert(_heap_write_mode == HeapArchiveMode::_uninitialized, "already initialized?");
388 _heap_write_mode = AOTStreamableObjects ? HeapArchiveMode::_streaming : HeapArchiveMode::_mapping;
389 }
390 }
391
392 void HeapShared::initialize_streaming() {
393 assert(is_loading_streaming_mode(), "shouldn't call this");
394 if (can_use_archived_heap()) {
395 AOTStreamedHeapLoader::initialize();
396 }
397 }
398
399 void HeapShared::enable_gc() {
400 #ifdef ASSERT
401 // At this point, a GC may start and will be able to see some or all
402 // of the cached oops. The class of each oop seen by the GC must have
403 // already been loaded. One function with such a requirement is
404 // ClaimMetadataVisitingOopIterateClosure::do_klass().
405 if (is_archived_heap_in_use()) {
406 Array<Klass*>* klasses = _runtime_classes_with_cached_oops;
407
408 for (int i = 0; i < klasses->length(); i++) {
409 assert(klasses->at(i)->class_loader_data() != nullptr,
410 "class of cached oop must have been loaded");
411 }
412 }
413 #endif
414
415 if (AOTStreamedHeapLoader::is_in_use()) {
416 AOTStreamedHeapLoader::enable_gc();
417 }
418 }
419
420 void HeapShared::materialize_thread_object() {
421 if (AOTStreamedHeapLoader::is_in_use()) {
422 AOTStreamedHeapLoader::materialize_thread_object();
423 }
424 }
425
426 void HeapShared::archive_interned_string(oop string) {
427 assert(HeapShared::is_writing_mapping_mode(), "Only used by this mode");
428 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, string);
429 assert(success, "shared strings array must not point to arrays or strings that are too large to archive");
430 }
431
432 void HeapShared::finalize_initialization(FileMapInfo* static_mapinfo) {
433 if (HeapShared::is_loading()) {
434 if (HeapShared::is_loading_streaming_mode()) {
435 // Heap initialization can be done only after vtables are initialized by ReadClosure.
436 AOTStreamedHeapLoader::finish_initialization(static_mapinfo);
437 } else {
438 // Finish up archived heap initialization. These must be
439 // done after ReadClosure.
440 AOTMappedHeapLoader::finish_initialization(static_mapinfo);
441 }
442 }
443 }
444
445 void HeapShared::make_archived_object_cache_gc_safe() {
446 ArchivedObjectCache* new_cache = new (mtClass)ArchivedObjectCache(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE);
447
448 // It's safe to change the behavior of the hash function now, because iterate_all()
449 // doesn't call the hash function.
450 // See archived_object_cache_hash() for more details.
451 assert(_use_identity_hash_for_archived_object_cache == false, "happens only once");
452 _use_identity_hash_for_archived_object_cache = true;
453
454 // Copy all CachedOopInfo into a new table using a different hashing algorithm
455 archived_object_cache()->iterate_all([&] (OopHandle oh, CachedOopInfo info) {
456 if (Arguments::is_valhalla_enabled() && oh.resolve()->klass()->is_inline_klass()) {
457 // After make_archived_object_cache_gc_safe() returns,
458 // _archived_object_cache->get() is called only from the (future) AOT code
459 // compiler to access heap oops referenced by AOT-compiled method.
460 //
461 // As planned in JDK 27 (JDK-8335368), AOT-compiled methods will only reference
462 // oops that are Strings, mirrors, or exceptions, all of which are not value
463 // objects.
464 //
465 // We exclude value objects from new_cache, as we don't know how to track them
466 // after the GC moves them. This should be fixed when AOT-compiled methods
467 // need to reference value objects.
468 //
469 // Also TODO: the AOT heap should de-duplicate value objects with identical
470 // values. See JDK-8383381
471 } else {
472 new_cache->put_when_absent(oh, info);
473 }
474 });
475
476 destroy_archived_object_cache();
477 _archived_object_cache = new_cache;
478 }
479
480 HeapShared::CachedOopInfo* HeapShared::get_cached_oop_info(oop obj) {
481 OopHandle oh(Universe::vm_global(), obj);
482 CachedOopInfo* result = _archived_object_cache->get(oh);
483 oh.release(Universe::vm_global());
484 return result;
485 }
486
487 bool HeapShared::has_been_archived(oop obj) {
488 assert(CDSConfig::is_dumping_heap(), "dump-time only");
489 return get_cached_oop_info(obj) != nullptr;
490 }
491
492 int HeapShared::append_root(oop obj) {
493 assert(SafepointSynchronize::is_at_safepoint(), "sanity");
494 assert(CDSConfig::is_dumping_heap(), "dump-time only");
495 assert(_pending_roots != nullptr, "sanity");
496
497 if (obj == nullptr) {
498 assert(_pending_roots->at(0) == nullptr, "root index 0 always maps to null");
499 return 0;
500 } else if (CDSConfig::is_dumping_aot_linked_classes()) {
501 // The AOT compiler may refer the same obj many times, so we
502 // should use the same index for this oop to avoid excessive entries
503 // in the roots array.
504 CachedOopInfo* obj_info = get_cached_oop_info(obj);
505 assert(obj_info != nullptr, "must be archived");
506
507 if (obj_info->root_index() > 0) {
508 return obj_info->root_index();
509 } else {
510 assert(obj_info->root_index() < 0, "must not be zero");
511 int i = _pending_roots->append(obj);
512 obj_info->set_root_index(i);
513 return i;
514 }
515 } else {
516 return _pending_roots->append(obj);
517 }
518 }
519
520 int HeapShared::get_root_index(oop obj) {
521 if (java_lang_Class::is_instance(obj)) {
522 obj = scratch_java_mirror(obj);
523 }
524
525 CachedOopInfo* obj_info = get_cached_oop_info(obj);
526 const char* error = nullptr;
527 if (obj_info == nullptr) {
528 error = "Not a cached oop";
529 } else if (obj_info->root_index() < 0) {
530 error = "Not a cached oop root";
531 } else {
532 return obj_info->root_index();
533 }
534
535 ResourceMark rm;
536 log_debug(aot, codecache, oops)("%s: " INTPTR_FORMAT " (%s)", error,
537 cast_from_oop<uintptr_t>(obj),
538 obj->klass()->external_name());
539 return -1;
540 }
541
542 oop HeapShared::get_root(int index, bool clear) {
543 assert(index >= 0, "sanity");
544 assert(is_archived_heap_in_use(), "getting roots into heap that is not used");
545
546 oop result;
547 if (HeapShared::is_loading_streaming_mode()) {
548 result = AOTStreamedHeapLoader::get_root(index);
549 } else {
550 assert(HeapShared::is_loading_mapping_mode(), "must be");
551 result = AOTMappedHeapLoader::get_root(index);
552 }
553
554 if (clear) {
555 clear_root(index);
556 }
557
558 return result;
559 }
560
561 void HeapShared::finish_materialize_objects() {
562 if (AOTStreamedHeapLoader::is_in_use()) {
563 AOTStreamedHeapLoader::finish_materialize_objects();
564 }
565 }
566
567 void HeapShared::clear_root(int index) {
568 if (CDSConfig::is_using_aot_linked_classes()) {
569 // When AOT linked classes are in use, all roots will be in use all
570 // the time, there's no benefit for clearing the roots. Also, we
571 // can't clear the roots as they can be shared.
572 return;
573 }
574
575 assert(index >= 0, "sanity");
576 assert(CDSConfig::is_using_archive(), "must be");
577 if (is_archived_heap_in_use()) {
578 if (log_is_enabled(Debug, aot, heap)) {
579 log_debug(aot, heap)("Clearing root %d: was %zu", index, p2i(get_root(index, false /* clear */)));
580 }
581 if (HeapShared::is_loading_streaming_mode()) {
582 AOTStreamedHeapLoader::clear_root(index);
583 } else {
584 assert(HeapShared::is_loading_mapping_mode(), "must be");
585 AOTMappedHeapLoader::clear_root(index);
586 }
587 }
588 }
589
590 bool HeapShared::archive_object(oop obj, oop referrer, KlassSubGraphInfo* subgraph_info) {
591 assert(CDSConfig::is_dumping_heap(), "dump-time only");
592
593 assert(!obj->is_stackChunk(), "do not archive stack chunks");
594 if (has_been_archived(obj)) {
595 return true;
596 }
597
598 if (is_too_large_to_archive(obj)) {
599 log_debug(aot, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: %zu",
600 p2i(obj), obj->size());
601 debug_trace();
602 return false;
603 }
604
605 AOTArtifactFinder::add_cached_class(obj->klass());
606 AOTOopChecker::check(obj); // Make sure contents of this oop are safe.
607 count_allocation(obj->size());
608 DEBUG_ONLY(_dumptime_classes_with_cached_oops->add(obj->klass()));
609
610 if (HeapShared::is_writing_streaming_mode()) {
611 AOTStreamedHeapWriter::add_source_obj(obj);
612 } else {
613 AOTMappedHeapWriter::add_source_obj(obj);
614 }
615
616 OopHandle oh(Universe::vm_global(), obj);
617 CachedOopInfo info = make_cached_oop_info(obj, referrer);
618 archived_object_cache()->put_when_absent(oh, info);
619 archived_object_cache()->maybe_grow();
620
621 Klass* k = obj->klass();
622 if (k->is_instance_klass()) {
623 // Whenever we see a non-array Java object of type X, we mark X to be aot-initialized.
624 // This ensures that during the production run, whenever Java code sees a cached object
625 // of type X, we know that X is already initialized. (see TODO comment below ...)
626
627 if (InstanceKlass::cast(k)->is_enum_subclass()
628 // We can't rerun <clinit> of enum classes (see cdsEnumKlass.cpp) so
629 // we must store them as AOT-initialized.
630 || (subgraph_info == _dump_time_special_subgraph))
631 // TODO: we do this only for the special subgraph for now. Extending this to
632 // other subgraphs would require more refactoring of the core library (such as
633 // move some initialization logic into runtimeSetup()).
634 //
635 // For the other subgraphs, we have a weaker mechanism to ensure that
636 // all classes in a subgraph are initialized before the subgraph is programmatically
637 // returned from jdk.internal.misc.CDS::initializeFromArchive().
638 // See HeapShared::initialize_from_archived_subgraph().
639 {
640 AOTArtifactFinder::add_aot_inited_class(InstanceKlass::cast(k));
641 }
642
643 if (java_lang_Class::is_instance(obj)) {
644 Klass* mirror_k = java_lang_Class::as_Klass(obj);
645 if (mirror_k != nullptr) {
646 AOTArtifactFinder::add_cached_class(mirror_k);
647 }
648 } else if (java_lang_invoke_ResolvedMethodName::is_instance(obj)) {
649 Method* m = java_lang_invoke_ResolvedMethodName::vmtarget(obj);
650 if (m != nullptr) {
651 m = RegeneratedClasses::maybe_get_regenerated_object(m);
652 InstanceKlass* method_holder = m->method_holder();
653 AOTArtifactFinder::add_cached_class(method_holder);
654 }
655 }
656 }
657
658 if (log_is_enabled(Debug, aot, heap)) {
659 ResourceMark rm;
660 LogTarget(Debug, aot, heap) log;
661 LogStream out(log);
662 out.print("Archived heap object " PTR_FORMAT " : %s ",
663 p2i(obj), obj->klass()->external_name());
664 if (java_lang_Class::is_instance(obj)) {
665 Klass* k = java_lang_Class::as_Klass(obj);
666 if (k != nullptr) {
667 out.print("%s", k->external_name());
668 } else {
669 out.print("primitive");
670 }
671 }
672 out.cr();
673 }
674
675 return true;
676 }
677
678 class MetaspaceObjToOopHandleTable: public HashTable<MetaspaceObj*, OopHandle,
679 36137, // prime number
680 AnyObj::C_HEAP,
681 mtClassShared> {
682 public:
683 oop get_oop(MetaspaceObj* ptr) {
684 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
685 OopHandle* handle = get(ptr);
686 if (handle != nullptr) {
687 return handle->resolve();
688 } else {
689 return nullptr;
690 }
691 }
692 void set_oop(MetaspaceObj* ptr, oop o) {
693 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
694 OopHandle handle(Universe::vm_global(), o);
695 put_when_absent(ptr, handle);
696 }
697 void remove_oop(MetaspaceObj* ptr) {
698 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
699 OopHandle* handle = get(ptr);
700 if (handle != nullptr) {
701 handle->release(Universe::vm_global());
702 remove(ptr);
703 }
704 }
705 };
706
707 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
708 if (SystemDictionaryShared::is_builtin_loader(src->pool_holder()->class_loader_data())) {
709 _scratch_objects_table->set_oop(src, dest);
710 }
711 }
712
713 refArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
714 oop rr = _scratch_objects_table->get_oop(src);
715 return rr == nullptr ? nullptr : oop_cast<refArrayOop>(rr);
716 }
717
718 void HeapShared::remove_scratch_resolved_references(ConstantPool* src) {
719 if (CDSConfig::is_dumping_heap()) {
720 _scratch_objects_table->remove_oop(src);
721 }
722 }
723
724 void HeapShared::init_dumping() {
725 _scratch_objects_table = new (mtClass)MetaspaceObjToOopHandleTable();
726 _pending_roots = new GrowableArrayCHeap<oop, mtClassShared>(500);
727 _pending_roots->append(nullptr); // root index 0 represents a null oop
728 DEBUG_ONLY(_dumptime_classes_with_cached_oops = new (mtClassShared)ArchivableKlassTable());
729 }
730
731 void HeapShared::init_scratch_objects_for_basic_type_mirrors(TRAPS) {
732 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
733 BasicType bt = (BasicType)i;
734 if (!is_reference_type(bt)) {
735 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
736 _scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
737 }
738 }
739 }
740
741 // Given java_mirror that represents a (primitive or reference) type T,
742 // return the "scratch" version that represents the same type T. Note
743 // that java_mirror will be returned if the mirror is already a scratch mirror.
744 //
745 // See java_lang_Class::create_scratch_mirror() for more info.
746 oop HeapShared::scratch_java_mirror(oop java_mirror) {
747 assert(java_lang_Class::is_instance(java_mirror), "must be");
748
749 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
750 BasicType bt = (BasicType)i;
751 if (!is_reference_type(bt)) {
752 if (_scratch_basic_type_mirrors[i].resolve() == java_mirror) {
753 return java_mirror;
754 }
755 }
756 }
757
758 if (java_lang_Class::is_primitive(java_mirror)) {
759 return scratch_java_mirror(java_lang_Class::as_BasicType(java_mirror));
760 } else {
761 return scratch_java_mirror(java_lang_Class::as_Klass(java_mirror));
762 }
763 }
764
765 oop HeapShared::scratch_java_mirror(BasicType t) {
766 assert((uint)t < T_VOID+1, "range check");
767 assert(!is_reference_type(t), "sanity");
768 return _scratch_basic_type_mirrors[t].resolve();
769 }
770
771 oop HeapShared::scratch_java_mirror(Klass* k) {
772 return _scratch_objects_table->get_oop(k);
773 }
774
775 void HeapShared::set_scratch_java_mirror(Klass* k, oop mirror) {
776 _scratch_objects_table->set_oop(k, mirror);
777 }
778
779 void HeapShared::remove_scratch_objects(Klass* k) {
780 // Klass is being deallocated. Java mirror can still be alive, and it should not
781 // point to dead klass. We need to break the link from mirror to the Klass.
782 // See how InstanceKlass::deallocate_contents does it for normal mirrors.
783 oop mirror = _scratch_objects_table->get_oop(k);
784 if (mirror != nullptr) {
785 java_lang_Class::set_klass(mirror, nullptr);
786 }
787 _scratch_objects_table->remove_oop(k);
788 if (k->is_instance_klass()) {
789 _scratch_objects_table->remove(InstanceKlass::cast(k)->constants());
790 }
791 }
792
793 //TODO: we eventually want a more direct test for these kinds of things.
794 //For example the JVM could record some bit of context from the creation
795 //of the klass, such as who called the hidden class factory. Using
796 //string compares on names is fragile and will break as soon as somebody
797 //changes the names in the JDK code. See discussion in JDK-8342481 for
798 //related ideas about marking AOT-related classes.
799 bool HeapShared::is_lambda_form_klass(InstanceKlass* ik) {
800 return ik->is_hidden() &&
801 (ik->name()->starts_with("java/lang/invoke/LambdaForm$MH+") ||
802 ik->name()->starts_with("java/lang/invoke/LambdaForm$DMH+") ||
803 ik->name()->starts_with("java/lang/invoke/LambdaForm$BMH+") ||
804 ik->name()->starts_with("java/lang/invoke/LambdaForm$VH+"));
805 }
806
807 bool HeapShared::is_lambda_proxy_klass(InstanceKlass* ik) {
808 return ik->is_hidden() && (ik->name()->index_of_at(0, "$$Lambda+", 9) > 0);
809 }
810
811 bool HeapShared::is_string_concat_klass(InstanceKlass* ik) {
812 return ik->is_hidden() && ik->name()->starts_with("java/lang/String$$StringConcat");
813 }
814
815 bool HeapShared::is_archivable_hidden_klass(InstanceKlass* ik) {
816 return CDSConfig::is_dumping_method_handles() &&
817 (is_lambda_form_klass(ik) || is_lambda_proxy_klass(ik) || is_string_concat_klass(ik));
818 }
819
820
821 void HeapShared::copy_and_rescan_aot_inited_mirror(InstanceKlass* ik) {
822 ik->set_has_aot_initialized_mirror();
823
824 oop orig_mirror;
825 if (RegeneratedClasses::is_regenerated_object(ik)) {
826 InstanceKlass* orig_ik = RegeneratedClasses::get_original_object(ik);
827 precond(orig_ik->is_initialized());
828 orig_mirror = orig_ik->java_mirror();
829 } else {
830 precond(ik->is_initialized());
831 orig_mirror = ik->java_mirror();
832 }
833
834 oop m = scratch_java_mirror(ik);
835 int nfields = 0;
836 for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {
837 if (fs.access_flags().is_static()) {
838 fieldDescriptor& fd = fs.field_descriptor();
839 int offset = fd.offset();
840 switch (fd.field_type()) {
841 case T_OBJECT:
842 case T_ARRAY:
843 {
844 oop field_obj = orig_mirror->obj_field(offset);
845 if (offset == java_lang_Class::reflection_data_offset()) {
846 // Class::reflectData use SoftReference, which cannot be archived. Set it
847 // to null and it will be recreated at runtime.
848 field_obj = nullptr;
849 }
850 m->obj_field_put(offset, field_obj);
851 if (field_obj != nullptr) {
852 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, field_obj);
853 assert(success, "sanity");
854 }
855 }
856 break;
857 case T_BOOLEAN:
858 m->bool_field_put(offset, orig_mirror->bool_field(offset));
859 break;
860 case T_BYTE:
861 m->byte_field_put(offset, orig_mirror->byte_field(offset));
862 break;
863 case T_SHORT:
864 m->short_field_put(offset, orig_mirror->short_field(offset));
865 break;
866 case T_CHAR:
867 m->char_field_put(offset, orig_mirror->char_field(offset));
868 break;
869 case T_INT:
870 m->int_field_put(offset, orig_mirror->int_field(offset));
871 break;
872 case T_LONG:
873 m->long_field_put(offset, orig_mirror->long_field(offset));
874 break;
875 case T_FLOAT:
876 m->float_field_put(offset, orig_mirror->float_field(offset));
877 break;
878 case T_DOUBLE:
879 m->double_field_put(offset, orig_mirror->double_field(offset));
880 break;
881 default:
882 ShouldNotReachHere();
883 }
884 nfields ++;
885 }
886 }
887
888 oop class_data = java_lang_Class::class_data(orig_mirror);
889 java_lang_Class::set_class_data(m, class_data);
890 if (class_data != nullptr) {
891 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, class_data);
892 assert(success, "sanity");
893 }
894
895 if (log_is_enabled(Debug, aot, init)) {
896 ResourceMark rm;
897 log_debug(aot, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
898 ik->is_hidden() ? " (hidden)" : "",
899 ik->is_enum_subclass() ? " (enum)" : "");
900 }
901 }
902
903 void HeapShared::copy_java_mirror(oop orig_mirror, oop scratch_m) {
904 // We need to retain the identity_hash, because it may have been used by some hashtables
905 // in the shared heap.
906 if (!orig_mirror->fast_no_hash_check()) {
907 intptr_t src_hash = orig_mirror->identity_hash();
908 if (UseCompactObjectHeaders) {
909 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
910 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
911 } else {
912 // For valhalla, the prototype header is the same as markWord::prototype();
913 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
914 }
915 assert(scratch_m->mark().is_unlocked(), "sanity");
916
917 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
918 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
919 }
920
921 Klass* k = java_lang_Class::as_Klass(orig_mirror);
922 if (k != nullptr && k->is_instance_klass()) {
923 InstanceKlass* ik = InstanceKlass::cast(k);
924
925 if (ik->is_inline_klass() && ik->is_initialized()) {
926 // Only concrete value classes need the null_reset field
927 InlineKlass* ilk = InlineKlass::cast(k);
928 if (ilk->supports_nullable_layouts()) {
929 scratch_m->obj_field_put(ilk->null_reset_value_offset(), ilk->null_reset_value());
930 }
931 }
932
933 if (ik->has_acmp_maps_offset()) {
934 int maps_offset = ik->acmp_maps_offset();
935 oop maps = orig_mirror->obj_field(maps_offset);
936 scratch_m->obj_field_put(maps_offset, maps);
937 }
938 }
939
940 if (CDSConfig::is_dumping_aot_linked_classes()) {
941 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
942 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
943 }
944 }
945
946 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
947 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
948 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
949 if (rr != nullptr && !HeapShared::is_too_large_to_archive(rr)) {
950 return HeapShared::scratch_resolved_references(src_ik->constants());
951 }
952 }
953 return nullptr;
954 }
955
956 int HeapShared::archive_exception_instance(oop exception) {
957 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, exception);
958 assert(success, "sanity");
959 return append_root(exception);
960 }
961
962 void HeapShared::get_pointer_info(oop src_obj, bool& has_oop_pointers, bool& has_native_pointers) {
963 OopHandle oh(&src_obj);
964 CachedOopInfo* info = archived_object_cache()->get(oh);
965 assert(info != nullptr, "must be");
966 has_oop_pointers = info->has_oop_pointers();
967 has_native_pointers = info->has_native_pointers();
968 }
969
970 void HeapShared::set_has_native_pointers(oop src_obj) {
971 OopHandle oh(&src_obj);
972 CachedOopInfo* info = archived_object_cache()->get(oh);
973 assert(info != nullptr, "must be");
974 info->set_has_native_pointers();
975 }
976
977 // Between start_scanning_for_oops() and end_scanning_for_oops(), we discover all Java heap objects that
978 // should be stored in the AOT cache. The scanning is coordinated by AOTArtifactFinder.
979 void HeapShared::start_scanning_for_oops() {
980 {
981 NoSafepointVerifier nsv;
982
983 // The special subgraph doesn't belong to any class. We use Object_klass() here just
984 // for convenience.
985 _dump_time_special_subgraph = init_subgraph_info(vmClasses::Object_klass());
986
987 // Cache for recording where the archived objects are copied to
988 create_archived_object_cache();
989
990 if (HeapShared::is_writing_mapping_mode() && (UseG1GC || UseCompressedOops)) {
991 aot_log_info(aot)("Heap range = [" PTR_FORMAT " - " PTR_FORMAT "]",
992 UseCompressedOops ? p2i(CompressedOops::begin()) :
993 p2i((address)G1CollectedHeap::heap()->reserved().start()),
994 UseCompressedOops ? p2i(CompressedOops::end()) :
995 p2i((address)G1CollectedHeap::heap()->reserved().end()));
996 }
997
998 archive_subgraphs();
999 }
1000
1001 init_seen_objects_table();
1002 Universe::archive_exception_instances();
1003 }
1004
1005 void HeapShared::end_scanning_for_oops() {
1006 if (is_writing_mapping_mode()) {
1007 StringTable::init_shared_table();
1008 }
1009 delete_seen_objects_table();
1010 }
1011
1012 void HeapShared::write_heap(AOTMappedHeapInfo* mapped_heap_info, AOTStreamedHeapInfo* streamed_heap_info) {
1013 {
1014 NoSafepointVerifier nsv;
1015 CDSHeapVerifier::verify();
1016 check_special_subgraph_classes();
1017 }
1018
1019 if (HeapShared::is_writing_mapping_mode()) {
1020 StringTable::write_shared_table();
1021 AOTMappedHeapWriter::write(_pending_roots, mapped_heap_info);
1022 } else {
1023 assert(HeapShared::is_writing_streaming_mode(), "are there more modes?");
1024 AOTStreamedHeapWriter::write(_pending_roots, streamed_heap_info);
1025 }
1026
1027 ArchiveBuilder::OtherROAllocMark mark;
1028 write_subgraph_info_table();
1029
1030 DEBUG_ONLY(_runtime_classes_with_cached_oops = _dumptime_classes_with_cached_oops->write_ordered_array());
1031
1032 delete _pending_roots;
1033 _pending_roots = nullptr;
1034
1035 make_archived_object_cache_gc_safe();
1036 }
1037
1038 void HeapShared::scan_java_mirror(oop orig_mirror) {
1039 oop m = scratch_java_mirror(orig_mirror);
1040 if (m != nullptr) { // nullptr if for custom class loader
1041 copy_java_mirror(orig_mirror, m);
1042 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, m);
1043 assert(success, "sanity");
1044 }
1045 }
1046
1047 void HeapShared::scan_java_class(Klass* orig_k) {
1048 scan_java_mirror(orig_k->java_mirror());
1049
1050 if (orig_k->is_instance_klass()) {
1051 InstanceKlass* orig_ik = InstanceKlass::cast(orig_k);
1052 orig_ik->constants()->prepare_resolved_references_for_archiving();
1053 objArrayOop rr = get_archived_resolved_references(orig_ik);
1054 if (rr != nullptr) {
1055 bool success = HeapShared::archive_reachable_objects_from(1, _dump_time_special_subgraph, rr);
1056 assert(success, "must be");
1057 }
1058 }
1059 }
1060
1061 void HeapShared::archive_subgraphs() {
1062 assert(CDSConfig::is_dumping_heap(), "must be");
1063
1064 if (CDSConfig::is_dumping_klass_subgraphs()) {
1065 archive_object_subgraphs(archive_subgraph_entry_fields);
1066 }
1067 }
1068
1069 //
1070 // Subgraph archiving support
1071 //
1072 HeapShared::DumpTimeKlassSubGraphInfoTable* HeapShared::_dump_time_subgraph_info_table = nullptr;
1073 HeapShared::RunTimeKlassSubGraphInfoTable HeapShared::_run_time_subgraph_info_table;
1074
1075 // Get the subgraph_info for Klass k. A new subgraph_info is created if
1076 // there is no existing one for k. The subgraph_info records the "buffered"
1077 // address of the class.
1078 KlassSubGraphInfo* HeapShared::init_subgraph_info(Klass* k) {
1079 assert(CDSConfig::is_dumping_heap(), "dump time only");
1080 bool created;
1081 KlassSubGraphInfo* info =
1082 _dump_time_subgraph_info_table->put_if_absent(k, KlassSubGraphInfo(k), &created);
1083 assert(created, "must not initialize twice");
1084 return info;
1085 }
1086
1087 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
1088 assert(CDSConfig::is_dumping_heap(), "dump time only");
1089 KlassSubGraphInfo* info = _dump_time_subgraph_info_table->get(k);
1090 assert(info != nullptr, "must have been initialized");
1091 return info;
1092 }
1093
1094 // Add an entry field to the current KlassSubGraphInfo.
1095 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
1096 assert(CDSConfig::is_dumping_heap(), "dump time only");
1097 if (_subgraph_entry_fields == nullptr) {
1098 _subgraph_entry_fields =
1099 new (mtClass) GrowableArray<int>(10, mtClass);
1100 }
1101 _subgraph_entry_fields->append(static_field_offset);
1102 _subgraph_entry_fields->append(HeapShared::append_root(v));
1103 }
1104
1105 // Add the Klass* for an object in the current KlassSubGraphInfo's subgraphs.
1106 // Only objects of boot classes can be included in sub-graph.
1107 void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) {
1108 assert(CDSConfig::is_dumping_heap(), "dump time only");
1109
1110 if (_subgraph_object_klasses == nullptr) {
1111 _subgraph_object_klasses =
1112 new (mtClass) GrowableArray<Klass*>(50, mtClass);
1113 }
1114
1115 if (_k == orig_k) {
1116 // Don't add the Klass containing the sub-graph to it's own klass
1117 // initialization list.
1118 return;
1119 }
1120
1121 if (orig_k->is_instance_klass()) {
1122 #ifdef ASSERT
1123 InstanceKlass* ik = InstanceKlass::cast(orig_k);
1124 if (CDSConfig::is_dumping_method_handles()) {
1125 // -XX:AOTInitTestClass must be used carefully in regression tests to
1126 // include only classes that are safe to aot-initialize.
1127 assert(ik->class_loader() == nullptr ||
1128 HeapShared::is_lambda_proxy_klass(ik) ||
1129 AOTClassInitializer::has_test_class(),
1130 "we can archive only instances of boot classes or lambda proxy classes");
1131 } else {
1132 assert(ik->class_loader() == nullptr, "must be boot class");
1133 }
1134 #endif
1135 // vmClasses::xxx_klass() are not updated, need to check
1136 // the original Klass*
1137 if (orig_k == vmClasses::String_klass() ||
1138 orig_k == vmClasses::Object_klass()) {
1139 // Initialized early during VM initialization. No need to be added
1140 // to the sub-graph object class list.
1141 return;
1142 }
1143 check_allowed_klass(InstanceKlass::cast(orig_k));
1144 } else if (orig_k->is_objArray_klass()) {
1145 Klass* abk = ObjArrayKlass::cast(orig_k)->bottom_klass();
1146 if (abk->is_instance_klass()) {
1147 assert(InstanceKlass::cast(abk)->defined_by_boot_loader(),
1148 "must be boot class");
1149 check_allowed_klass(InstanceKlass::cast(ObjArrayKlass::cast(orig_k)->bottom_klass()));
1150 }
1151 if (orig_k == Universe::objectArrayKlass()) {
1152 // Initialized early during Universe::genesis. No need to be added
1153 // to the list.
1154 return;
1155 }
1156 if (orig_k->is_flatArray_klass()) {
1157 _subgraph_object_klasses->append_if_missing(FlatArrayKlass::cast(orig_k)->element_klass());
1158 }
1159 } else {
1160 assert(orig_k->is_typeArray_klass(), "must be");
1161 // Primitive type arrays are created early during Universe::genesis.
1162 return;
1163 }
1164
1165 if (log_is_enabled(Debug, aot, heap)) {
1166 if (!_subgraph_object_klasses->contains(orig_k)) {
1167 ResourceMark rm;
1168 log_debug(aot, heap)("Adding klass %s", orig_k->external_name());
1169 }
1170 }
1171
1172 _subgraph_object_klasses->append_if_missing(orig_k);
1173 }
1174
1175 void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) {
1176 #ifndef PRODUCT
1177 if (AOTClassInitializer::has_test_class()) {
1178 // The tests can cache arbitrary types of objects.
1179 return;
1180 }
1181 #endif
1182
1183 if (ik->module()->name() == vmSymbols::java_base()) {
1184 assert(ik->package() != nullptr, "classes in java.base cannot be in unnamed package");
1185 return;
1186 }
1187
1188 const char* lambda_msg = "";
1189 if (CDSConfig::is_dumping_method_handles()) {
1190 lambda_msg = ", or a lambda proxy class";
1191 if (HeapShared::is_lambda_proxy_klass(ik) &&
1192 (ik->class_loader() == nullptr ||
1193 ik->class_loader() == SystemDictionary::java_platform_loader() ||
1194 ik->class_loader() == SystemDictionary::java_system_loader())) {
1195 return;
1196 }
1197 }
1198
1199 #ifndef PRODUCT
1200 if (!ik->module()->is_named() && ik->package() == nullptr && ArchiveHeapTestClass != nullptr) {
1201 // This class is loaded by ArchiveHeapTestClass
1202 return;
1203 }
1204 const char* testcls_msg = ", or a test class in an unnamed package of an unnamed module";
1205 #else
1206 const char* testcls_msg = "";
1207 #endif
1208
1209 ResourceMark rm;
1210 log_error(aot, heap)("Class %s not allowed in archive heap. Must be in java.base%s%s",
1211 ik->external_name(), lambda_msg, testcls_msg);
1212 AOTMetaspace::unrecoverable_writing_error();
1213 }
1214
1215 // Initialize an archived subgraph_info_record from the given KlassSubGraphInfo.
1216 void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) {
1217 _k = ArchiveBuilder::get_buffered_klass(info->klass());
1218 _entry_field_records = nullptr;
1219 _subgraph_object_klasses = nullptr;
1220
1221 // populate the entry fields
1222 GrowableArray<int>* entry_fields = info->subgraph_entry_fields();
1223 if (entry_fields != nullptr) {
1224 int num_entry_fields = entry_fields->length();
1225 assert(num_entry_fields % 2 == 0, "sanity");
1226 _entry_field_records =
1227 ArchiveBuilder::new_ro_array<int>(num_entry_fields);
1228 for (int i = 0 ; i < num_entry_fields; i++) {
1229 _entry_field_records->at_put(i, entry_fields->at(i));
1230 }
1231 }
1232
1233 // <recorded_klasses> has the Klasses of all the objects that are referenced by this subgraph.
1234 // Copy those that need to be explicitly initialized into <_subgraph_object_klasses>.
1235 GrowableArray<Klass*>* recorded_klasses = info->subgraph_object_klasses();
1236 if (recorded_klasses != nullptr) {
1237 // AOT-inited classes are automatically marked as "initialized" during bootstrap. When
1238 // programmatically loading a subgraph, we only need to explicitly initialize the classes
1239 // that are not aot-inited.
1240 int num_to_copy = 0;
1241 for (int i = 0; i < recorded_klasses->length(); i++) {
1242 Klass* subgraph_k = ArchiveBuilder::get_buffered_klass(recorded_klasses->at(i));
1243 if (!subgraph_k->has_aot_initialized_mirror()) {
1244 num_to_copy ++;
1245 }
1246 }
1247
1248 _subgraph_object_klasses = ArchiveBuilder::new_ro_array<Klass*>(num_to_copy);
1249 bool is_special = (_k == ArchiveBuilder::get_buffered_klass(vmClasses::Object_klass()));
1250 for (int i = 0, n = 0; i < recorded_klasses->length(); i++) {
1251 Klass* subgraph_k = ArchiveBuilder::get_buffered_klass(recorded_klasses->at(i));
1252 if (subgraph_k->has_aot_initialized_mirror()) {
1253 continue;
1254 }
1255 if (log_is_enabled(Info, aot, heap)) {
1256 ResourceMark rm;
1257 const char* owner_name = is_special ? "<special>" : _k->external_name();
1258 if (subgraph_k->is_instance_klass()) {
1259 InstanceKlass* src_ik = InstanceKlass::cast(ArchiveBuilder::current()->get_source_addr(subgraph_k));
1260 }
1261 log_info(aot, heap)(
1262 "Archived object klass %s (%2d) => %s",
1263 owner_name, n, subgraph_k->external_name());
1264 }
1265 _subgraph_object_klasses->at_put(n, subgraph_k);
1266 ArchivePtrMarker::mark_pointer(_subgraph_object_klasses->adr_at(n));
1267 n++;
1268 }
1269 }
1270
1271 ArchivePtrMarker::mark_pointer(&_k);
1272 ArchivePtrMarker::mark_pointer(&_entry_field_records);
1273 ArchivePtrMarker::mark_pointer(&_subgraph_object_klasses);
1274 }
1275
1276 class HeapShared::CopyKlassSubGraphInfoToArchive : StackObj {
1277 CompactHashtableWriter* _writer;
1278 public:
1279 CopyKlassSubGraphInfoToArchive(CompactHashtableWriter* writer) : _writer(writer) {}
1280
1281 bool do_entry(Klass* klass, KlassSubGraphInfo& info) {
1282 if (info.subgraph_object_klasses() != nullptr || info.subgraph_entry_fields() != nullptr) {
1283 ArchivedKlassSubGraphInfoRecord* record = HeapShared::archive_subgraph_info(&info);
1284 Klass* buffered_k = ArchiveBuilder::get_buffered_klass(klass);
1285 unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary((address)buffered_k);
1286 _writer->add(hash, AOTCompressedPointers::encode_not_null(record));
1287 }
1288 return true; // keep on iterating
1289 }
1290 };
1291
1292 ArchivedKlassSubGraphInfoRecord* HeapShared::archive_subgraph_info(KlassSubGraphInfo* info) {
1293 ArchivedKlassSubGraphInfoRecord* record =
1294 (ArchivedKlassSubGraphInfoRecord*)ArchiveBuilder::ro_region_alloc(sizeof(ArchivedKlassSubGraphInfoRecord));
1295 record->init(info);
1296 if (info == _dump_time_special_subgraph) {
1297 _run_time_special_subgraph = record;
1298 }
1299 return record;
1300 }
1301
1302 // Build the records of archived subgraph infos, which include:
1303 // - Entry points to all subgraphs from the containing class mirror. The entry
1304 // points are static fields in the mirror. For each entry point, the field
1305 // offset, and value are recorded in the sub-graph
1306 // info. The value is stored back to the corresponding field at runtime.
1307 // - A list of klasses that need to be loaded/initialized before archived
1308 // java object sub-graph can be accessed at runtime.
1309 void HeapShared::write_subgraph_info_table() {
1310 // Allocate the contents of the hashtable(s) inside the RO region of the CDS archive.
1311 DumpTimeKlassSubGraphInfoTable* d_table = _dump_time_subgraph_info_table;
1312 CompactHashtableStats stats;
1313
1314 _run_time_subgraph_info_table.reset();
1315
1316 CompactHashtableWriter writer(d_table->number_of_entries(), &stats);
1317 CopyKlassSubGraphInfoToArchive copy(&writer);
1318 d_table->iterate(©);
1319 writer.dump(&_run_time_subgraph_info_table, "subgraphs");
1320
1321 #ifndef PRODUCT
1322 if (ArchiveHeapTestClass != nullptr) {
1323 size_t len = strlen(ArchiveHeapTestClass) + 1;
1324 Array<char>* array = ArchiveBuilder::new_ro_array<char>((int)len);
1325 strncpy(array->adr_at(0), ArchiveHeapTestClass, len);
1326 _archived_ArchiveHeapTestClass = array;
1327 }
1328 #endif
1329 if (log_is_enabled(Info, aot, heap)) {
1330 print_stats();
1331 }
1332 }
1333
1334 void HeapShared::serialize_tables(SerializeClosure* soc) {
1335
1336 #ifndef PRODUCT
1337 soc->do_ptr(&_archived_ArchiveHeapTestClass);
1338 if (soc->reading() && _archived_ArchiveHeapTestClass != nullptr) {
1339 _test_class_name = _archived_ArchiveHeapTestClass->adr_at(0);
1340 setup_test_class(_test_class_name);
1341 }
1342 #endif
1343
1344 _run_time_subgraph_info_table.serialize_header(soc);
1345 soc->do_ptr(&_run_time_special_subgraph);
1346 DEBUG_ONLY(soc->do_ptr(&_runtime_classes_with_cached_oops));
1347 }
1348
1349 static void verify_the_heap(Klass* k, const char* which) {
1350 if (VerifyArchivedFields > 0) {
1351 ResourceMark rm;
1352 log_info(aot, heap)("Verify heap %s initializing static field(s) in %s",
1353 which, k->external_name());
1354
1355 if (VerifyArchivedFields == 1) {
1356 VM_Verify verify_op;
1357 VMThread::execute(&verify_op);
1358 } else if (VerifyArchivedFields == 2 && is_init_completed()) {
1359 // At this time, the oop->klass() of some archived objects in the heap may not
1360 // have been loaded into the system dictionary yet. Nevertheless, oop->klass() should
1361 // have enough information (object size, oop maps, etc) so that a GC can be safely
1362 // performed.
1363 //
1364 // -XX:VerifyArchivedFields=2 force a GC to happen in such an early stage
1365 // to check for GC safety.
1366 log_info(aot, heap)("Trigger GC %s initializing static field(s) in %s",
1367 which, k->external_name());
1368 FlagSetting fs1(VerifyBeforeGC, true);
1369 FlagSetting fs2(VerifyDuringGC, true);
1370 FlagSetting fs3(VerifyAfterGC, true);
1371 Universe::heap()->collect(GCCause::_java_lang_system_gc);
1372 }
1373 }
1374 }
1375
1376 // Before GC can execute, we must ensure that all oops reachable from HeapShared::roots()
1377 // have a valid klass. I.e., oopDesc::klass() must have already been resolved.
1378 void HeapShared::resolve_classes(JavaThread* current) {
1379 assert(CDSConfig::is_using_archive(), "runtime only!");
1380 if (CDSConfig::is_using_klass_subgraphs()) {
1381 resolve_classes_for_subgraphs(current, archive_subgraph_entry_fields);
1382 }
1383 }
1384
1385 void HeapShared::resolve_classes_for_subgraphs(JavaThread* current, ArchivableStaticFieldInfo fields[]) {
1386 for (int i = 0; fields[i].valid(); i++) {
1387 ArchivableStaticFieldInfo* info = &fields[i];
1388 TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name);
1389 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name);
1390 assert(k != nullptr && k->defined_by_boot_loader(), "sanity");
1391 resolve_classes_for_subgraph_of(current, k);
1392 }
1393 }
1394
1395 void HeapShared::resolve_classes_for_subgraph_of(JavaThread* current, Klass* k) {
1396 JavaThread* THREAD = current;
1397 ExceptionMark em(THREAD);
1398 const ArchivedKlassSubGraphInfoRecord* record =
1399 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/false, THREAD);
1400 if (HAS_PENDING_EXCEPTION) {
1401 CLEAR_PENDING_EXCEPTION;
1402 }
1403 if (record == nullptr) {
1404 clear_archived_roots_of(k);
1405 }
1406 }
1407
1408 void HeapShared::initialize_java_lang_invoke(TRAPS) {
1409 if (CDSConfig::is_using_aot_linked_classes() || CDSConfig::is_dumping_method_handles()) {
1410 resolve_or_init("java/lang/invoke/Invokers$Holder", true, CHECK);
1411 resolve_or_init("java/lang/invoke/MethodHandle", true, CHECK);
1412 resolve_or_init("java/lang/invoke/MethodHandleNatives", true, CHECK);
1413 resolve_or_init("java/lang/invoke/DirectMethodHandle$Holder", true, CHECK);
1414 resolve_or_init("java/lang/invoke/DelegatingMethodHandle$Holder", true, CHECK);
1415 resolve_or_init("java/lang/invoke/LambdaForm$Holder", true, CHECK);
1416 resolve_or_init("java/lang/invoke/BoundMethodHandle$Species_L", true, CHECK);
1417 }
1418 }
1419
1420 // Initialize the InstanceKlasses of objects that are reachable from the following roots:
1421 // - interned strings
1422 // - Klass::java_mirror() -- including aot-initialized mirrors such as those of Enum klasses.
1423 // - ConstantPool::resolved_references()
1424 // - Universe::<xxx>_exception_instance()
1425 //
1426 // For example, if this enum class is initialized at AOT cache assembly time:
1427 //
1428 // enum Fruit {
1429 // APPLE, ORANGE, BANANA;
1430 // static final Set<Fruit> HAVE_SEEDS = new HashSet<>(Arrays.asList(APPLE, ORANGE));
1431 // }
1432 //
1433 // the aot-initialized mirror of Fruit has a static field that references HashSet, which
1434 // should be initialized before any Java code can access the Fruit class. Note that
1435 // HashSet itself doesn't necessary need to be an aot-initialized class.
1436 void HeapShared::init_classes_for_special_subgraph(Handle class_loader, TRAPS) {
1437 if (!is_archived_heap_in_use()) {
1438 return;
1439 }
1440
1441 assert( _run_time_special_subgraph != nullptr, "must be");
1442 Array<Klass*>* klasses = _run_time_special_subgraph->subgraph_object_klasses();
1443 if (klasses != nullptr) {
1444 for (int pass = 0; pass < 2; pass ++) {
1445 for (int i = 0; i < klasses->length(); i++) {
1446 Klass* k = klasses->at(i);
1447 if (k->class_loader_data() == nullptr) {
1448 // This class is not yet loaded. We will initialize it in a later phase.
1449 // For example, we have loaded only AOTLinkedClassCategory::BOOT1 classes
1450 // but k is part of AOTLinkedClassCategory::BOOT2.
1451 continue;
1452 }
1453 if (k->class_loader() == class_loader()) {
1454 if (pass == 0) {
1455 if (k->is_instance_klass()) {
1456 InstanceKlass::cast(k)->link_class(CHECK);
1457 }
1458 } else {
1459 resolve_or_init(k, /*do_init*/true, CHECK);
1460 }
1461 }
1462 }
1463 }
1464 }
1465 }
1466
1467 void HeapShared::initialize_from_archived_subgraph(JavaThread* current, Klass* k) {
1468 JavaThread* THREAD = current;
1469 if (!CDSConfig::is_using_klass_subgraphs()) {
1470 return; // nothing to do
1471 }
1472
1473 if (k->name()->equals("jdk/internal/module/ArchivedModuleGraph") &&
1474 !CDSConfig::is_using_optimized_module_handling() &&
1475 // archive was created with --module-path
1476 AOTClassLocationConfig::runtime()->num_module_paths() > 0) {
1477 // ArchivedModuleGraph was created with a --module-path that's different than the runtime --module-path.
1478 // Thus, it might contain references to modules that do not exist at runtime. We cannot use it.
1479 log_info(aot, heap)("Skip initializing ArchivedModuleGraph subgraph: is_using_optimized_module_handling=%s num_module_paths=%d",
1480 BOOL_TO_STR(CDSConfig::is_using_optimized_module_handling()),
1481 AOTClassLocationConfig::runtime()->num_module_paths());
1482 return;
1483 }
1484
1485 ExceptionMark em(THREAD);
1486 const ArchivedKlassSubGraphInfoRecord* record =
1487 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/true, THREAD);
1488
1489 if (HAS_PENDING_EXCEPTION) {
1490 CLEAR_PENDING_EXCEPTION;
1491 // None of the field value will be set if there was an exception when initializing the classes.
1492 // The java code will not see any of the archived objects in the
1493 // subgraphs referenced from k in this case.
1494 return;
1495 }
1496
1497 if (record != nullptr) {
1498 init_archived_fields_for(k, record);
1499 }
1500 }
1501
1502 const ArchivedKlassSubGraphInfoRecord*
1503 HeapShared::resolve_or_init_classes_for_subgraph_of(Klass* k, bool do_init, TRAPS) {
1504 assert(!CDSConfig::is_dumping_heap(), "Should not be called when dumping heap");
1505
1506 if (!k->in_aot_cache()) {
1507 return nullptr;
1508 }
1509 unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary_quick(k);
1510 const ArchivedKlassSubGraphInfoRecord* record = _run_time_subgraph_info_table.lookup(k, hash, 0);
1511
1512 #ifndef PRODUCT
1513 if (_test_class_name != nullptr && k->name()->equals(_test_class_name) && record != nullptr) {
1514 _test_class = k;
1515 _test_class_record = record;
1516 }
1517 #endif
1518
1519 // Initialize from archived data. Currently this is done only
1520 // during VM initialization time. No lock is needed.
1521 if (record == nullptr) {
1522 if (log_is_enabled(Info, aot, heap)) {
1523 ResourceMark rm(THREAD);
1524 log_info(aot, heap)("subgraph %s is not recorded",
1525 k->external_name());
1526 }
1527 return nullptr;
1528 } else {
1529 if (log_is_enabled(Info, aot, heap)) {
1530 ResourceMark rm;
1531 log_info(aot, heap)("%s subgraph %s ", do_init ? "init" : "resolve", k->external_name());
1532 }
1533
1534 Array<Klass*>* klasses = record->subgraph_object_klasses();
1535
1536 if (do_init && klasses != nullptr) {
1537 // All the classes of the oops in this subgraph are in the klasses array.
1538 // Link them first in case any of the oops are used in the <clinit> methods
1539 // invoked in the rest of this function.
1540 for (int i = 0; i < klasses->length(); i++) {
1541 Klass* klass = klasses->at(i);
1542 if (klass->in_aot_cache() && klass->is_instance_klass()) {
1543 InstanceKlass::cast(klass)->link_class(CHECK_NULL);
1544 }
1545 }
1546 }
1547
1548 resolve_or_init(k, do_init, CHECK_NULL);
1549
1550 // Load/link/initialize the klasses of the objects in the subgraph.
1551 // nullptr class loader is used.
1552 if (klasses != nullptr) {
1553 for (int i = 0; i < klasses->length(); i++) {
1554 Klass* klass = klasses->at(i);
1555 if (!klass->in_aot_cache()) {
1556 return nullptr;
1557 }
1558 resolve_or_init(klass, do_init, CHECK_NULL);
1559 }
1560 }
1561 }
1562
1563 return record;
1564 }
1565
1566 void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) {
1567 TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name);
1568 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym);
1569 if (k == nullptr) {
1570 return;
1571 }
1572 assert(k->defined_by_boot_loader(), "sanity");
1573 resolve_or_init(k, false, CHECK);
1574 if (do_init) {
1575 resolve_or_init(k, true, CHECK);
1576 }
1577 }
1578
1579 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
1580 if (!do_init) {
1581 if (k->class_loader_data() == nullptr) {
1582 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
1583 if (resolved_k->is_array_klass()) {
1584 assert(resolved_k == k || resolved_k == k->super(), "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1585 } else {
1586 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1587 }
1588 }
1589 } else {
1590 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
1591 if (k->is_instance_klass()) {
1592 InstanceKlass* ik = InstanceKlass::cast(k);
1593 ik->initialize(CHECK);
1594 } else if (k->is_objArray_klass()) {
1595 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1596 oak->initialize(CHECK);
1597 }
1598 }
1599 }
1600
1601 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1602 verify_the_heap(k, "before");
1603
1604 Array<int>* entry_field_records = record->entry_field_records();
1605 if (entry_field_records != nullptr) {
1606 int efr_len = entry_field_records->length();
1607 assert(efr_len % 2 == 0, "sanity");
1608 for (int i = 0; i < efr_len; i += 2) {
1609 int field_offset = entry_field_records->at(i);
1610 int root_index = entry_field_records->at(i+1);
1611 // Load the subgraph entry fields from the record and store them back to
1612 // the corresponding fields within the mirror.
1613 oop v = get_root(root_index, /*clear=*/true);
1614 oop m = k->java_mirror();
1615 if (k->has_aot_initialized_mirror()) {
1616 assert(v == m->obj_field(field_offset), "must be aot-initialized");
1617 } else {
1618 m->obj_field_put(field_offset, v);
1619 }
1620 log_debug(aot, heap)(" " PTR_FORMAT " init field @ %2d = " PTR_FORMAT, p2i(k), field_offset, p2i(v));
1621 }
1622
1623 // Done. Java code can see the archived sub-graphs referenced from k's
1624 // mirror after this point.
1625 if (log_is_enabled(Info, aot, heap)) {
1626 ResourceMark rm;
1627 log_info(aot, heap)("initialize_from_archived_subgraph %s " PTR_FORMAT "%s",
1628 k->external_name(), p2i(k),
1629 k->has_aot_initialized_mirror() ? " (aot-inited)" : "");
1630 }
1631 }
1632
1633 verify_the_heap(k, "after ");
1634 }
1635
1636 void HeapShared::clear_archived_roots_of(Klass* k) {
1637 unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary_quick(k);
1638 const ArchivedKlassSubGraphInfoRecord* record = _run_time_subgraph_info_table.lookup(k, hash, 0);
1639 if (record != nullptr) {
1640 Array<int>* entry_field_records = record->entry_field_records();
1641 if (entry_field_records != nullptr) {
1642 int efr_len = entry_field_records->length();
1643 assert(efr_len % 2 == 0, "sanity");
1644 for (int i = 0; i < efr_len; i += 2) {
1645 int root_index = entry_field_records->at(i+1);
1646 clear_root(root_index);
1647 }
1648 }
1649 }
1650 }
1651
1652 // Push all oop fields (or oop array elemenets in case of an objArray) in
1653 // _referencing_obj onto the _stack.
1654 class HeapShared::OopFieldPusher: public BasicOopIterateClosure {
1655 PendingOopStack* _stack;
1656 GrowableArray<oop> _found_oop_fields;
1657 int _level;
1658 bool _record_klasses_only;
1659 KlassSubGraphInfo* _subgraph_info;
1660 oop _referencing_obj;
1661 bool _is_java_lang_ref;
1662 public:
1663 OopFieldPusher(PendingOopStack* stack,
1664 int level,
1665 bool record_klasses_only,
1666 KlassSubGraphInfo* subgraph_info,
1667 oop orig) :
1668 _stack(stack),
1669 _found_oop_fields(),
1670 _level(level),
1671 _record_klasses_only(record_klasses_only),
1672 _subgraph_info(subgraph_info),
1673 _referencing_obj(orig) {
1674 _is_java_lang_ref = AOTReferenceObjSupport::check_if_ref_obj(orig);
1675 }
1676 void do_oop(narrowOop *p) { OopFieldPusher::do_oop_work(p); }
1677 void do_oop( oop *p) { OopFieldPusher::do_oop_work(p); }
1678
1679 ~OopFieldPusher() {
1680 while (_found_oop_fields.length() > 0) {
1681 // This produces the exact same traversal order as the previous version
1682 // of OopFieldPusher that recurses on the C stack -- a depth-first search,
1683 // walking the oop fields in _referencing_obj by ascending field offsets.
1684 oop obj = _found_oop_fields.pop();
1685 _stack->push(PendingOop(obj, _referencing_obj, _level + 1));
1686 }
1687 }
1688
1689 protected:
1690 template <class T> void do_oop_work(T *p) {
1691 int field_offset = pointer_delta_as_int((char*)p, cast_from_oop<char*>(_referencing_obj));
1692 oop obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(_referencing_obj, field_offset);
1693 if (obj != nullptr) {
1694 if (_is_java_lang_ref && AOTReferenceObjSupport::skip_field(field_offset)) {
1695 // Do not follow these fields. They will be cleared to null.
1696 return;
1697 }
1698
1699 if (!_record_klasses_only && log_is_enabled(Debug, aot, heap)) {
1700 ResourceMark rm;
1701 log_debug(aot, heap)("(%d) %s[%d] ==> " PTR_FORMAT " size %zu %s", _level,
1702 _referencing_obj->klass()->external_name(), field_offset,
1703 p2i(obj), obj->size() * HeapWordSize, obj->klass()->external_name());
1704 if (log_is_enabled(Trace, aot, heap)) {
1705 LogTarget(Trace, aot, heap) log;
1706 LogStream out(log);
1707 obj->print_on(&out);
1708 }
1709 }
1710
1711 _found_oop_fields.push(obj);
1712 }
1713 }
1714
1715 public:
1716 oop referencing_obj() { return _referencing_obj; }
1717 KlassSubGraphInfo* subgraph_info() { return _subgraph_info; }
1718 };
1719
1720 // Checks if an oop has any non-null oop fields
1721 class PointsToOopsChecker : public BasicOopIterateClosure {
1722 bool _result;
1723
1724 template <class T> void check(T *p) {
1725 _result |= (HeapAccess<>::oop_load(p) != nullptr);
1726 }
1727
1728 public:
1729 PointsToOopsChecker() : _result(false) {}
1730 void do_oop(narrowOop *p) { check(p); }
1731 void do_oop( oop *p) { check(p); }
1732 bool result() { return _result; }
1733 };
1734
1735 HeapShared::CachedOopInfo HeapShared::make_cached_oop_info(oop obj, oop referrer) {
1736 PointsToOopsChecker points_to_oops_checker;
1737 obj->oop_iterate(&points_to_oops_checker);
1738 return CachedOopInfo(OopHandle(Universe::vm_global(), referrer), points_to_oops_checker.result());
1739 }
1740
1741 void HeapShared::init_box_classes(TRAPS) {
1742 if (is_archived_heap_in_use()) {
1743 vmClasses::Boolean_klass()->initialize(CHECK);
1744 vmClasses::Character_klass()->initialize(CHECK);
1745 vmClasses::Float_klass()->initialize(CHECK);
1746 vmClasses::Double_klass()->initialize(CHECK);
1747 vmClasses::Byte_klass()->initialize(CHECK);
1748 vmClasses::Short_klass()->initialize(CHECK);
1749 vmClasses::Integer_klass()->initialize(CHECK);
1750 vmClasses::Long_klass()->initialize(CHECK);
1751 vmClasses::Void_klass()->initialize(CHECK);
1752 }
1753 }
1754
1755 // (1) If orig_obj has not been archived yet, archive it.
1756 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
1757 // trace all objects that are reachable from it, and make sure these objects are archived.
1758 // (3) Record the klasses of all objects that are reachable from orig_obj (including those that
1759 // were already archived when this function is called)
1760 bool HeapShared::archive_reachable_objects_from(int level,
1761 KlassSubGraphInfo* subgraph_info,
1762 oop orig_obj) {
1763 assert(orig_obj != nullptr, "must be");
1764 PendingOopStack stack;
1765 stack.push(PendingOop(orig_obj, nullptr, level));
1766
1767 while (stack.length() > 0) {
1768 PendingOop po = stack.pop();
1769 _object_being_archived = po;
1770 bool status = walk_one_object(&stack, po.level(), subgraph_info, po.obj(), po.referrer());
1771 _object_being_archived = PendingOop();
1772
1773 if (!status) {
1774 // Don't archive a subgraph root that's too big. For archives static fields, that's OK
1775 // as the Java code will take care of initializing this field dynamically.
1776 assert(level == 1, "VM should have exited with unarchivable objects for _level > 1");
1777 return false;
1778 }
1779 }
1780
1781 return true;
1782 }
1783
1784 bool HeapShared::walk_one_object(PendingOopStack* stack, int level, KlassSubGraphInfo* subgraph_info,
1785 oop orig_obj, oop referrer) {
1786 assert(orig_obj != nullptr, "must be");
1787 if (!JavaClasses::is_supported_for_archiving(orig_obj)) {
1788 // This object has injected fields that cannot be supported easily, so we disallow them for now.
1789 // If you get an error here, you probably made a change in the JDK library that has added
1790 // these objects that are referenced (directly or indirectly) by static fields.
1791 ResourceMark rm;
1792 log_error(aot, heap)("Cannot archive object " PTR_FORMAT " of class %s", p2i(orig_obj), orig_obj->klass()->external_name());
1793 debug_trace();
1794 AOTMetaspace::unrecoverable_writing_error();
1795 }
1796
1797 if (log_is_enabled(Debug, aot, heap) && java_lang_Class::is_instance(orig_obj)) {
1798 ResourceMark rm;
1799 LogTarget(Debug, aot, heap) log;
1800 LogStream out(log);
1801 out.print("Found java mirror " PTR_FORMAT " ", p2i(orig_obj));
1802 Klass* k = java_lang_Class::as_Klass(orig_obj);
1803 if (k != nullptr) {
1804 out.print("%s", k->external_name());
1805 } else {
1806 out.print("primitive");
1807 }
1808 out.print_cr("; scratch mirror = " PTR_FORMAT,
1809 p2i(scratch_java_mirror(orig_obj)));
1810 }
1811
1812 if (java_lang_Class::is_instance(orig_obj)) {
1813 orig_obj = RegeneratedClasses::maybe_get_regenerated_mirror(orig_obj);
1814 }
1815
1816 if (CDSConfig::is_dumping_aot_linked_classes()) {
1817 if (java_lang_Class::is_instance(orig_obj)) {
1818 orig_obj = scratch_java_mirror(orig_obj);
1819 assert(orig_obj != nullptr, "must be archived");
1820 }
1821 } else if (java_lang_Class::is_instance(orig_obj) && subgraph_info != _dump_time_special_subgraph) {
1822 // Without CDSConfig::is_dumping_aot_linked_classes(), we only allow archived objects to
1823 // point to the mirrors of (1) j.l.Object, (2) primitive classes, and (3) box classes. These are initialized
1824 // very early by HeapShared::init_box_classes().
1825 if (orig_obj == vmClasses::Object_klass()->java_mirror()
1826 || java_lang_Class::is_primitive(orig_obj)
1827 || orig_obj == vmClasses::Boolean_klass()->java_mirror()
1828 || orig_obj == vmClasses::Character_klass()->java_mirror()
1829 || orig_obj == vmClasses::Float_klass()->java_mirror()
1830 || orig_obj == vmClasses::Double_klass()->java_mirror()
1831 || orig_obj == vmClasses::Byte_klass()->java_mirror()
1832 || orig_obj == vmClasses::Short_klass()->java_mirror()
1833 || orig_obj == vmClasses::Integer_klass()->java_mirror()
1834 || orig_obj == vmClasses::Long_klass()->java_mirror()
1835 || orig_obj == vmClasses::Void_klass()->java_mirror()) {
1836 orig_obj = scratch_java_mirror(orig_obj);
1837 assert(orig_obj != nullptr, "must be archived");
1838 } else {
1839 // If you get an error here, you probably made a change in the JDK library that has added a Class
1840 // object that is referenced (directly or indirectly) by an ArchivableStaticFieldInfo
1841 // defined at the top of this file.
1842 log_error(aot, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
1843 debug_trace();
1844 AOTMetaspace::unrecoverable_writing_error();
1845 }
1846 }
1847
1848 if (has_been_seen_during_subgraph_recording(orig_obj)) {
1849 // orig_obj has already been archived and traced. Nothing more to do.
1850 return true;
1851 } else {
1852 set_has_been_seen_during_subgraph_recording(orig_obj);
1853 }
1854
1855 bool already_archived = has_been_archived(orig_obj);
1856 bool record_klasses_only = already_archived;
1857 if (!already_archived) {
1858 ++_num_new_archived_objs;
1859 if (!archive_object(orig_obj, referrer, subgraph_info)) {
1860 // Skip archiving the sub-graph referenced from the current entry field.
1861 ResourceMark rm;
1862 log_error(aot, heap)(
1863 "Cannot archive the sub-graph referenced from %s object ("
1864 PTR_FORMAT ") size %zu, skipped.",
1865 orig_obj->klass()->external_name(), p2i(orig_obj), orig_obj->size() * HeapWordSize);
1866 if (level == 1) {
1867 // Don't archive a subgraph root that's too big. For archives static fields, that's OK
1868 // as the Java code will take care of initializing this field dynamically.
1869 return false;
1870 } else {
1871 // We don't know how to handle an object that has been archived, but some of its reachable
1872 // objects cannot be archived. Bail out for now. We might need to fix this in the future if
1873 // we have a real use case.
1874 AOTMetaspace::unrecoverable_writing_error();
1875 }
1876 }
1877 }
1878
1879 Klass *orig_k = orig_obj->klass();
1880 subgraph_info->add_subgraph_object_klass(orig_k);
1881
1882 {
1883 // Find all the oops that are referenced by orig_obj, push them onto the stack
1884 // so we can work on them next.
1885 ResourceMark rm;
1886 OopFieldPusher pusher(stack, level, record_klasses_only, subgraph_info, orig_obj);
1887 orig_obj->oop_iterate(&pusher);
1888 }
1889
1890 if (CDSConfig::is_dumping_aot_linked_classes()) {
1891 // The enum klasses are archived with aot-initialized mirror.
1892 // See AOTClassInitializer::can_archive_initialized_mirror().
1893 } else {
1894 // This is legacy support for enum classes before JEP 483 -- we cannot rerun
1895 // the enum's <clinit> in the production run, so special handling is needed.
1896 if (CDSEnumKlass::is_enum_obj(orig_obj)) {
1897 CDSEnumKlass::handle_enum_obj(level + 1, subgraph_info, orig_obj);
1898 }
1899 }
1900
1901 return true;
1902 }
1903
1904 //
1905 // Start from the given static field in a java mirror and archive the
1906 // complete sub-graph of java heap objects that are reached directly
1907 // or indirectly from the starting object by following references.
1908 // Sub-graph archiving restrictions (current):
1909 //
1910 // - All classes of objects in the archived sub-graph (including the
1911 // entry class) must be boot class only.
1912 // - No java.lang.Class instance (java mirror) can be included inside
1913 // an archived sub-graph. Mirror can only be the sub-graph entry object.
1914 //
1915 // The Java heap object sub-graph archiving process (see OopFieldPusher):
1916 //
1917 // 1) Java object sub-graph archiving starts from a given static field
1918 // within a Class instance (java mirror). If the static field is a
1919 // reference field and points to a non-null java object, proceed to
1920 // the next step.
1921 //
1922 // 2) Archives the referenced java object. If an archived copy of the
1923 // current object already exists, updates the pointer in the archived
1924 // copy of the referencing object to point to the current archived object.
1925 // Otherwise, proceed to the next step.
1926 //
1927 // 3) Follows all references within the current java object and recursively
1928 // archive the sub-graph of objects starting from each reference.
1929 //
1930 // 4) Updates the pointer in the archived copy of referencing object to
1931 // point to the current archived object.
1932 //
1933 // 5) The Klass of the current java object is added to the list of Klasses
1934 // for loading and initializing before any object in the archived graph can
1935 // be accessed at runtime.
1936 //
1937 void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k,
1938 const char* klass_name,
1939 int field_offset,
1940 const char* field_name) {
1941 precond(CDSConfig::is_dumping_klass_subgraphs());
1942 assert(k->defined_by_boot_loader(), "must be boot class");
1943
1944 oop m = k->java_mirror();
1945
1946 KlassSubGraphInfo* subgraph_info = get_subgraph_info(k);
1947 oop f = m->obj_field(field_offset);
1948
1949 log_debug(aot, heap)("Start archiving from: %s::%s (" PTR_FORMAT ")", klass_name, field_name, p2i(f));
1950
1951 if (!CompressedOops::is_null(f)) {
1952 if (log_is_enabled(Trace, aot, heap)) {
1953 LogTarget(Trace, aot, heap) log;
1954 LogStream out(log);
1955 f->print_on(&out);
1956 }
1957
1958 bool success = archive_reachable_objects_from(1, subgraph_info, f);
1959 if (!success) {
1960 log_error(aot, heap)("Archiving failed %s::%s (some reachable objects cannot be archived)",
1961 klass_name, field_name);
1962 } else {
1963 // Note: the field value is not preserved in the archived mirror.
1964 // Record the field as a new subGraph entry point. The recorded
1965 // information is restored from the archive at runtime.
1966 subgraph_info->add_subgraph_entry_field(field_offset, f);
1967 log_info(aot, heap)("Archived field %s::%s => " PTR_FORMAT, klass_name, field_name, p2i(f));
1968 }
1969 } else {
1970 // The field contains null, we still need to record the entry point,
1971 // so it can be restored at runtime.
1972 subgraph_info->add_subgraph_entry_field(field_offset, nullptr);
1973 }
1974 }
1975
1976 #ifndef PRODUCT
1977 class VerifySharedOopClosure: public BasicOopIterateClosure {
1978 public:
1979 void do_oop(narrowOop *p) { VerifySharedOopClosure::do_oop_work(p); }
1980 void do_oop( oop *p) { VerifySharedOopClosure::do_oop_work(p); }
1981
1982 protected:
1983 template <class T> void do_oop_work(T *p) {
1984 oop obj = HeapAccess<>::oop_load(p);
1985 if (obj != nullptr) {
1986 HeapShared::verify_reachable_objects_from(obj);
1987 }
1988 }
1989 };
1990
1991 void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_offset) {
1992 precond(CDSConfig::is_dumping_klass_subgraphs());
1993 assert(k->defined_by_boot_loader(), "must be boot class");
1994
1995 oop m = k->java_mirror();
1996 oop f = m->obj_field(field_offset);
1997 if (!CompressedOops::is_null(f)) {
1998 verify_subgraph_from(f);
1999 }
2000 }
2001
2002 void HeapShared::verify_subgraph_from(oop orig_obj) {
2003 if (!has_been_archived(orig_obj)) {
2004 // It's OK for the root of a subgraph to be not archived. See comments in
2005 // archive_reachable_objects_from().
2006 return;
2007 }
2008
2009 // Verify that all objects reachable from orig_obj are archived.
2010 init_seen_objects_table();
2011 verify_reachable_objects_from(orig_obj);
2012 delete_seen_objects_table();
2013 }
2014
2015 void HeapShared::verify_reachable_objects_from(oop obj) {
2016 _num_total_verifications ++;
2017 if (java_lang_Class::is_instance(obj)) {
2018 obj = RegeneratedClasses::maybe_get_regenerated_mirror(obj);
2019 obj = scratch_java_mirror(obj);
2020 assert(obj != nullptr, "must be");
2021 }
2022 if (!has_been_seen_during_subgraph_recording(obj)) {
2023 set_has_been_seen_during_subgraph_recording(obj);
2024 assert(has_been_archived(obj), "must be");
2025 VerifySharedOopClosure walker;
2026 obj->oop_iterate(&walker);
2027 }
2028 }
2029 #endif
2030
2031 void HeapShared::check_special_subgraph_classes() {
2032 if (CDSConfig::is_dumping_aot_linked_classes()) {
2033 // We can have aot-initialized classes (such as Enums) that can reference objects
2034 // of arbitrary types. Currently, we trust the JEP 483 implementation to only
2035 // aot-initialize classes that are "safe".
2036 //
2037 // TODO: we need an automatic tool that checks the safety of aot-initialized
2038 // classes (when we extend the set of aot-initialized classes beyond JEP 483)
2039 return;
2040 } else {
2041 // In this case, the special subgraph should contain a few specific types
2042 GrowableArray<Klass*>* klasses = _dump_time_special_subgraph->subgraph_object_klasses();
2043 int num = klasses->length();
2044 for (int i = 0; i < num; i++) {
2045 Klass* subgraph_k = klasses->at(i);
2046 Symbol* name = subgraph_k->name();
2047
2048 if (subgraph_k->is_identity_class() &&
2049 name != vmSymbols::java_lang_Class() &&
2050 name != vmSymbols::java_lang_String() &&
2051 name != vmSymbols::java_lang_ArithmeticException() &&
2052 name != vmSymbols::java_lang_ArrayIndexOutOfBoundsException() &&
2053 name != vmSymbols::java_lang_ArrayStoreException() &&
2054 name != vmSymbols::java_lang_ClassCastException() &&
2055 name != vmSymbols::java_lang_InternalError() &&
2056 name != vmSymbols::java_lang_NullPointerException() &&
2057 name != vmSymbols::jdk_internal_vm_PreemptedException()) {
2058 ResourceMark rm;
2059 fatal("special subgraph cannot have objects of type %s", subgraph_k->external_name());
2060 }
2061 }
2062 }
2063 }
2064
2065 HeapShared::SeenObjectsTable* HeapShared::_seen_objects_table = nullptr;
2066 HeapShared::PendingOop HeapShared::_object_being_archived;
2067 size_t HeapShared::_num_new_walked_objs;
2068 size_t HeapShared::_num_new_archived_objs;
2069 size_t HeapShared::_num_old_recorded_klasses;
2070
2071 size_t HeapShared::_num_total_subgraph_recordings = 0;
2072 size_t HeapShared::_num_total_walked_objs = 0;
2073 size_t HeapShared::_num_total_archived_objs = 0;
2074 size_t HeapShared::_num_total_recorded_klasses = 0;
2075 size_t HeapShared::_num_total_verifications = 0;
2076
2077 bool HeapShared::has_been_seen_during_subgraph_recording(oop obj) {
2078 return _seen_objects_table->get(obj) != nullptr;
2079 }
2080
2081 void HeapShared::set_has_been_seen_during_subgraph_recording(oop obj) {
2082 assert(!has_been_seen_during_subgraph_recording(obj), "sanity");
2083 _seen_objects_table->put_when_absent(obj, true);
2084 _seen_objects_table->maybe_grow();
2085 ++ _num_new_walked_objs;
2086 }
2087
2088 void HeapShared::start_recording_subgraph(InstanceKlass *k, const char* class_name) {
2089 log_info(aot, heap)("Start recording subgraph(s) for archived fields in %s", class_name);
2090 init_subgraph_info(k);
2091 init_seen_objects_table();
2092 _num_new_walked_objs = 0;
2093 _num_new_archived_objs = 0;
2094 _num_old_recorded_klasses = get_subgraph_info(k)->num_subgraph_object_klasses();
2095 }
2096
2097 void HeapShared::done_recording_subgraph(InstanceKlass *k, const char* class_name) {
2098 size_t num_new_recorded_klasses = get_subgraph_info(k)->num_subgraph_object_klasses() -
2099 _num_old_recorded_klasses;
2100 log_info(aot, heap)("Done recording subgraph(s) for archived fields in %s: "
2101 "walked %zu objs, archived %zu new objs, recorded %zu classes",
2102 class_name, _num_new_walked_objs, _num_new_archived_objs,
2103 num_new_recorded_klasses);
2104
2105 delete_seen_objects_table();
2106
2107 _num_total_subgraph_recordings ++;
2108 _num_total_walked_objs += _num_new_walked_objs;
2109 _num_total_archived_objs += _num_new_archived_objs;
2110 _num_total_recorded_klasses += num_new_recorded_klasses;
2111 }
2112
2113 class ArchivableStaticFieldFinder: public FieldClosure {
2114 InstanceKlass* _ik;
2115 Symbol* _field_name;
2116 bool _found;
2117 int _offset;
2118 public:
2119 ArchivableStaticFieldFinder(InstanceKlass* ik, Symbol* field_name) :
2120 _ik(ik), _field_name(field_name), _found(false), _offset(-1) {}
2121
2122 virtual void do_field(fieldDescriptor* fd) {
2123 if (fd->name() == _field_name) {
2124 assert(!_found, "fields can never be overloaded");
2125 if (is_reference_type(fd->field_type())) {
2126 _found = true;
2127 _offset = fd->offset();
2128 }
2129 }
2130 }
2131 bool found() { return _found; }
2132 int offset() { return _offset; }
2133 };
2134
2135 void HeapShared::init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[],
2136 TRAPS) {
2137 for (int i = 0; fields[i].valid(); i++) {
2138 ArchivableStaticFieldInfo* info = &fields[i];
2139 TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name);
2140 TempNewSymbol field_name = SymbolTable::new_symbol(info->field_name);
2141 ResourceMark rm; // for stringStream::as_string() etc.
2142
2143 #ifndef PRODUCT
2144 bool is_test_class = (ArchiveHeapTestClass != nullptr) && (strcmp(info->klass_name, ArchiveHeapTestClass) == 0);
2145 const char* test_class_name = ArchiveHeapTestClass;
2146 #else
2147 bool is_test_class = false;
2148 const char* test_class_name = ""; // avoid C++ printf checks warnings.
2149 #endif
2150
2151 if (is_test_class) {
2152 log_warning(aot)("Loading ArchiveHeapTestClass %s ...", test_class_name);
2153 }
2154
2155 Klass* k = SystemDictionary::resolve_or_fail(klass_name, true, THREAD);
2156 if (HAS_PENDING_EXCEPTION) {
2157 CLEAR_PENDING_EXCEPTION;
2158 stringStream st;
2159 st.print("Fail to initialize archive heap: %s cannot be loaded by the boot loader", info->klass_name);
2160 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), st.as_string());
2161 }
2162
2163 if (!k->is_instance_klass()) {
2164 stringStream st;
2165 st.print("Fail to initialize archive heap: %s is not an instance class", info->klass_name);
2166 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), st.as_string());
2167 }
2168
2169 InstanceKlass* ik = InstanceKlass::cast(k);
2170 assert(InstanceKlass::cast(ik)->defined_by_boot_loader(),
2171 "Only support boot classes");
2172
2173 if (is_test_class) {
2174 if (ik->module()->is_named()) {
2175 // We don't want ArchiveHeapTestClass to be abused to easily load/initialize arbitrary
2176 // core-lib classes. You need to at least append to the bootclasspath.
2177 stringStream st;
2178 st.print("ArchiveHeapTestClass %s is not in unnamed module", test_class_name);
2179 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), st.as_string());
2180 }
2181
2182 if (ik->package() != nullptr) {
2183 // This restriction makes HeapShared::is_a_test_class_in_unnamed_module() easy.
2184 stringStream st;
2185 st.print("ArchiveHeapTestClass %s is not in unnamed package", test_class_name);
2186 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), st.as_string());
2187 }
2188 } else {
2189 if (ik->module()->name() != vmSymbols::java_base()) {
2190 // We don't want to deal with cases when a module is unavailable at runtime.
2191 // FUTURE -- load from archived heap only when module graph has not changed
2192 // between dump and runtime.
2193 stringStream st;
2194 st.print("%s is not in java.base module", info->klass_name);
2195 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), st.as_string());
2196 }
2197 }
2198
2199 if (is_test_class) {
2200 log_warning(aot)("Initializing ArchiveHeapTestClass %s ...", test_class_name);
2201 }
2202 ik->initialize(CHECK);
2203
2204 ArchivableStaticFieldFinder finder(ik, field_name);
2205 ik->do_local_static_fields(&finder);
2206 if (!finder.found()) {
2207 stringStream st;
2208 st.print("Unable to find the static T_OBJECT field %s::%s", info->klass_name, info->field_name);
2209 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), st.as_string());
2210 }
2211
2212 info->klass = ik;
2213 info->offset = finder.offset();
2214 }
2215 }
2216
2217 void HeapShared::init_subgraph_entry_fields(TRAPS) {
2218 assert(CDSConfig::is_dumping_heap(), "must be");
2219 _dump_time_subgraph_info_table = new (mtClass)DumpTimeKlassSubGraphInfoTable();
2220 if (CDSConfig::is_dumping_klass_subgraphs()) {
2221 init_subgraph_entry_fields(archive_subgraph_entry_fields, CHECK);
2222 }
2223 }
2224
2225 #ifndef PRODUCT
2226 void HeapShared::setup_test_class(const char* test_class_name) {
2227 ArchivableStaticFieldInfo* p = archive_subgraph_entry_fields;
2228 int num_slots = sizeof(archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
2229 assert(p[num_slots - 2].klass_name == nullptr, "must have empty slot that's patched below");
2230 assert(p[num_slots - 1].klass_name == nullptr, "must have empty slot that marks the end of the list");
2231
2232 if (test_class_name != nullptr) {
2233 p[num_slots - 2].klass_name = test_class_name;
2234 p[num_slots - 2].field_name = ARCHIVE_TEST_FIELD_NAME;
2235 }
2236 }
2237
2238 // See if ik is one of the test classes that are pulled in by -XX:ArchiveHeapTestClass
2239 // during runtime. This may be called before the module system is initialized so
2240 // we cannot rely on InstanceKlass::module(), etc.
2241 bool HeapShared::is_a_test_class_in_unnamed_module(Klass* ik) {
2242 if (_test_class != nullptr) {
2243 if (ik == _test_class) {
2244 return true;
2245 }
2246 Array<Klass*>* klasses = _test_class_record->subgraph_object_klasses();
2247 if (klasses == nullptr) {
2248 return false;
2249 }
2250
2251 for (int i = 0; i < klasses->length(); i++) {
2252 Klass* k = klasses->at(i);
2253 if (k == ik) {
2254 Symbol* name;
2255 if (k->is_instance_klass()) {
2256 name = InstanceKlass::cast(k)->name();
2257 } else if (k->is_objArray_klass()) {
2258 Klass* bk = ObjArrayKlass::cast(k)->bottom_klass();
2259 if (!bk->is_instance_klass()) {
2260 return false;
2261 }
2262 name = bk->name();
2263 } else {
2264 return false;
2265 }
2266
2267 // See KlassSubGraphInfo::check_allowed_klass() - we only allow test classes
2268 // to be:
2269 // (A) java.base classes (which must not be in the unnamed module)
2270 // (B) test classes which must be in the unnamed package of the unnamed module.
2271 // So if we see a '/' character in the class name, it must be in (A);
2272 // otherwise it must be in (B).
2273 if (name->index_of_at(0, "/", 1) >= 0) {
2274 return false; // (A)
2275 }
2276
2277 return true; // (B)
2278 }
2279 }
2280 }
2281
2282 return false;
2283 }
2284
2285 void HeapShared::initialize_test_class_from_archive(JavaThread* current) {
2286 Klass* k = _test_class;
2287 if (k != nullptr && is_archived_heap_in_use()) {
2288 JavaThread* THREAD = current;
2289 ExceptionMark em(THREAD);
2290 const ArchivedKlassSubGraphInfoRecord* record =
2291 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/false, THREAD);
2292
2293 // The _test_class is in the unnamed module, so it can't call CDS.initializeFromArchive()
2294 // from its <clinit> method. So we set up its "archivedObjects" field first, before
2295 // calling its <clinit>. This is not strictly clean, but it's a convenient way to write unit
2296 // test cases (see test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java).
2297 if (record != nullptr) {
2298 init_archived_fields_for(k, record);
2299 }
2300 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/true, THREAD);
2301 }
2302 }
2303 #endif
2304
2305 void HeapShared::init_for_dumping(TRAPS) {
2306 if (CDSConfig::is_dumping_heap()) {
2307 setup_test_class(ArchiveHeapTestClass);
2308 init_subgraph_entry_fields(CHECK);
2309 }
2310 }
2311
2312 void HeapShared::init_heap_writer() {
2313 if (HeapShared::is_writing_streaming_mode()) {
2314 AOTStreamedHeapWriter::init();
2315 } else {
2316 AOTMappedHeapWriter::init();
2317 }
2318 }
2319
2320 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[]) {
2321 _num_total_subgraph_recordings = 0;
2322 _num_total_walked_objs = 0;
2323 _num_total_archived_objs = 0;
2324 _num_total_recorded_klasses = 0;
2325 _num_total_verifications = 0;
2326
2327 // For each class X that has one or more archived fields:
2328 // [1] Dump the subgraph of each archived field
2329 // [2] Create a list of all the class of the objects that can be reached
2330 // by any of these static fields.
2331 // At runtime, these classes are initialized before X's archived fields
2332 // are restored by HeapShared::initialize_from_archived_subgraph().
2333 for (int i = 0; fields[i].valid(); ) {
2334 ArchivableStaticFieldInfo* info = &fields[i];
2335 const char* klass_name = info->klass_name;
2336 start_recording_subgraph(info->klass, klass_name);
2337
2338 // If you have specified consecutive fields of the same klass in
2339 // fields[], these will be archived in the same
2340 // {start_recording_subgraph ... done_recording_subgraph} pass to
2341 // save time.
2342 for (; fields[i].valid(); i++) {
2343 ArchivableStaticFieldInfo* f = &fields[i];
2344 if (f->klass_name != klass_name) {
2345 break;
2346 }
2347
2348 archive_reachable_objects_from_static_field(f->klass, f->klass_name,
2349 f->offset, f->field_name);
2350 }
2351 done_recording_subgraph(info->klass, klass_name);
2352 }
2353
2354 log_info(aot, heap)("Archived subgraph records = %zu",
2355 _num_total_subgraph_recordings);
2356 log_info(aot, heap)(" Walked %zu objects", _num_total_walked_objs);
2357 log_info(aot, heap)(" Archived %zu objects", _num_total_archived_objs);
2358 log_info(aot, heap)(" Recorded %zu klasses", _num_total_recorded_klasses);
2359
2360 #ifndef PRODUCT
2361 for (int i = 0; fields[i].valid(); i++) {
2362 ArchivableStaticFieldInfo* f = &fields[i];
2363 verify_subgraph_from_static_field(f->klass, f->offset);
2364 }
2365 log_info(aot, heap)(" Verified %zu references", _num_total_verifications);
2366 #endif
2367 }
2368
2369 bool HeapShared::is_interned_string(oop obj) {
2370 if (!java_lang_String::is_instance(obj)) {
2371 return false;
2372 }
2373
2374 ResourceMark rm;
2375 int len = 0;
2376 jchar* name = java_lang_String::as_unicode_string_or_null(obj, len);
2377 if (name == nullptr) {
2378 fatal("Insufficient memory for dumping");
2379 }
2380 return StringTable::lookup(name, len) == obj;
2381 }
2382
2383 bool HeapShared::is_dumped_interned_string(oop o) {
2384 return is_interned_string(o) && has_been_archived(o);
2385 }
2386
2387 // These tables should be used only within the CDS safepoint, so
2388 // delete them before we exit the safepoint. Otherwise the table will
2389 // contain bad oops after a GC.
2390 void HeapShared::delete_tables_with_raw_oops() {
2391 assert(_seen_objects_table == nullptr, "should have been deleted");
2392
2393 if (is_writing_mapping_mode()) {
2394 AOTMappedHeapWriter::delete_tables_with_raw_oops();
2395 } else {
2396 assert(is_writing_streaming_mode(), "what other mode?");
2397 AOTStreamedHeapWriter::delete_tables_with_raw_oops();
2398 }
2399 }
2400
2401 void HeapShared::debug_trace() {
2402 ResourceMark rm;
2403 oop referrer = _object_being_archived.referrer();
2404 if (referrer != nullptr) {
2405 LogStream ls(Log(aot, heap)::error());
2406 ls.print_cr("Reference trace");
2407 CDSHeapVerifier::trace_to_root(&ls, referrer);
2408 }
2409 }
2410
2411 #ifndef PRODUCT
2412 // At dump-time, find the location of all the non-null oop pointers in an archived heap
2413 // region. This way we can quickly relocate all the pointers without using
2414 // BasicOopIterateClosure at runtime.
2415 class FindEmbeddedNonNullPointers: public BasicOopIterateClosure {
2416 void* _start;
2417 BitMap *_oopmap;
2418 size_t _num_total_oops;
2419 size_t _num_null_oops;
2420 public:
2421 FindEmbeddedNonNullPointers(void* start, BitMap* oopmap)
2422 : _start(start), _oopmap(oopmap), _num_total_oops(0), _num_null_oops(0) {}
2423
2424 virtual void do_oop(narrowOop* p) {
2425 assert(UseCompressedOops, "sanity");
2426 _num_total_oops ++;
2427 narrowOop v = *p;
2428 if (!CompressedOops::is_null(v)) {
2429 size_t idx = p - (narrowOop*)_start;
2430 _oopmap->set_bit(idx);
2431 } else {
2432 _num_null_oops ++;
2433 }
2434 }
2435 virtual void do_oop(oop* p) {
2436 assert(!UseCompressedOops, "sanity");
2437 _num_total_oops ++;
2438 if ((*p) != nullptr) {
2439 size_t idx = p - (oop*)_start;
2440 _oopmap->set_bit(idx);
2441 } else {
2442 _num_null_oops ++;
2443 }
2444 }
2445 size_t num_total_oops() const { return _num_total_oops; }
2446 size_t num_null_oops() const { return _num_null_oops; }
2447 };
2448 #endif
2449
2450 void HeapShared::count_allocation(size_t size) {
2451 _total_obj_count ++;
2452 _total_obj_size += size;
2453 for (int i = 0; i < ALLOC_STAT_SLOTS; i++) {
2454 if (size <= (size_t(1) << i)) {
2455 _alloc_count[i] ++;
2456 _alloc_size[i] += size;
2457 return;
2458 }
2459 }
2460 }
2461
2462 static double avg_size(size_t size, size_t count) {
2463 double avg = 0;
2464 if (count > 0) {
2465 avg = double(size * HeapWordSize) / double(count);
2466 }
2467 return avg;
2468 }
2469
2470 void HeapShared::print_stats() {
2471 size_t huge_count = _total_obj_count;
2472 size_t huge_size = _total_obj_size;
2473
2474 for (int i = 0; i < ALLOC_STAT_SLOTS; i++) {
2475 size_t byte_size_limit = (size_t(1) << i) * HeapWordSize;
2476 size_t count = _alloc_count[i];
2477 size_t size = _alloc_size[i];
2478 log_info(aot, heap)("%8zu objects are <= %-6zu"
2479 " bytes (total %8zu bytes, avg %8.1f bytes)",
2480 count, byte_size_limit, size * HeapWordSize, avg_size(size, count));
2481 huge_count -= count;
2482 huge_size -= size;
2483 }
2484
2485 log_info(aot, heap)("%8zu huge objects (total %8zu bytes"
2486 ", avg %8.1f bytes)",
2487 huge_count, huge_size * HeapWordSize,
2488 avg_size(huge_size, huge_count));
2489 log_info(aot, heap)("%8zu total objects (total %8zu bytes"
2490 ", avg %8.1f bytes)",
2491 _total_obj_count, _total_obj_size * HeapWordSize,
2492 avg_size(_total_obj_size, _total_obj_count));
2493 }
2494
2495 bool HeapShared::is_metadata_field(oop src_obj, int offset) {
2496 bool result = false;
2497 do_metadata_offsets(src_obj, [&](int metadata_offset) {
2498 if (metadata_offset == offset) {
2499 result = true;
2500 }
2501 });
2502 return result;
2503 }
2504
2505 void HeapShared::remap_dumped_metadata(oop src_obj, address archived_object) {
2506 do_metadata_offsets(src_obj, [&](int offset) {
2507 Metadata** buffered_field_addr = (Metadata**)(archived_object + offset);
2508 Metadata* native_ptr = *buffered_field_addr;
2509
2510 if (native_ptr == nullptr) {
2511 return;
2512 }
2513
2514 native_ptr = RegeneratedClasses::maybe_get_regenerated_object(native_ptr);
2515
2516 address buffered_native_ptr = ArchiveBuilder::current()->get_buffered_addr((address)native_ptr);
2517 address requested_native_ptr = ArchiveBuilder::current()->to_requested(buffered_native_ptr);
2518 *buffered_field_addr = (Metadata*)requested_native_ptr;
2519 });
2520 }
2521
2522 bool HeapShared::is_archived_boot_layer_available(JavaThread* current) {
2523 TempNewSymbol klass_name = SymbolTable::new_symbol(ARCHIVED_BOOT_LAYER_CLASS);
2524 InstanceKlass* k = SystemDictionary::find_instance_klass(current, klass_name, Handle());
2525 if (k == nullptr) {
2526 return false;
2527 } else {
2528 TempNewSymbol field_name = SymbolTable::new_symbol(ARCHIVED_BOOT_LAYER_FIELD);
2529 TempNewSymbol field_signature = SymbolTable::new_symbol("Ljdk/internal/module/ArchivedBootLayer;");
2530 fieldDescriptor fd;
2531 if (k->find_field(field_name, field_signature, true, &fd) != nullptr) {
2532 oop m = k->java_mirror();
2533 oop f = m->obj_field(fd.offset());
2534 if (CompressedOops::is_null(f)) {
2535 return false;
2536 }
2537 } else {
2538 return false;
2539 }
2540 }
2541 return true;
2542 }
2543
2544 #endif // INCLUDE_CDS_JAVA_HEAP