6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "cds/archiveBuilder.hpp"
27 #include "cds/archiveHeapLoader.hpp"
28 #include "cds/archiveHeapWriter.hpp"
29 #include "cds/archiveUtils.hpp"
30 #include "cds/cdsConfig.hpp"
31 #include "cds/cdsEnumKlass.hpp"
32 #include "cds/cdsHeapVerifier.hpp"
33 #include "cds/heapShared.hpp"
34 #include "cds/metaspaceShared.hpp"
35 #include "classfile/classLoaderData.hpp"
36 #include "classfile/classLoaderExt.hpp"
37 #include "classfile/javaClasses.inline.hpp"
38 #include "classfile/modules.hpp"
39 #include "classfile/stringTable.hpp"
40 #include "classfile/symbolTable.hpp"
41 #include "classfile/systemDictionary.hpp"
42 #include "classfile/systemDictionaryShared.hpp"
43 #include "classfile/vmClasses.hpp"
44 #include "classfile/vmSymbols.hpp"
45 #include "gc/shared/collectedHeap.hpp"
68 #include "gc/g1/g1CollectedHeap.hpp"
69 #endif
70
71 #if INCLUDE_CDS_JAVA_HEAP
72
73 struct ArchivableStaticFieldInfo {
74 const char* klass_name;
75 const char* field_name;
76 InstanceKlass* klass;
77 int offset;
78 BasicType type;
79
80 ArchivableStaticFieldInfo(const char* k, const char* f)
81 : klass_name(k), field_name(f), klass(nullptr), offset(0), type(T_ILLEGAL) {}
82
83 bool valid() {
84 return klass_name != nullptr;
85 }
86 };
87
88 bool HeapShared::_disable_writing = false;
89 DumpedInternedStrings *HeapShared::_dumped_interned_strings = nullptr;
90
91 size_t HeapShared::_alloc_count[HeapShared::ALLOC_STAT_SLOTS];
92 size_t HeapShared::_alloc_size[HeapShared::ALLOC_STAT_SLOTS];
93 size_t HeapShared::_total_obj_count;
94 size_t HeapShared::_total_obj_size;
95
96 #ifndef PRODUCT
97 #define ARCHIVE_TEST_FIELD_NAME "archivedObjects"
98 static Array<char>* _archived_ArchiveHeapTestClass = nullptr;
99 static const char* _test_class_name = nullptr;
100 static const Klass* _test_class = nullptr;
101 static const ArchivedKlassSubGraphInfoRecord* _test_class_record = nullptr;
102 #endif
103
104
105 //
106 // If you add new entries to the following tables, you should know what you're doing!
107 //
108
109 static ArchivableStaticFieldInfo archive_subgraph_entry_fields[] = {
110 {"java/lang/Integer$IntegerCache", "archivedCache"},
111 {"java/lang/Long$LongCache", "archivedCache"},
112 {"java/lang/Byte$ByteCache", "archivedCache"},
113 {"java/lang/Short$ShortCache", "archivedCache"},
114 {"java/lang/Character$CharacterCache", "archivedCache"},
115 {"java/util/jar/Attributes$Name", "KNOWN_NAMES"},
116 {"sun/util/locale/BaseLocale", "constantBaseLocales"},
117 {"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"},
118 {"java/util/ImmutableCollections", "archivedObjects"},
119 {"java/lang/ModuleLayer", "EMPTY_LAYER"},
120 {"java/lang/module/Configuration", "EMPTY_CONFIGURATION"},
121 {"jdk/internal/math/FDBigInteger", "archivedCaches"},
122 #ifndef PRODUCT
123 {nullptr, nullptr}, // Extra slot for -XX:ArchiveHeapTestClass
124 #endif
125 {nullptr, nullptr},
126 };
127
128 // full module graph
129 static ArchivableStaticFieldInfo fmg_archive_subgraph_entry_fields[] = {
130 {"jdk/internal/loader/ArchivedClassLoaders", "archivedClassLoaders"},
131 {ARCHIVED_BOOT_LAYER_CLASS, ARCHIVED_BOOT_LAYER_FIELD},
132 {"java/lang/Module$ArchivedData", "archivedData"},
133 {nullptr, nullptr},
134 };
135
136 KlassSubGraphInfo* HeapShared::_default_subgraph_info;
137 GrowableArrayCHeap<oop, mtClassShared>* HeapShared::_pending_roots = nullptr;
138 GrowableArrayCHeap<OopHandle, mtClassShared>* HeapShared::_root_segments;
139 int HeapShared::_root_segment_max_size_elems;
140 OopHandle HeapShared::_scratch_basic_type_mirrors[T_VOID+1];
141 MetaspaceObjToOopHandleTable* HeapShared::_scratch_java_mirror_table = nullptr;
142 MetaspaceObjToOopHandleTable* HeapShared::_scratch_references_table = nullptr;
143
144 static bool is_subgraph_root_class_of(ArchivableStaticFieldInfo fields[], InstanceKlass* ik) {
145 for (int i = 0; fields[i].valid(); i++) {
146 if (fields[i].klass == ik) {
147 return true;
148 }
149 }
150 return false;
151 }
152
153 bool HeapShared::is_subgraph_root_class(InstanceKlass* ik) {
154 return is_subgraph_root_class_of(archive_subgraph_entry_fields, ik) ||
155 is_subgraph_root_class_of(fmg_archive_subgraph_entry_fields, ik);
156 }
157
204 vmSymbols::bootLoader_name(),
205 vmSymbols::void_BuiltinClassLoader_signature(),
206 CHECK);
207 Handle boot_loader(THREAD, result.get_oop());
208 reset_states(boot_loader(), CHECK);
209 }
210
211 HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = nullptr;
212
213 bool HeapShared::has_been_archived(oop obj) {
214 assert(CDSConfig::is_dumping_heap(), "dump-time only");
215 return archived_object_cache()->get(obj) != nullptr;
216 }
217
218 int HeapShared::append_root(oop obj) {
219 assert(CDSConfig::is_dumping_heap(), "dump-time only");
220
221 // No GC should happen since we aren't scanning _pending_roots.
222 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
223
224 if (_pending_roots == nullptr) {
225 _pending_roots = new GrowableArrayCHeap<oop, mtClassShared>(500);
226 }
227
228 return _pending_roots->append(obj);
229 }
230
231 objArrayOop HeapShared::root_segment(int segment_idx) {
232 if (CDSConfig::is_dumping_heap()) {
233 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
234 if (!HeapShared::can_write()) {
235 return nullptr;
236 }
237 } else {
238 assert(CDSConfig::is_using_archive(), "must be");
239 }
240
241 objArrayOop segment = (objArrayOop)_root_segments->at(segment_idx).resolve();
242 assert(segment != nullptr, "should have been initialized");
243 return segment;
244 }
245
246 void HeapShared::get_segment_indexes(int idx, int& seg_idx, int& int_idx) {
247 assert(_root_segment_max_size_elems > 0, "sanity");
248
249 // Try to avoid divisions for the common case.
250 if (idx < _root_segment_max_size_elems) {
251 seg_idx = 0;
252 int_idx = idx;
253 } else {
254 seg_idx = idx / _root_segment_max_size_elems;
255 int_idx = idx % _root_segment_max_size_elems;
256 }
257
258 assert(idx == seg_idx * _root_segment_max_size_elems + int_idx,
259 "sanity: %d index maps to %d segment and %d internal", idx, seg_idx, int_idx);
260 }
261
262 // Returns an objArray that contains all the roots of the archived objects
263 oop HeapShared::get_root(int index, bool clear) {
264 assert(index >= 0, "sanity");
265 assert(!CDSConfig::is_dumping_heap() && CDSConfig::is_using_archive(), "runtime only");
281 get_segment_indexes(index, seg_idx, int_idx);
282 if (log_is_enabled(Debug, cds, heap)) {
283 oop old = root_segment(seg_idx)->obj_at(int_idx);
284 log_debug(cds, heap)("Clearing root %d: was " PTR_FORMAT, index, p2i(old));
285 }
286 root_segment(seg_idx)->obj_at_put(int_idx, nullptr);
287 }
288 }
289
290 bool HeapShared::archive_object(oop obj) {
291 assert(CDSConfig::is_dumping_heap(), "dump-time only");
292
293 assert(!obj->is_stackChunk(), "do not archive stack chunks");
294 if (has_been_archived(obj)) {
295 return true;
296 }
297
298 if (ArchiveHeapWriter::is_too_large_to_archive(obj->size())) {
299 log_debug(cds, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: " SIZE_FORMAT,
300 p2i(obj), obj->size());
301 return false;
302 } else {
303 count_allocation(obj->size());
304 ArchiveHeapWriter::add_source_obj(obj);
305 CachedOopInfo info = make_cached_oop_info(obj);
306 archived_object_cache()->put_when_absent(obj, info);
307 archived_object_cache()->maybe_grow();
308 mark_native_pointers(obj);
309
310 if (log_is_enabled(Debug, cds, heap)) {
311 ResourceMark rm;
312 log_debug(cds, heap)("Archived heap object " PTR_FORMAT " : %s",
313 p2i(obj), obj->klass()->external_name());
314 }
315
316 if (java_lang_Module::is_instance(obj) && Modules::check_archived_module_oop(obj)) {
317 Modules::update_oops_in_archived_module(obj, append_root(obj));
318 }
319
320 return true;
321 }
322 }
323
324 class MetaspaceObjToOopHandleTable: public ResourceHashtable<MetaspaceObj*, OopHandle,
325 36137, // prime number
326 AnyObj::C_HEAP,
327 mtClassShared> {
328 public:
329 oop get_oop(MetaspaceObj* ptr) {
330 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
331 OopHandle* handle = get(ptr);
332 if (handle != nullptr) {
333 return handle->resolve();
335 return nullptr;
336 }
337 }
338 void set_oop(MetaspaceObj* ptr, oop o) {
339 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
340 OopHandle handle(Universe::vm_global(), o);
341 bool is_new = put(ptr, handle);
342 assert(is_new, "cannot set twice");
343 }
344 void remove_oop(MetaspaceObj* ptr) {
345 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
346 OopHandle* handle = get(ptr);
347 if (handle != nullptr) {
348 handle->release(Universe::vm_global());
349 remove(ptr);
350 }
351 }
352 };
353
354 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
355 _scratch_references_table->set_oop(src, dest);
356 }
357
358 objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
359 return (objArrayOop)_scratch_references_table->get_oop(src);
360 }
361
362 void HeapShared::init_scratch_objects(TRAPS) {
363 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
364 BasicType bt = (BasicType)i;
365 if (!is_reference_type(bt)) {
366 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
367 _scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
368 }
369 }
370 _scratch_java_mirror_table = new (mtClass)MetaspaceObjToOopHandleTable();
371 _scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable();
372 }
373
374 oop HeapShared::scratch_java_mirror(BasicType t) {
375 assert((uint)t < T_VOID+1, "range check");
376 assert(!is_reference_type(t), "sanity");
377 return _scratch_basic_type_mirrors[t].resolve();
378 }
379
380 oop HeapShared::scratch_java_mirror(Klass* k) {
381 return _scratch_java_mirror_table->get_oop(k);
382 }
383
384 void HeapShared::set_scratch_java_mirror(Klass* k, oop mirror) {
385 _scratch_java_mirror_table->set_oop(k, mirror);
386 }
387
388 void HeapShared::remove_scratch_objects(Klass* k) {
389 _scratch_java_mirror_table->remove_oop(k);
390 if (k->is_instance_klass()) {
391 _scratch_references_table->remove(InstanceKlass::cast(k)->constants());
392 }
393 }
394
395 void HeapShared::archive_java_mirrors() {
396 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
397 BasicType bt = (BasicType)i;
398 if (!is_reference_type(bt)) {
399 oop m = _scratch_basic_type_mirrors[i].resolve();
400 assert(m != nullptr, "sanity");
401 bool success = archive_reachable_objects_from(1, _default_subgraph_info, m);
402 assert(success, "sanity");
403
404 log_trace(cds, heap, mirror)(
405 "Archived %s mirror object from " PTR_FORMAT,
406 type2name(bt), p2i(m));
407
408 Universe::set_archived_basic_type_mirror_index(bt, append_root(m));
409 }
410 }
411
412 GrowableArray<Klass*>* klasses = ArchiveBuilder::current()->klasses();
413 assert(klasses != nullptr, "sanity");
414 for (int i = 0; i < klasses->length(); i++) {
415 Klass* orig_k = klasses->at(i);
416 oop m = scratch_java_mirror(orig_k);
417 if (m != nullptr) {
418 Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k);
419 bool success = archive_reachable_objects_from(1, _default_subgraph_info, m);
420 guarantee(success, "scratch mirrors must point to only archivable objects");
421 buffered_k->set_archived_java_mirror(append_root(m));
422 ResourceMark rm;
423 log_trace(cds, heap, mirror)(
424 "Archived %s mirror object from " PTR_FORMAT,
425 buffered_k->external_name(), p2i(m));
426
427 // archive the resolved_referenes array
428 if (buffered_k->is_instance_klass()) {
429 InstanceKlass* ik = InstanceKlass::cast(buffered_k);
430 oop rr = ik->constants()->prepare_resolved_references_for_archiving();
431 if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) {
432 bool success = HeapShared::archive_reachable_objects_from(1, _default_subgraph_info, rr);
433 assert(success, "must be");
434 int root_index = append_root(rr);
435 ik->constants()->cache()->set_archived_references(root_index);
442 void HeapShared::archive_strings() {
443 oop shared_strings_array = StringTable::init_shared_table(_dumped_interned_strings);
444 bool success = archive_reachable_objects_from(1, _default_subgraph_info, shared_strings_array);
445 // We must succeed because:
446 // - _dumped_interned_strings do not contain any large strings.
447 // - StringTable::init_shared_table() doesn't create any large arrays.
448 assert(success, "shared strings array must not point to arrays or strings that are too large to archive");
449 StringTable::set_shared_strings_array_index(append_root(shared_strings_array));
450 }
451
452 int HeapShared::archive_exception_instance(oop exception) {
453 bool success = archive_reachable_objects_from(1, _default_subgraph_info, exception);
454 assert(success, "sanity");
455 return append_root(exception);
456 }
457
458 void HeapShared::mark_native_pointers(oop orig_obj) {
459 if (java_lang_Class::is_instance(orig_obj)) {
460 ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::klass_offset());
461 ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::array_klass_offset());
462 }
463 }
464
465 void HeapShared::get_pointer_info(oop src_obj, bool& has_oop_pointers, bool& has_native_pointers) {
466 CachedOopInfo* info = archived_object_cache()->get(src_obj);
467 assert(info != nullptr, "must be");
468 has_oop_pointers = info->has_oop_pointers();
469 has_native_pointers = info->has_native_pointers();
470 }
471
472 void HeapShared::set_has_native_pointers(oop src_obj) {
473 CachedOopInfo* info = archived_object_cache()->get(src_obj);
474 assert(info != nullptr, "must be");
475 info->set_has_native_pointers();
476 }
477
478 void HeapShared::archive_objects(ArchiveHeapInfo *heap_info) {
479 {
480 NoSafepointVerifier nsv;
481
482 _default_subgraph_info = init_subgraph_info(vmClasses::Object_klass(), false);
483
484 // Cache for recording where the archived objects are copied to
485 create_archived_object_cache();
486
487 if (UseCompressedOops || UseG1GC) {
488 log_info(cds)("Heap range = [" PTR_FORMAT " - " PTR_FORMAT "]",
489 UseCompressedOops ? p2i(CompressedOops::begin()) :
490 p2i((address)G1CollectedHeap::heap()->reserved().start()),
491 UseCompressedOops ? p2i(CompressedOops::end()) :
492 p2i((address)G1CollectedHeap::heap()->reserved().end()));
493 }
494 copy_objects();
495
496 CDSHeapVerifier::verify();
497 check_default_subgraph_classes();
498 }
499
500 ArchiveHeapWriter::write(_pending_roots, heap_info);
501 }
502
503 void HeapShared::copy_interned_strings() {
504 init_seen_objects_table();
505
506 auto copier = [&] (oop s, bool value_ignored) {
507 assert(s != nullptr, "sanity");
508 assert(!ArchiveHeapWriter::is_string_too_large_to_archive(s), "large strings must have been filtered");
509 bool success = archive_reachable_objects_from(1, _default_subgraph_info, s);
510 assert(success, "must be");
511 // Prevent string deduplication from changing the value field to
512 // something not in the archive.
513 java_lang_String::set_deduplication_forbidden(s);
514 };
515 _dumped_interned_strings->iterate_all(copier);
516
517 delete_seen_objects_table();
518 }
519
520 void HeapShared::copy_special_objects() {
583 // Add the Klass* for an object in the current KlassSubGraphInfo's subgraphs.
584 // Only objects of boot classes can be included in sub-graph.
585 void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) {
586 assert(CDSConfig::is_dumping_heap(), "dump time only");
587 Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k);
588
589 if (_subgraph_object_klasses == nullptr) {
590 _subgraph_object_klasses =
591 new (mtClass) GrowableArray<Klass*>(50, mtClass);
592 }
593
594 assert(ArchiveBuilder::current()->is_in_buffer_space(buffered_k), "must be a shared class");
595
596 if (_k == buffered_k) {
597 // Don't add the Klass containing the sub-graph to it's own klass
598 // initialization list.
599 return;
600 }
601
602 if (buffered_k->is_instance_klass()) {
603 assert(InstanceKlass::cast(buffered_k)->is_shared_boot_class(),
604 "must be boot class");
605 // vmClasses::xxx_klass() are not updated, need to check
606 // the original Klass*
607 if (orig_k == vmClasses::String_klass() ||
608 orig_k == vmClasses::Object_klass()) {
609 // Initialized early during VM initialization. No need to be added
610 // to the sub-graph object class list.
611 return;
612 }
613 check_allowed_klass(InstanceKlass::cast(orig_k));
614 } else if (buffered_k->is_objArray_klass()) {
615 Klass* abk = ObjArrayKlass::cast(buffered_k)->bottom_klass();
616 if (abk->is_instance_klass()) {
617 assert(InstanceKlass::cast(abk)->is_shared_boot_class(),
618 "must be boot class");
619 check_allowed_klass(InstanceKlass::cast(ObjArrayKlass::cast(orig_k)->bottom_klass()));
620 }
621 if (buffered_k == Universe::objectArrayKlass()) {
622 // Initialized early during Universe::genesis. No need to be added
623 // to the list.
624 return;
625 }
626 } else {
627 assert(buffered_k->is_typeArray_klass(), "must be");
628 // Primitive type arrays are created early during Universe::genesis.
629 return;
630 }
631
632 if (log_is_enabled(Debug, cds, heap)) {
633 if (!_subgraph_object_klasses->contains(buffered_k)) {
634 ResourceMark rm;
635 log_debug(cds, heap)("Adding klass %s", orig_k->external_name());
636 }
637 }
638
639 _subgraph_object_klasses->append_if_missing(buffered_k);
640 _has_non_early_klasses |= is_non_early_klass(orig_k);
641 }
642
643 void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) {
644 if (ik->module()->name() == vmSymbols::java_base()) {
645 assert(ik->package() != nullptr, "classes in java.base cannot be in unnamed package");
646 return;
647 }
648
649 #ifndef PRODUCT
650 if (!ik->module()->is_named() && ik->package() == nullptr) {
651 // This class is loaded by ArchiveHeapTestClass
652 return;
653 }
654 const char* extra_msg = ", or in an unnamed package of an unnamed module";
655 #else
656 const char* extra_msg = "";
657 #endif
658
659 ResourceMark rm;
660 log_error(cds, heap)("Class %s not allowed in archive heap. Must be in java.base%s",
661 ik->external_name(), extra_msg);
662 MetaspaceShared::unrecoverable_writing_error();
663 }
721 _subgraph_object_klasses =
722 ArchiveBuilder::new_ro_array<Klass*>(num_subgraphs_klasses);
723 for (int i = 0; i < num_subgraphs_klasses; i++) {
724 Klass* subgraph_k = subgraph_object_klasses->at(i);
725 if (log_is_enabled(Info, cds, heap)) {
726 ResourceMark rm;
727 log_info(cds, heap)(
728 "Archived object klass %s (%2d) => %s",
729 _k->external_name(), i, subgraph_k->external_name());
730 }
731 _subgraph_object_klasses->at_put(i, subgraph_k);
732 ArchivePtrMarker::mark_pointer(_subgraph_object_klasses->adr_at(i));
733 }
734 }
735
736 ArchivePtrMarker::mark_pointer(&_k);
737 ArchivePtrMarker::mark_pointer(&_entry_field_records);
738 ArchivePtrMarker::mark_pointer(&_subgraph_object_klasses);
739 }
740
741 struct CopyKlassSubGraphInfoToArchive : StackObj {
742 CompactHashtableWriter* _writer;
743 CopyKlassSubGraphInfoToArchive(CompactHashtableWriter* writer) : _writer(writer) {}
744
745 bool do_entry(Klass* klass, KlassSubGraphInfo& info) {
746 if (info.subgraph_object_klasses() != nullptr || info.subgraph_entry_fields() != nullptr) {
747 ArchivedKlassSubGraphInfoRecord* record =
748 (ArchivedKlassSubGraphInfoRecord*)ArchiveBuilder::ro_region_alloc(sizeof(ArchivedKlassSubGraphInfoRecord));
749 record->init(&info);
750
751 Klass* buffered_k = ArchiveBuilder::get_buffered_klass(klass);
752 unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary((address)buffered_k);
753 u4 delta = ArchiveBuilder::current()->any_to_offset_u4(record);
754 _writer->add(hash, delta);
755 }
756 return true; // keep on iterating
757 }
758 };
759
760 // Build the records of archived subgraph infos, which include:
761 // - Entry points to all subgraphs from the containing class mirror. The entry
762 // points are static fields in the mirror. For each entry point, the field
763 // offset, and value are recorded in the sub-graph
764 // info. The value is stored back to the corresponding field at runtime.
765 // - A list of klasses that need to be loaded/initialized before archived
766 // java object sub-graph can be accessed at runtime.
767 void HeapShared::write_subgraph_info_table() {
768 // Allocate the contents of the hashtable(s) inside the RO region of the CDS archive.
769 DumpTimeKlassSubGraphInfoTable* d_table = _dump_time_subgraph_info_table;
770 CompactHashtableStats stats;
771
772 _run_time_subgraph_info_table.reset();
773
774 CompactHashtableWriter writer(d_table->_count, &stats);
775 CopyKlassSubGraphInfoToArchive copy(&writer);
776 d_table->iterate(©);
777 writer.dump(&_run_time_subgraph_info_table, "subgraphs");
778
779 #ifndef PRODUCT
796 _root_segments = new GrowableArrayCHeap<OopHandle, mtClassShared>(10);
797 }
798 _root_segments->push(OopHandle(Universe::vm_global(), segment_oop));
799 }
800
801 void HeapShared::init_root_segment_sizes(int max_size_elems) {
802 _root_segment_max_size_elems = max_size_elems;
803 }
804
805 void HeapShared::serialize_tables(SerializeClosure* soc) {
806
807 #ifndef PRODUCT
808 soc->do_ptr(&_archived_ArchiveHeapTestClass);
809 if (soc->reading() && _archived_ArchiveHeapTestClass != nullptr) {
810 _test_class_name = _archived_ArchiveHeapTestClass->adr_at(0);
811 setup_test_class(_test_class_name);
812 }
813 #endif
814
815 _run_time_subgraph_info_table.serialize_header(soc);
816 }
817
818 static void verify_the_heap(Klass* k, const char* which) {
819 if (VerifyArchivedFields > 0) {
820 ResourceMark rm;
821 log_info(cds, heap)("Verify heap %s initializing static field(s) in %s",
822 which, k->external_name());
823
824 VM_Verify verify_op;
825 VMThread::execute(&verify_op);
826
827 if (VerifyArchivedFields > 1 && is_init_completed()) {
828 // At this time, the oop->klass() of some archived objects in the heap may not
829 // have been loaded into the system dictionary yet. Nevertheless, oop->klass() should
830 // have enough information (object size, oop maps, etc) so that a GC can be safely
831 // performed.
832 //
833 // -XX:VerifyArchivedFields=2 force a GC to happen in such an early stage
834 // to check for GC safety.
835 log_info(cds, heap)("Trigger GC %s initializing static field(s) in %s",
836 which, k->external_name());
837 FlagSetting fs1(VerifyBeforeGC, true);
838 FlagSetting fs2(VerifyDuringGC, true);
839 FlagSetting fs3(VerifyAfterGC, true);
840 Universe::heap()->collect(GCCause::_java_lang_system_gc);
841 }
842 }
843 }
844
845 // Before GC can execute, we must ensure that all oops reachable from HeapShared::roots()
846 // have a valid klass. I.e., oopDesc::klass() must have already been resolved.
847 //
848 // Note: if a ArchivedKlassSubGraphInfoRecord contains non-early classes, and JVMTI
849 // ClassFileLoadHook is enabled, it's possible for this class to be dynamically replaced. In
850 // this case, we will not load the ArchivedKlassSubGraphInfoRecord and will clear its roots.
851 void HeapShared::resolve_classes(JavaThread* current) {
852 assert(CDSConfig::is_using_archive(), "runtime only!");
853 if (!ArchiveHeapLoader::is_in_use()) {
854 return; // nothing to do
855 }
856 resolve_classes_for_subgraphs(current, archive_subgraph_entry_fields);
857 resolve_classes_for_subgraphs(current, fmg_archive_subgraph_entry_fields);
858 }
859
860 void HeapShared::resolve_classes_for_subgraphs(JavaThread* current, ArchivableStaticFieldInfo fields[]) {
861 for (int i = 0; fields[i].valid(); i++) {
862 ArchivableStaticFieldInfo* info = &fields[i];
863 TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name);
864 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name);
865 assert(k != nullptr && k->is_shared_boot_class(), "sanity");
866 resolve_classes_for_subgraph_of(current, k);
867 }
868 }
869
870 void HeapShared::resolve_classes_for_subgraph_of(JavaThread* current, Klass* k) {
871 JavaThread* THREAD = current;
872 ExceptionMark em(THREAD);
873 const ArchivedKlassSubGraphInfoRecord* record =
874 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/false, THREAD);
875 if (HAS_PENDING_EXCEPTION) {
876 CLEAR_PENDING_EXCEPTION;
877 }
878 if (record == nullptr) {
879 clear_archived_roots_of(k);
880 }
881 }
882
883 void HeapShared::initialize_from_archived_subgraph(JavaThread* current, Klass* k) {
884 JavaThread* THREAD = current;
885 if (!ArchiveHeapLoader::is_in_use()) {
886 return; // nothing to do
887 }
888
889 if (k->name()->equals("jdk/internal/module/ArchivedModuleGraph") &&
890 !CDSConfig::is_using_optimized_module_handling() &&
891 // archive was created with --module-path
892 ClassLoaderExt::num_module_paths() > 0) {
893 // ArchivedModuleGraph was created with a --module-path that's different than the runtime --module-path.
894 // Thus, it might contain references to modules that do not exist at runtime. We cannot use it.
895 log_info(cds, heap)("Skip initializing ArchivedModuleGraph subgraph: is_using_optimized_module_handling=%s num_module_paths=%d",
896 BOOL_TO_STR(CDSConfig::is_using_optimized_module_handling()), ClassLoaderExt::num_module_paths());
897 return;
898 }
899
900 ExceptionMark em(THREAD);
901 const ArchivedKlassSubGraphInfoRecord* record =
902 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/true, THREAD);
966
967 resolve_or_init(k, do_init, CHECK_NULL);
968
969 // Load/link/initialize the klasses of the objects in the subgraph.
970 // nullptr class loader is used.
971 Array<Klass*>* klasses = record->subgraph_object_klasses();
972 if (klasses != nullptr) {
973 for (int i = 0; i < klasses->length(); i++) {
974 Klass* klass = klasses->at(i);
975 if (!klass->is_shared()) {
976 return nullptr;
977 }
978 resolve_or_init(klass, do_init, CHECK_NULL);
979 }
980 }
981 }
982
983 return record;
984 }
985
986 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
987 if (!do_init) {
988 if (k->class_loader_data() == nullptr) {
989 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
990 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
991 }
992 } else {
993 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
994 if (k->is_instance_klass()) {
995 InstanceKlass* ik = InstanceKlass::cast(k);
996 ik->initialize(CHECK);
997 } else if (k->is_objArray_klass()) {
998 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
999 oak->initialize(CHECK);
1000 }
1001 }
1002 }
1003
1004 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1005 verify_the_heap(k, "before");
1113
1114 template <class T> void check(T *p) {
1115 _result |= (HeapAccess<>::oop_load(p) != nullptr);
1116 }
1117
1118 public:
1119 PointsToOopsChecker() : _result(false) {}
1120 void do_oop(narrowOop *p) { check(p); }
1121 void do_oop( oop *p) { check(p); }
1122 bool result() { return _result; }
1123 };
1124
1125 HeapShared::CachedOopInfo HeapShared::make_cached_oop_info(oop obj) {
1126 WalkOopAndArchiveClosure* walker = WalkOopAndArchiveClosure::current();
1127 oop referrer = (walker == nullptr) ? nullptr : walker->referencing_obj();
1128 PointsToOopsChecker points_to_oops_checker;
1129 obj->oop_iterate(&points_to_oops_checker);
1130 return CachedOopInfo(referrer, points_to_oops_checker.result());
1131 }
1132
1133 // (1) If orig_obj has not been archived yet, archive it.
1134 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
1135 // trace all objects that are reachable from it, and make sure these objects are archived.
1136 // (3) Record the klasses of all orig_obj and all reachable objects.
1137 bool HeapShared::archive_reachable_objects_from(int level,
1138 KlassSubGraphInfo* subgraph_info,
1139 oop orig_obj) {
1140 assert(orig_obj != nullptr, "must be");
1141
1142 if (!JavaClasses::is_supported_for_archiving(orig_obj)) {
1143 // This object has injected fields that cannot be supported easily, so we disallow them for now.
1144 // If you get an error here, you probably made a change in the JDK library that has added
1145 // these objects that are referenced (directly or indirectly) by static fields.
1146 ResourceMark rm;
1147 log_error(cds, heap)("Cannot archive object of class %s", orig_obj->klass()->external_name());
1148 if (log_is_enabled(Trace, cds, heap)) {
1149 WalkOopAndArchiveClosure* walker = WalkOopAndArchiveClosure::current();
1150 if (walker != nullptr) {
1151 LogStream ls(Log(cds, heap)::trace());
1152 CDSHeapVerifier::trace_to_root(&ls, walker->referencing_obj());
1153 }
1154 }
1155 MetaspaceShared::unrecoverable_writing_error();
1156 }
1157
1158 // java.lang.Class instances cannot be included in an archived object sub-graph. We only support
1159 // them as Klass::_archived_mirror because they need to be specially restored at run time.
1160 //
1161 // If you get an error here, you probably made a change in the JDK library that has added a Class
1162 // object that is referenced (directly or indirectly) by static fields.
1163 if (java_lang_Class::is_instance(orig_obj) && subgraph_info != _default_subgraph_info) {
1164 log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
1165 MetaspaceShared::unrecoverable_writing_error();
1166 }
1167
1168 if (has_been_seen_during_subgraph_recording(orig_obj)) {
1169 // orig_obj has already been archived and traced. Nothing more to do.
1170 return true;
1171 } else {
1172 set_has_been_seen_during_subgraph_recording(orig_obj);
1173 }
1174
1175 bool already_archived = has_been_archived(orig_obj);
1176 bool record_klasses_only = already_archived;
1177 if (!already_archived) {
1178 ++_num_new_archived_objs;
1179 if (!archive_object(orig_obj)) {
1180 // Skip archiving the sub-graph referenced from the current entry field.
1181 ResourceMark rm;
1182 log_error(cds, heap)(
1183 "Cannot archive the sub-graph referenced from %s object ("
1184 PTR_FORMAT ") size " SIZE_FORMAT ", skipped.",
1185 orig_obj->klass()->external_name(), p2i(orig_obj), orig_obj->size() * HeapWordSize);
1186 if (level == 1) {
1187 // Don't archive a subgraph root that's too big. For archives static fields, that's OK
1188 // as the Java code will take care of initializing this field dynamically.
1189 return false;
1190 } else {
1191 // We don't know how to handle an object that has been archived, but some of its reachable
1192 // objects cannot be archived. Bail out for now. We might need to fix this in the future if
1193 // we have a real use case.
1194 MetaspaceShared::unrecoverable_writing_error();
1195 }
1196 }
1197 }
1198
1199 Klass *orig_k = orig_obj->klass();
1200 subgraph_info->add_subgraph_object_klass(orig_k);
1201
1202 WalkOopAndArchiveClosure walker(level, record_klasses_only, subgraph_info, orig_obj);
1203 orig_obj->oop_iterate(&walker);
1204
1205 if (CDSEnumKlass::is_enum_obj(orig_obj)) {
1206 CDSEnumKlass::handle_enum_obj(level + 1, subgraph_info, orig_obj);
1207 }
1208 return true;
1209 }
1210
1211 //
1212 // Start from the given static field in a java mirror and archive the
1213 // complete sub-graph of java heap objects that are reached directly
1214 // or indirectly from the starting object by following references.
1215 // Sub-graph archiving restrictions (current):
1216 //
1217 // - All classes of objects in the archived sub-graph (including the
1218 // entry class) must be boot class only.
1219 // - No java.lang.Class instance (java mirror) can be included inside
1220 // an archived sub-graph. Mirror can only be the sub-graph entry object.
1221 //
1222 // The Java heap object sub-graph archiving process (see
1223 // WalkOopAndArchiveClosure):
1224 //
1225 // 1) Java object sub-graph archiving starts from a given static field
1226 // within a Class instance (java mirror). If the static field is a
1227 // reference field and points to a non-null java object, proceed to
1305 if (!CompressedOops::is_null(f)) {
1306 verify_subgraph_from(f);
1307 }
1308 }
1309
1310 void HeapShared::verify_subgraph_from(oop orig_obj) {
1311 if (!has_been_archived(orig_obj)) {
1312 // It's OK for the root of a subgraph to be not archived. See comments in
1313 // archive_reachable_objects_from().
1314 return;
1315 }
1316
1317 // Verify that all objects reachable from orig_obj are archived.
1318 init_seen_objects_table();
1319 verify_reachable_objects_from(orig_obj);
1320 delete_seen_objects_table();
1321 }
1322
1323 void HeapShared::verify_reachable_objects_from(oop obj) {
1324 _num_total_verifications ++;
1325 if (!has_been_seen_during_subgraph_recording(obj)) {
1326 set_has_been_seen_during_subgraph_recording(obj);
1327 assert(has_been_archived(obj), "must be");
1328 VerifySharedOopClosure walker;
1329 obj->oop_iterate(&walker);
1330 }
1331 }
1332 #endif
1333
1334 // The "default subgraph" contains special objects (see heapShared.hpp) that
1335 // can be accessed before we load any Java classes (including java/lang/Class).
1336 // Make sure that these are only instances of the very few specific types
1337 // that we can handle.
1338 void HeapShared::check_default_subgraph_classes() {
1339 GrowableArray<Klass*>* klasses = _default_subgraph_info->subgraph_object_klasses();
1340 int num = klasses->length();
1341 for (int i = 0; i < num; i++) {
1342 Klass* subgraph_k = klasses->at(i);
1343 if (log_is_enabled(Info, cds, heap)) {
1344 ResourceMark rm;
1345 log_info(cds, heap)(
1346 "Archived object klass (default subgraph %d) => %s",
1347 i, subgraph_k->external_name());
1348 }
1349
1350 Symbol* name = ArchiveBuilder::current()->get_source_addr(subgraph_k->name());
1351 guarantee(name == vmSymbols::java_lang_Class() ||
1352 name == vmSymbols::java_lang_String() ||
1353 name == vmSymbols::java_lang_ArithmeticException() ||
1354 name == vmSymbols::java_lang_NullPointerException() ||
1355 name == vmSymbols::java_lang_InternalError() ||
1356 name == vmSymbols::java_lang_ArrayIndexOutOfBoundsException() ||
1357 name == vmSymbols::java_lang_ArrayStoreException() ||
1358 name == vmSymbols::java_lang_ClassCastException() ||
1359 name == vmSymbols::object_array_signature() ||
1360 name == vmSymbols::byte_array_signature() ||
1361 name == vmSymbols::char_array_signature(),
1362 "default subgraph can have only these objects");
1363 }
1364 }
1365
1366 HeapShared::SeenObjectsTable* HeapShared::_seen_objects_table = nullptr;
1367 int HeapShared::_num_new_walked_objs;
1368 int HeapShared::_num_new_archived_objs;
1369 int HeapShared::_num_old_recorded_klasses;
1370
1371 int HeapShared::_num_total_subgraph_recordings = 0;
1372 int HeapShared::_num_total_walked_objs = 0;
1373 int HeapShared::_num_total_archived_objs = 0;
1374 int HeapShared::_num_total_recorded_klasses = 0;
1375 int HeapShared::_num_total_verifications = 0;
1376
1377 bool HeapShared::has_been_seen_during_subgraph_recording(oop obj) {
1378 return _seen_objects_table->get(obj) != nullptr;
1379 }
1380
1381 void HeapShared::set_has_been_seen_during_subgraph_recording(oop obj) {
1382 assert(!has_been_seen_during_subgraph_recording(obj), "sanity");
1565 return false;
1566 }
1567
1568 // See KlassSubGraphInfo::check_allowed_klass() - only two types of
1569 // classes are allowed:
1570 // (A) java.base classes (which must not be in the unnamed module)
1571 // (B) test classes which must be in the unnamed package of the unnamed module.
1572 // So if we see a '/' character in the class name, it must be in (A);
1573 // otherwise it must be in (B).
1574 if (name->index_of_at(0, "/", 1) >= 0) {
1575 return false; // (A)
1576 }
1577
1578 return true; // (B)
1579 }
1580 }
1581 }
1582
1583 return false;
1584 }
1585 #endif
1586
1587 void HeapShared::init_for_dumping(TRAPS) {
1588 if (HeapShared::can_write()) {
1589 setup_test_class(ArchiveHeapTestClass);
1590 _dumped_interned_strings = new (mtClass)DumpedInternedStrings(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE);
1591 init_subgraph_entry_fields(CHECK);
1592 }
1593 }
1594
1595 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
1596 bool is_full_module_graph) {
1597 _num_total_subgraph_recordings = 0;
1598 _num_total_walked_objs = 0;
1599 _num_total_archived_objs = 0;
1600 _num_total_recorded_klasses = 0;
1601 _num_total_verifications = 0;
1602
1603 // For each class X that has one or more archived fields:
1604 // [1] Dump the subgraph of each archived field
1605 // [2] Create a list of all the class of the objects that can be reached
1606 // by any of these static fields.
1607 // At runtime, these classes are initialized before X's archived fields
1608 // are restored by HeapShared::initialize_from_archived_subgraph().
1609 for (int i = 0; fields[i].valid(); ) {
1610 ArchivableStaticFieldInfo* info = &fields[i];
1611 const char* klass_name = info->klass_name;
1612 start_recording_subgraph(info->klass, klass_name, is_full_module_graph);
1613
1614 // If you have specified consecutive fields of the same klass in
1615 // fields[], these will be archived in the same
1616 // {start_recording_subgraph ... done_recording_subgraph} pass to
1617 // save time.
1618 for (; fields[i].valid(); i++) {
1619 ArchivableStaticFieldInfo* f = &fields[i];
1620 if (f->klass_name != klass_name) {
1621 break;
1622 }
1623
1624 archive_reachable_objects_from_static_field(f->klass, f->klass_name,
1625 f->offset, f->field_name);
1626 }
1627 done_recording_subgraph(info->klass, klass_name);
1628 }
1629
1630 log_info(cds, heap)("Archived subgraph records = %d",
1631 _num_total_subgraph_recordings);
1632 log_info(cds, heap)(" Walked %d objects", _num_total_walked_objs);
1633 log_info(cds, heap)(" Archived %d objects", _num_total_archived_objs);
1634 log_info(cds, heap)(" Recorded %d klasses", _num_total_recorded_klasses);
1635
1636 #ifndef PRODUCT
1637 for (int i = 0; fields[i].valid(); i++) {
1638 ArchivableStaticFieldInfo* f = &fields[i];
1639 verify_subgraph_from_static_field(f->klass, f->offset);
1640 }
1641 log_info(cds, heap)(" Verified %d references", _num_total_verifications);
1642 #endif
1643 }
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "cds/aotClassInitializer.hpp"
27 #include "cds/archiveBuilder.hpp"
28 #include "cds/archiveHeapLoader.hpp"
29 #include "cds/archiveHeapWriter.hpp"
30 #include "cds/archiveUtils.hpp"
31 #include "cds/cdsConfig.hpp"
32 #include "cds/cdsEnumKlass.hpp"
33 #include "cds/cdsHeapVerifier.hpp"
34 #include "cds/heapShared.hpp"
35 #include "cds/metaspaceShared.hpp"
36 #include "classfile/classLoaderData.hpp"
37 #include "classfile/classLoaderExt.hpp"
38 #include "classfile/javaClasses.inline.hpp"
39 #include "classfile/modules.hpp"
40 #include "classfile/stringTable.hpp"
41 #include "classfile/symbolTable.hpp"
42 #include "classfile/systemDictionary.hpp"
43 #include "classfile/systemDictionaryShared.hpp"
44 #include "classfile/vmClasses.hpp"
45 #include "classfile/vmSymbols.hpp"
46 #include "gc/shared/collectedHeap.hpp"
69 #include "gc/g1/g1CollectedHeap.hpp"
70 #endif
71
72 #if INCLUDE_CDS_JAVA_HEAP
73
74 struct ArchivableStaticFieldInfo {
75 const char* klass_name;
76 const char* field_name;
77 InstanceKlass* klass;
78 int offset;
79 BasicType type;
80
81 ArchivableStaticFieldInfo(const char* k, const char* f)
82 : klass_name(k), field_name(f), klass(nullptr), offset(0), type(T_ILLEGAL) {}
83
84 bool valid() {
85 return klass_name != nullptr;
86 }
87 };
88
89 class HeapShared::ArchivingObjectMark : public StackObj {
90 public:
91 ArchivingObjectMark(oop obj) {
92 _trace->push(obj);
93 }
94 ~ArchivingObjectMark() {
95 _trace->pop();
96 }
97 };
98
99 class HeapShared::ContextMark : public StackObj {
100 ResourceMark rm;
101 public:
102 ContextMark(const char* c) : rm{} {
103 _context->push(c);
104 }
105 ~ContextMark() {
106 _context->pop();
107 }
108 };
109
110 bool HeapShared::_disable_writing = false;
111 DumpedInternedStrings *HeapShared::_dumped_interned_strings = nullptr;
112
113 size_t HeapShared::_alloc_count[HeapShared::ALLOC_STAT_SLOTS];
114 size_t HeapShared::_alloc_size[HeapShared::ALLOC_STAT_SLOTS];
115 size_t HeapShared::_total_obj_count;
116 size_t HeapShared::_total_obj_size;
117
118 #ifndef PRODUCT
119 #define ARCHIVE_TEST_FIELD_NAME "archivedObjects"
120 static Array<char>* _archived_ArchiveHeapTestClass = nullptr;
121 static const char* _test_class_name = nullptr;
122 static Klass* _test_class = nullptr;
123 static const ArchivedKlassSubGraphInfoRecord* _test_class_record = nullptr;
124 #endif
125
126
127 //
128 // If you add new entries to the following tables, you should know what you're doing!
129 //
130
131 static ArchivableStaticFieldInfo archive_subgraph_entry_fields[] = {
132 {"java/lang/Integer$IntegerCache", "archivedCache"},
133 {"java/lang/Long$LongCache", "archivedCache"},
134 {"java/lang/Byte$ByteCache", "archivedCache"},
135 {"java/lang/Short$ShortCache", "archivedCache"},
136 {"java/lang/Character$CharacterCache", "archivedCache"},
137 {"java/util/jar/Attributes$Name", "KNOWN_NAMES"},
138 {"sun/util/locale/BaseLocale", "constantBaseLocales"},
139 {"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"},
140 {"java/util/ImmutableCollections", "archivedObjects"},
141 {"java/lang/ModuleLayer", "EMPTY_LAYER"},
142 {"java/lang/module/Configuration", "EMPTY_CONFIGURATION"},
143 {"jdk/internal/math/FDBigInteger", "archivedCaches"},
144 {"java/lang/reflect/Proxy$ProxyBuilder", "archivedData"}, // FIXME -- requires AOTClassLinking
145
146 #ifndef PRODUCT
147 {nullptr, nullptr}, // Extra slot for -XX:ArchiveHeapTestClass
148 #endif
149 {nullptr, nullptr},
150 };
151
152 // full module graph
153 static ArchivableStaticFieldInfo fmg_archive_subgraph_entry_fields[] = {
154 {"jdk/internal/loader/ArchivedClassLoaders", "archivedClassLoaders"},
155 {ARCHIVED_BOOT_LAYER_CLASS, ARCHIVED_BOOT_LAYER_FIELD},
156 {"java/lang/Module$ArchivedData", "archivedData"},
157 {nullptr, nullptr},
158 };
159
160 KlassSubGraphInfo* HeapShared::_default_subgraph_info;
161 ArchivedKlassSubGraphInfoRecord* HeapShared::_runtime_default_subgraph_info;
162 GrowableArrayCHeap<OopHandle, mtClassShared>* HeapShared::_pending_roots = nullptr;
163 GrowableArrayCHeap<oop, mtClassShared>* HeapShared::_trace = nullptr;
164 GrowableArrayCHeap<const char*, mtClassShared>* HeapShared::_context = nullptr;
165 GrowableArrayCHeap<OopHandle, mtClassShared>* HeapShared::_root_segments;
166 int HeapShared::_root_segment_max_size_elems;
167 OopHandle HeapShared::_scratch_basic_type_mirrors[T_VOID+1];
168 MetaspaceObjToOopHandleTable* HeapShared::_scratch_java_mirror_table = nullptr;
169 MetaspaceObjToOopHandleTable* HeapShared::_scratch_references_table = nullptr;
170
171 static bool is_subgraph_root_class_of(ArchivableStaticFieldInfo fields[], InstanceKlass* ik) {
172 for (int i = 0; fields[i].valid(); i++) {
173 if (fields[i].klass == ik) {
174 return true;
175 }
176 }
177 return false;
178 }
179
180 bool HeapShared::is_subgraph_root_class(InstanceKlass* ik) {
181 return is_subgraph_root_class_of(archive_subgraph_entry_fields, ik) ||
182 is_subgraph_root_class_of(fmg_archive_subgraph_entry_fields, ik);
183 }
184
231 vmSymbols::bootLoader_name(),
232 vmSymbols::void_BuiltinClassLoader_signature(),
233 CHECK);
234 Handle boot_loader(THREAD, result.get_oop());
235 reset_states(boot_loader(), CHECK);
236 }
237
238 HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = nullptr;
239
240 bool HeapShared::has_been_archived(oop obj) {
241 assert(CDSConfig::is_dumping_heap(), "dump-time only");
242 return archived_object_cache()->get(obj) != nullptr;
243 }
244
245 int HeapShared::append_root(oop obj) {
246 assert(CDSConfig::is_dumping_heap(), "dump-time only");
247
248 // No GC should happen since we aren't scanning _pending_roots.
249 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
250
251 if (UsePermanentHeapObjects && obj != nullptr) {
252 int n = get_archived_object_permanent_index_locked(obj);
253 assert(n >= 0, "must have been added");
254 return n;
255 }
256
257 if (_pending_roots == nullptr) {
258 _pending_roots = new GrowableArrayCHeap<OopHandle, mtClassShared>(500);
259 }
260
261 OopHandle oh(Universe::vm_global(), obj);
262 return _pending_roots->append(oh);
263 }
264
265 objArrayOop HeapShared::root_segment(int segment_idx) {
266 if (CDSConfig::is_dumping_heap() && !CDSConfig::is_dumping_final_static_archive()) {
267 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
268 if (!HeapShared::can_write()) {
269 return nullptr;
270 }
271 } else {
272 assert(CDSConfig::is_using_archive(), "must be");
273 }
274
275 objArrayOop segment = (objArrayOop)_root_segments->at(segment_idx).resolve();
276 assert(segment != nullptr, "should have been initialized");
277 return segment;
278 }
279
280 inline unsigned int oop_handle_hash(const OopHandle& oh) {
281 oop o = oh.resolve();
282 if (o == nullptr) {
283 return 0;
284 } else {
285 return o->identity_hash();
286 }
287 }
288
289 inline bool oop_handle_equals(const OopHandle& a, const OopHandle& b) {
290 return a.resolve() == b.resolve();
291 }
292
293 class OrigToScratchObjectTable: public ResourceHashtable<OopHandle, OopHandle,
294 36137, // prime number
295 AnyObj::C_HEAP,
296 mtClassShared,
297 oop_handle_hash,
298 oop_handle_equals> {};
299
300 static OrigToScratchObjectTable* _orig_to_scratch_object_table = nullptr;
301
302 void HeapShared::track_scratch_object(oop orig_obj, oop scratch_obj) {
303 MutexLocker ml(ArchivedObjectTables_lock, Mutex::_no_safepoint_check_flag);
304 if (_orig_to_scratch_object_table == nullptr) {
305 _orig_to_scratch_object_table = new (mtClass)OrigToScratchObjectTable();
306 }
307
308 OopHandle orig_h(Universe::vm_global(), orig_obj);
309 OopHandle scratch_h(Universe::vm_global(), scratch_obj);
310 _orig_to_scratch_object_table->put_when_absent(orig_h, scratch_h);
311 }
312
313 oop HeapShared::orig_to_scratch_object(oop orig_obj) {
314 MutexLocker ml(ArchivedObjectTables_lock, Mutex::_no_safepoint_check_flag);
315 if (_orig_to_scratch_object_table != nullptr) {
316 OopHandle orig(&orig_obj);
317 OopHandle* v = _orig_to_scratch_object_table->get(orig);
318 if (v != nullptr) {
319 return v->resolve();
320 }
321 }
322 return nullptr;
323 }
324
325 class ArchivedObjectPermanentIndexTable: public ResourceHashtable<OopHandle, int,
326 36137, // prime number
327 AnyObj::C_HEAP,
328 mtClassShared,
329 oop_handle_hash,
330 oop_handle_equals> {};
331
332 static ArchivedObjectPermanentIndexTable* _permanent_index_table = nullptr;
333
334 void HeapShared::add_to_permanent_index_table(oop obj) {
335 assert_locked_or_safepoint(ArchivedObjectTables_lock);
336
337 assert(CDSConfig::is_dumping_heap(), "must be");
338 if (UsePermanentHeapObjects) {
339 if (_permanent_index_table == nullptr) {
340 _permanent_index_table = new (mtClass)ArchivedObjectPermanentIndexTable();
341 }
342 if (_pending_roots == nullptr) {
343 _pending_roots = new GrowableArrayCHeap<OopHandle, mtClassShared>(500);
344 }
345
346 if (_orig_to_scratch_object_table != nullptr) {
347 OopHandle orig(&obj);
348 OopHandle* v = _orig_to_scratch_object_table->get(orig);
349 if (v != nullptr) {
350 obj = v->resolve();
351 }
352 }
353
354 OopHandle oh(Universe::vm_global(), obj);
355 int index = _pending_roots->append(oh);
356 _permanent_index_table->put_when_absent(oh, index);
357 }
358 }
359
360 int HeapShared::get_archived_object_permanent_index(oop obj) {
361 MutexLocker ml(ArchivedObjectTables_lock, Mutex::_no_safepoint_check_flag);
362 return get_archived_object_permanent_index_locked(obj);
363 }
364
365 // Can be called in the "old" workflow.
366 int HeapShared::get_archived_object_permanent_index_locked(oop obj) {
367 assert_locked_or_safepoint(ArchivedObjectTables_lock);
368 if (!UsePermanentHeapObjects) {
369 return -1;
370 }
371 if (!CDSConfig::is_dumping_heap() && !ArchiveHeapLoader::is_in_use()) {
372 return -1;
373 }
374
375 if (_permanent_index_table == nullptr) {
376 if (!ArchiveHeapLoader::is_in_use()) {
377 // Called in the old workflow
378 return -1;
379 } else {
380 _permanent_index_table = new (mtClass)ArchivedObjectPermanentIndexTable();
381 int count = 0;
382 for (int segment_idx = 0; segment_idx < _root_segments->length(); segment_idx++) {
383 objArrayOop segment = (objArrayOop)_root_segments->at(segment_idx).resolve();
384 for (int i = 0; i < segment->length(); i++, count++) {
385 oop root = segment->obj_at(i);
386 if (root != nullptr) {
387 OopHandle tmp(Universe::vm_global(), root);
388 int index = count;
389 _permanent_index_table->put_when_absent(tmp, index);
390 }
391 }
392 }
393 }
394 }
395
396 if (_orig_to_scratch_object_table != nullptr) {
397 OopHandle orig(&obj);
398 OopHandle* v = _orig_to_scratch_object_table->get(orig);
399 if (v != nullptr) {
400 obj = v->resolve();
401 }
402 }
403
404 OopHandle tmp(&obj);
405 int* v = _permanent_index_table->get(tmp);
406 if (v != nullptr) {
407 int n = *v;
408 return n;
409 }
410
411 return -1;
412 }
413
414 oop HeapShared::get_archived_object(int permanent_index) {
415 if (ArchiveHeapLoader::is_in_use()) {
416 return get_root(permanent_index);
417 } else {
418 assert(CDSConfig::is_dumping_heap(), "must be");
419 if (_pending_roots != nullptr) {
420 return _pending_roots->at(permanent_index).resolve();
421 } else {
422 return nullptr;
423 }
424 }
425 }
426
427 void HeapShared::get_segment_indexes(int idx, int& seg_idx, int& int_idx) {
428 assert(_root_segment_max_size_elems > 0, "sanity");
429
430 // Try to avoid divisions for the common case.
431 if (idx < _root_segment_max_size_elems) {
432 seg_idx = 0;
433 int_idx = idx;
434 } else {
435 seg_idx = idx / _root_segment_max_size_elems;
436 int_idx = idx % _root_segment_max_size_elems;
437 }
438
439 assert(idx == seg_idx * _root_segment_max_size_elems + int_idx,
440 "sanity: %d index maps to %d segment and %d internal", idx, seg_idx, int_idx);
441 }
442
443 // Returns an objArray that contains all the roots of the archived objects
444 oop HeapShared::get_root(int index, bool clear) {
445 assert(index >= 0, "sanity");
446 assert(!CDSConfig::is_dumping_heap() && CDSConfig::is_using_archive(), "runtime only");
462 get_segment_indexes(index, seg_idx, int_idx);
463 if (log_is_enabled(Debug, cds, heap)) {
464 oop old = root_segment(seg_idx)->obj_at(int_idx);
465 log_debug(cds, heap)("Clearing root %d: was " PTR_FORMAT, index, p2i(old));
466 }
467 root_segment(seg_idx)->obj_at_put(int_idx, nullptr);
468 }
469 }
470
471 bool HeapShared::archive_object(oop obj) {
472 assert(CDSConfig::is_dumping_heap(), "dump-time only");
473
474 assert(!obj->is_stackChunk(), "do not archive stack chunks");
475 if (has_been_archived(obj)) {
476 return true;
477 }
478
479 if (ArchiveHeapWriter::is_too_large_to_archive(obj->size())) {
480 log_debug(cds, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: " SIZE_FORMAT,
481 p2i(obj), obj->size());
482 debug_trace();
483 return false;
484 } else {
485 add_to_permanent_index_table(obj);
486 count_allocation(obj->size());
487 ArchiveHeapWriter::add_source_obj(obj);
488 CachedOopInfo info = make_cached_oop_info(obj);
489 archived_object_cache()->put_when_absent(obj, info);
490 archived_object_cache()->maybe_grow();
491 mark_native_pointers(obj);
492
493 if (log_is_enabled(Debug, cds, heap)) {
494 ResourceMark rm;
495 LogTarget(Debug, cds, heap) log;
496 LogStream out(log);
497 out.print("Archived heap object " PTR_FORMAT " : %s ",
498 p2i(obj), obj->klass()->external_name());
499 if (java_lang_Class::is_instance(obj)) {
500 Klass* k = java_lang_Class::as_Klass(obj);
501 if (k != nullptr) {
502 out.print("%s", k->external_name());
503 } else {
504 out.print("primitive");
505 }
506 }
507 out.cr();
508 }
509
510 if (java_lang_Module::is_instance(obj) && Modules::check_archived_module_oop(obj)) {
511 Modules::update_oops_in_archived_module(obj, append_root(obj));
512 }
513
514 return true;
515 }
516 }
517
518 class MetaspaceObjToOopHandleTable: public ResourceHashtable<MetaspaceObj*, OopHandle,
519 36137, // prime number
520 AnyObj::C_HEAP,
521 mtClassShared> {
522 public:
523 oop get_oop(MetaspaceObj* ptr) {
524 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
525 OopHandle* handle = get(ptr);
526 if (handle != nullptr) {
527 return handle->resolve();
529 return nullptr;
530 }
531 }
532 void set_oop(MetaspaceObj* ptr, oop o) {
533 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
534 OopHandle handle(Universe::vm_global(), o);
535 bool is_new = put(ptr, handle);
536 assert(is_new, "cannot set twice");
537 }
538 void remove_oop(MetaspaceObj* ptr) {
539 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
540 OopHandle* handle = get(ptr);
541 if (handle != nullptr) {
542 handle->release(Universe::vm_global());
543 remove(ptr);
544 }
545 }
546 };
547
548 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
549 if (_scratch_references_table == nullptr) {
550 _scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable();
551 }
552 _scratch_references_table->set_oop(src, dest);
553 }
554
555 objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
556 return (objArrayOop)_scratch_references_table->get_oop(src);
557 }
558
559 void HeapShared::init_scratch_objects(TRAPS) {
560 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
561 BasicType bt = (BasicType)i;
562 if (!is_reference_type(bt)) {
563 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
564 _scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
565 track_scratch_object(Universe::java_mirror(bt), m);
566 }
567 }
568 _scratch_java_mirror_table = new (mtClass)MetaspaceObjToOopHandleTable();
569 if (_scratch_references_table == nullptr) {
570 _scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable();
571 }
572 }
573
574 // Given java_mirror that represents a (primitive or reference) type T,
575 // return the "scratch" version that represents the same type T.
576 // Note that if java_mirror will be returned if it's already a
577 // scratch mirror.
578 //
579 // See java_lang_Class::create_scratch_mirror() for more info.
580 oop HeapShared::scratch_java_mirror(oop java_mirror) {
581 assert(java_lang_Class::is_instance(java_mirror), "must be");
582
583 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
584 BasicType bt = (BasicType)i;
585 if (!is_reference_type(bt)) {
586 if (_scratch_basic_type_mirrors[i].resolve() == java_mirror) {
587 return java_mirror;
588 }
589 }
590 }
591
592 if (java_lang_Class::is_primitive(java_mirror)) {
593 return scratch_java_mirror(java_lang_Class::as_BasicType(java_mirror));
594 } else {
595 return scratch_java_mirror(java_lang_Class::as_Klass(java_mirror));
596 }
597 }
598
599 oop HeapShared::scratch_java_mirror(BasicType t) {
600 assert((uint)t < T_VOID+1, "range check");
601 assert(!is_reference_type(t), "sanity");
602 return _scratch_basic_type_mirrors[t].resolve();
603 }
604
605 oop HeapShared::scratch_java_mirror(Klass* k) {
606 return _scratch_java_mirror_table->get_oop(k);
607 }
608
609 void HeapShared::set_scratch_java_mirror(Klass* k, oop mirror) {
610 track_scratch_object(k->java_mirror(), mirror);
611 _scratch_java_mirror_table->set_oop(k, mirror);
612 }
613
614 void HeapShared::remove_scratch_objects(Klass* k) {
615 _scratch_java_mirror_table->remove_oop(k);
616 if (k->is_instance_klass()) {
617 _scratch_references_table->remove(InstanceKlass::cast(k)->constants());
618 }
619 oop mirror = k->java_mirror();
620 if (mirror != nullptr) {
621 OopHandle tmp(&mirror);
622 OopHandle* v = _orig_to_scratch_object_table->get(tmp);
623 if (v != nullptr) {
624 oop scratch_mirror = v->resolve();
625 java_lang_Class::set_klass(scratch_mirror, nullptr);
626 _orig_to_scratch_object_table->remove(tmp);
627 }
628 }
629 }
630
631 bool HeapShared::is_lambda_form_klass(InstanceKlass* ik) {
632 return ik->is_hidden() &&
633 (ik->name()->starts_with("java/lang/invoke/LambdaForm$MH+") ||
634 ik->name()->starts_with("java/lang/invoke/LambdaForm$DMH+") ||
635 ik->name()->starts_with("java/lang/invoke/LambdaForm$BMH+"));
636 }
637
638 bool HeapShared::is_lambda_proxy_klass(InstanceKlass* ik) {
639 return ik->is_hidden() && (ik->name()->index_of_at(0, "$$Lambda+", 9) > 0);
640 }
641
642 bool HeapShared::is_archivable_hidden_klass(InstanceKlass* ik) {
643 return CDSConfig::is_dumping_invokedynamic() && (is_lambda_form_klass(ik) || is_lambda_proxy_klass(ik));
644 }
645
646 void HeapShared::copy_aot_initialized_mirror(Klass* orig_k, oop orig_mirror, oop m) {
647 if (!orig_k->is_instance_klass()) {
648 return;
649 }
650 InstanceKlass* ik = InstanceKlass::cast(orig_k);
651
652 if (HeapShared::is_archivable_hidden_klass(ik)) {
653 // We can't rerun the <clinit> method of hidden classes as we don't save
654 // the classData, so we must archive its mirror in initialized state.
655 assert(ik->is_initialized(), "must be");
656 }
657
658 if (!ik->is_initialized() || !AOTClassInitializer::can_archive_initialized_mirror(ik)) {
659 return;
660 }
661
662 int nfields = 0;
663 for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {
664 if (fs.access_flags().is_static()) {
665 fieldDescriptor& fd = fs.field_descriptor();
666 int offset = fd.offset();
667 switch (fd.field_type()) {
668 case T_OBJECT:
669 case T_ARRAY:
670 m->obj_field_put(offset, orig_mirror->obj_field(offset));
671 break;
672 case T_BOOLEAN:
673 m->bool_field_put(offset, orig_mirror->bool_field(offset));
674 break;
675 case T_BYTE:
676 m->byte_field_put(offset, orig_mirror->byte_field(offset));
677 break;
678 case T_SHORT:
679 m->short_field_put(offset, orig_mirror->short_field(offset));
680 break;
681 case T_CHAR:
682 m->char_field_put(offset, orig_mirror->char_field(offset));
683 break;
684 case T_INT:
685 m->int_field_put(offset, orig_mirror->int_field(offset));
686 break;
687 case T_LONG:
688 m->long_field_put(offset, orig_mirror->long_field(offset));
689 break;
690 case T_FLOAT:
691 m->float_field_put(offset, orig_mirror->float_field(offset));
692 break;
693 case T_DOUBLE:
694 m->double_field_put(offset, orig_mirror->double_field(offset));
695 break;
696 default:
697 ShouldNotReachHere();
698 }
699 nfields ++;
700 }
701 }
702
703 java_lang_Class::set_class_data(m, java_lang_Class::class_data(orig_mirror));
704
705 // Class::reflectData use SoftReference, which cannot be archived. Set it
706 // to null and it will be recreated at runtime.
707 java_lang_Class::set_reflection_data(m, nullptr);
708
709 if (log_is_enabled(Info, cds, init)) {
710 ResourceMark rm;
711 log_debug(cds, init)("copied %3d field(s) in preinitialized mirror %s%s", nfields, ik->external_name(),
712 ik->is_hidden() ? " (hidden)" : "");
713 }
714
715 InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(ik);
716 buffered_ik->set_has_preinitialized_mirror();
717 }
718
719 static void copy_java_mirror_hashcode(oop orig_mirror, oop scratch_m) {
720 int src_hash = orig_mirror->identity_hash();
721 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
722 assert(scratch_m->mark().is_unlocked(), "sanity");
723
724 DEBUG_ONLY(int archived_hash = scratch_m->identity_hash());
725 assert(src_hash == archived_hash, "Java mirror wrong hash: original %x, scratch %x", src_hash, archived_hash);
726 }
727
728 void HeapShared::archive_java_mirrors() {
729 AOTClassInitializer::reset_preinit_check();
730
731 _orig_to_scratch_object_table->iterate([&](OopHandle o, OopHandle s) {
732 copy_java_mirror_hashcode(o.resolve(), s.resolve());
733 return true;
734 });
735
736 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
737 BasicType bt = (BasicType)i;
738 if (!is_reference_type(bt)) {
739 oop orig_mirror = Universe::java_mirror(bt);
740 oop m = _scratch_basic_type_mirrors[i].resolve();
741 assert(m != nullptr, "sanity");
742 bool success = archive_reachable_objects_from(1, _default_subgraph_info, m);
743 assert(success, "sanity");
744
745 log_trace(cds, heap, mirror)(
746 "Archived %s mirror object from " PTR_FORMAT,
747 type2name(bt), p2i(m));
748
749 Universe::set_archived_basic_type_mirror_index(bt, append_root(m));
750 }
751 }
752
753 GrowableArray<Klass*>* klasses = ArchiveBuilder::current()->klasses();
754 assert(klasses != nullptr, "sanity");
755
756 for (int i = 0; i < klasses->length(); i++) {
757 Klass* orig_k = klasses->at(i);
758 oop orig_mirror = orig_k->java_mirror();
759 oop m = scratch_java_mirror(orig_k);
760 if (m != nullptr) {
761 copy_aot_initialized_mirror(orig_k, orig_mirror, m);
762 if (CDSConfig::is_dumping_reflection_data() && java_lang_Class::has_reflection_data(orig_mirror)) {
763 oop reflection_data = java_lang_Class::reflection_data(orig_mirror);
764 bool success = archive_reachable_objects_from(1, _default_subgraph_info, reflection_data);
765 guarantee(success, "");
766 java_lang_Class::set_reflection_data(m, reflection_data);
767 }
768 }
769 }
770
771 for (int i = 0; i < klasses->length(); i++) {
772 Klass* orig_k = klasses->at(i);
773 oop orig_mirror = orig_k->java_mirror();
774 oop m = scratch_java_mirror(orig_k);
775 if (m != nullptr) {
776 Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k);
777 bool success = archive_reachable_objects_from(1, _default_subgraph_info, m);
778 guarantee(success, "scratch mirrors must point to only archivable objects");
779 buffered_k->set_archived_java_mirror(append_root(m));
780 ResourceMark rm;
781 log_trace(cds, heap, mirror)(
782 "Archived %s mirror object from " PTR_FORMAT,
783 buffered_k->external_name(), p2i(m));
784
785 // archive the resolved_referenes array
786 if (buffered_k->is_instance_klass()) {
787 InstanceKlass* ik = InstanceKlass::cast(buffered_k);
788 oop rr = ik->constants()->prepare_resolved_references_for_archiving();
789 if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) {
790 bool success = HeapShared::archive_reachable_objects_from(1, _default_subgraph_info, rr);
791 assert(success, "must be");
792 int root_index = append_root(rr);
793 ik->constants()->cache()->set_archived_references(root_index);
800 void HeapShared::archive_strings() {
801 oop shared_strings_array = StringTable::init_shared_table(_dumped_interned_strings);
802 bool success = archive_reachable_objects_from(1, _default_subgraph_info, shared_strings_array);
803 // We must succeed because:
804 // - _dumped_interned_strings do not contain any large strings.
805 // - StringTable::init_shared_table() doesn't create any large arrays.
806 assert(success, "shared strings array must not point to arrays or strings that are too large to archive");
807 StringTable::set_shared_strings_array_index(append_root(shared_strings_array));
808 }
809
810 int HeapShared::archive_exception_instance(oop exception) {
811 bool success = archive_reachable_objects_from(1, _default_subgraph_info, exception);
812 assert(success, "sanity");
813 return append_root(exception);
814 }
815
816 void HeapShared::mark_native_pointers(oop orig_obj) {
817 if (java_lang_Class::is_instance(orig_obj)) {
818 ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::klass_offset());
819 ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::array_klass_offset());
820 } else if (java_lang_invoke_ResolvedMethodName::is_instance(orig_obj)) {
821 ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_invoke_ResolvedMethodName::vmtarget_offset());
822 }
823 }
824
825 void HeapShared::get_pointer_info(oop src_obj, bool& has_oop_pointers, bool& has_native_pointers) {
826 CachedOopInfo* info = archived_object_cache()->get(src_obj);
827 assert(info != nullptr, "must be");
828 has_oop_pointers = info->has_oop_pointers();
829 has_native_pointers = info->has_native_pointers();
830 }
831
832 void HeapShared::set_has_native_pointers(oop src_obj) {
833 CachedOopInfo* info = archived_object_cache()->get(src_obj);
834 assert(info != nullptr, "must be");
835 info->set_has_native_pointers();
836 }
837
838 void HeapShared::start_finding_archivable_hidden_classes() {
839 NoSafepointVerifier nsv;
840
841 init_seen_objects_table();
842
843 find_archivable_hidden_classes_helper(archive_subgraph_entry_fields);
844 if (CDSConfig::is_dumping_full_module_graph()) {
845 find_archivable_hidden_classes_helper(fmg_archive_subgraph_entry_fields);
846 }
847 }
848
849 void HeapShared::end_finding_archivable_hidden_classes() {
850 NoSafepointVerifier nsv;
851
852 delete_seen_objects_table();
853 }
854
855 void HeapShared::find_archivable_hidden_classes_helper(ArchivableStaticFieldInfo fields[]) {
856 if (!CDSConfig::is_dumping_heap()) {
857 return;
858 }
859 for (int i = 0; fields[i].valid(); ) {
860 ArchivableStaticFieldInfo* info = &fields[i];
861 const char* klass_name = info->klass_name;
862 for (; fields[i].valid(); i++) {
863 ArchivableStaticFieldInfo* f = &fields[i];
864 if (f->klass_name != klass_name) {
865 break;
866 }
867
868 InstanceKlass* k = f->klass;
869 oop m = k->java_mirror();
870 oop o = m->obj_field(f->offset);
871 if (o != nullptr) {
872 find_archivable_hidden_classes_in_object(o);
873 }
874 }
875 }
876 }
877
878 class HeapShared::FindHiddenClassesOopClosure: public BasicOopIterateClosure {
879 GrowableArray<oop> _stack;
880 template <class T> void do_oop_work(T *p) {
881 // Recurse on a GrowableArray to avoid overflowing the C stack.
882 oop o = RawAccess<>::oop_load(p);
883 if (o != nullptr) {
884 _stack.append(o);
885 }
886 }
887
888 public:
889
890 void do_oop(narrowOop *p) { FindHiddenClassesOopClosure::do_oop_work(p); }
891 void do_oop( oop *p) { FindHiddenClassesOopClosure::do_oop_work(p); }
892
893 FindHiddenClassesOopClosure(oop o) {
894 _stack.append(o);
895 }
896 oop pop() {
897 if (_stack.length() == 0) {
898 return nullptr;
899 } else {
900 return _stack.pop();
901 }
902 }
903 };
904
905 void HeapShared::find_archivable_hidden_classes_in_object(oop root) {
906 ResourceMark rm;
907 FindHiddenClassesOopClosure c(root);
908 oop o;
909 while ((o = c.pop()) != nullptr) {
910 if (!has_been_seen_during_subgraph_recording(o)) {
911 set_has_been_seen_during_subgraph_recording(o);
912
913 if (java_lang_Class::is_instance(o)) {
914 Klass* k = java_lang_Class::as_Klass(o);
915 if (k != nullptr && k->is_instance_klass()) {
916 SystemDictionaryShared::mark_required_class(InstanceKlass::cast(k));
917 }
918 } else if (java_lang_invoke_ResolvedMethodName::is_instance(o)) {
919 Method* m = java_lang_invoke_ResolvedMethodName::vmtarget(o);
920 if (m != nullptr && m->method_holder() != nullptr) {
921 SystemDictionaryShared::mark_required_class(m->method_holder());
922 }
923 }
924
925 o->oop_iterate(&c);
926 }
927 }
928 }
929
930 void HeapShared::archive_objects(ArchiveHeapInfo *heap_info) {
931 {
932 NoSafepointVerifier nsv;
933
934 _default_subgraph_info = init_subgraph_info(vmClasses::Object_klass(), false);
935 _trace = new GrowableArrayCHeap<oop, mtClassShared>(250);
936 _context = new GrowableArrayCHeap<const char*, mtClassShared>(250);
937
938 // Cache for recording where the archived objects are copied to
939 create_archived_object_cache();
940
941 if (UseCompressedOops || UseG1GC) {
942 log_info(cds)("Heap range = [" PTR_FORMAT " - " PTR_FORMAT "]",
943 UseCompressedOops ? p2i(CompressedOops::begin()) :
944 p2i((address)G1CollectedHeap::heap()->reserved().start()),
945 UseCompressedOops ? p2i(CompressedOops::end()) :
946 p2i((address)G1CollectedHeap::heap()->reserved().end()));
947 }
948 copy_objects();
949
950 if (!SkipArchiveHeapVerification) {
951 CDSHeapVerifier::verify();
952 }
953 check_default_subgraph_classes();
954 }
955
956 GrowableArrayCHeap<oop, mtClassShared>* roots = new GrowableArrayCHeap<oop, mtClassShared>(_pending_roots->length());
957 for (int i = 0; i < _pending_roots->length(); i++) {
958 roots->append(_pending_roots->at(i).resolve());
959 }
960 ArchiveHeapWriter::write(roots, heap_info);
961 }
962
963 void HeapShared::copy_interned_strings() {
964 init_seen_objects_table();
965
966 auto copier = [&] (oop s, bool value_ignored) {
967 assert(s != nullptr, "sanity");
968 assert(!ArchiveHeapWriter::is_string_too_large_to_archive(s), "large strings must have been filtered");
969 bool success = archive_reachable_objects_from(1, _default_subgraph_info, s);
970 assert(success, "must be");
971 // Prevent string deduplication from changing the value field to
972 // something not in the archive.
973 java_lang_String::set_deduplication_forbidden(s);
974 };
975 _dumped_interned_strings->iterate_all(copier);
976
977 delete_seen_objects_table();
978 }
979
980 void HeapShared::copy_special_objects() {
1043 // Add the Klass* for an object in the current KlassSubGraphInfo's subgraphs.
1044 // Only objects of boot classes can be included in sub-graph.
1045 void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) {
1046 assert(CDSConfig::is_dumping_heap(), "dump time only");
1047 Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k);
1048
1049 if (_subgraph_object_klasses == nullptr) {
1050 _subgraph_object_klasses =
1051 new (mtClass) GrowableArray<Klass*>(50, mtClass);
1052 }
1053
1054 assert(ArchiveBuilder::current()->is_in_buffer_space(buffered_k), "must be a shared class");
1055
1056 if (_k == buffered_k) {
1057 // Don't add the Klass containing the sub-graph to it's own klass
1058 // initialization list.
1059 return;
1060 }
1061
1062 if (buffered_k->is_instance_klass()) {
1063 if (CDSConfig::is_dumping_invokedynamic()) {
1064 assert(InstanceKlass::cast(buffered_k)->is_shared_boot_class() ||
1065 HeapShared::is_lambda_proxy_klass(InstanceKlass::cast(buffered_k)),
1066 "we can archive only instances of boot classes or lambda proxy classes");
1067 } else {
1068 assert(InstanceKlass::cast(buffered_k)->is_shared_boot_class(),
1069 "must be boot class");
1070 }
1071 // vmClasses::xxx_klass() are not updated, need to check
1072 // the original Klass*
1073 if (orig_k == vmClasses::String_klass() ||
1074 orig_k == vmClasses::Object_klass()) {
1075 // Initialized early during VM initialization. No need to be added
1076 // to the sub-graph object class list.
1077 return;
1078 }
1079 check_allowed_klass(InstanceKlass::cast(orig_k));
1080 } else if (buffered_k->is_objArray_klass()) {
1081 Klass* abk = ObjArrayKlass::cast(buffered_k)->bottom_klass();
1082 if (abk->is_instance_klass()) {
1083 assert(InstanceKlass::cast(abk)->is_shared_boot_class(),
1084 "must be boot class");
1085 check_allowed_klass(InstanceKlass::cast(ObjArrayKlass::cast(orig_k)->bottom_klass()));
1086 }
1087 if (buffered_k == Universe::objectArrayKlass()) {
1088 // Initialized early during Universe::genesis. No need to be added
1089 // to the list.
1090 return;
1091 }
1092 } else {
1093 assert(buffered_k->is_typeArray_klass(), "must be");
1094 // Primitive type arrays are created early during Universe::genesis.
1095 return;
1096 }
1097
1098 if (log_is_enabled(Debug, cds, heap)) {
1099 if (!_subgraph_object_klasses->contains(buffered_k)) {
1100 ResourceMark rm;
1101 log_debug(cds, heap)("Adding klass %s", orig_k->external_name());
1102 }
1103 }
1104
1105 _subgraph_object_klasses->append_if_missing(buffered_k);
1106 _has_non_early_klasses |= is_non_early_klass(orig_k);
1107 }
1108
1109 void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) {
1110 if (CDSConfig::is_dumping_invokedynamic()) {
1111 // FIXME -- this allows LambdaProxy classes
1112 return;
1113 }
1114 if (ik->module()->name() == vmSymbols::java_base()) {
1115 assert(ik->package() != nullptr, "classes in java.base cannot be in unnamed package");
1116 return;
1117 }
1118
1119 #ifndef PRODUCT
1120 if (!ik->module()->is_named() && ik->package() == nullptr) {
1121 // This class is loaded by ArchiveHeapTestClass
1122 return;
1123 }
1124 const char* extra_msg = ", or in an unnamed package of an unnamed module";
1125 #else
1126 const char* extra_msg = "";
1127 #endif
1128
1129 ResourceMark rm;
1130 log_error(cds, heap)("Class %s not allowed in archive heap. Must be in java.base%s",
1131 ik->external_name(), extra_msg);
1132 MetaspaceShared::unrecoverable_writing_error();
1133 }
1191 _subgraph_object_klasses =
1192 ArchiveBuilder::new_ro_array<Klass*>(num_subgraphs_klasses);
1193 for (int i = 0; i < num_subgraphs_klasses; i++) {
1194 Klass* subgraph_k = subgraph_object_klasses->at(i);
1195 if (log_is_enabled(Info, cds, heap)) {
1196 ResourceMark rm;
1197 log_info(cds, heap)(
1198 "Archived object klass %s (%2d) => %s",
1199 _k->external_name(), i, subgraph_k->external_name());
1200 }
1201 _subgraph_object_klasses->at_put(i, subgraph_k);
1202 ArchivePtrMarker::mark_pointer(_subgraph_object_klasses->adr_at(i));
1203 }
1204 }
1205
1206 ArchivePtrMarker::mark_pointer(&_k);
1207 ArchivePtrMarker::mark_pointer(&_entry_field_records);
1208 ArchivePtrMarker::mark_pointer(&_subgraph_object_klasses);
1209 }
1210
1211 class HeapShared::CopyKlassSubGraphInfoToArchive : StackObj {
1212 CompactHashtableWriter* _writer;
1213 public:
1214 CopyKlassSubGraphInfoToArchive(CompactHashtableWriter* writer) : _writer(writer) {}
1215
1216 bool do_entry(Klass* klass, KlassSubGraphInfo& info) {
1217 if (info.subgraph_object_klasses() != nullptr || info.subgraph_entry_fields() != nullptr) {
1218 ArchivedKlassSubGraphInfoRecord* record = HeapShared::archive_subgraph_info(&info);
1219 Klass* buffered_k = ArchiveBuilder::get_buffered_klass(klass);
1220 unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary((address)buffered_k);
1221 u4 delta = ArchiveBuilder::current()->any_to_offset_u4(record);
1222 _writer->add(hash, delta);
1223 }
1224 return true; // keep on iterating
1225 }
1226 };
1227
1228 ArchivedKlassSubGraphInfoRecord* HeapShared::archive_subgraph_info(KlassSubGraphInfo* info) {
1229 ArchivedKlassSubGraphInfoRecord* record =
1230 (ArchivedKlassSubGraphInfoRecord*)ArchiveBuilder::ro_region_alloc(sizeof(ArchivedKlassSubGraphInfoRecord));
1231 record->init(info);
1232 if (info == _default_subgraph_info) {
1233 _runtime_default_subgraph_info = record;
1234 }
1235 return record;
1236 }
1237
1238 // Build the records of archived subgraph infos, which include:
1239 // - Entry points to all subgraphs from the containing class mirror. The entry
1240 // points are static fields in the mirror. For each entry point, the field
1241 // offset, and value are recorded in the sub-graph
1242 // info. The value is stored back to the corresponding field at runtime.
1243 // - A list of klasses that need to be loaded/initialized before archived
1244 // java object sub-graph can be accessed at runtime.
1245 void HeapShared::write_subgraph_info_table() {
1246 // Allocate the contents of the hashtable(s) inside the RO region of the CDS archive.
1247 DumpTimeKlassSubGraphInfoTable* d_table = _dump_time_subgraph_info_table;
1248 CompactHashtableStats stats;
1249
1250 _run_time_subgraph_info_table.reset();
1251
1252 CompactHashtableWriter writer(d_table->_count, &stats);
1253 CopyKlassSubGraphInfoToArchive copy(&writer);
1254 d_table->iterate(©);
1255 writer.dump(&_run_time_subgraph_info_table, "subgraphs");
1256
1257 #ifndef PRODUCT
1274 _root_segments = new GrowableArrayCHeap<OopHandle, mtClassShared>(10);
1275 }
1276 _root_segments->push(OopHandle(Universe::vm_global(), segment_oop));
1277 }
1278
1279 void HeapShared::init_root_segment_sizes(int max_size_elems) {
1280 _root_segment_max_size_elems = max_size_elems;
1281 }
1282
1283 void HeapShared::serialize_tables(SerializeClosure* soc) {
1284
1285 #ifndef PRODUCT
1286 soc->do_ptr(&_archived_ArchiveHeapTestClass);
1287 if (soc->reading() && _archived_ArchiveHeapTestClass != nullptr) {
1288 _test_class_name = _archived_ArchiveHeapTestClass->adr_at(0);
1289 setup_test_class(_test_class_name);
1290 }
1291 #endif
1292
1293 _run_time_subgraph_info_table.serialize_header(soc);
1294 soc->do_ptr(&_runtime_default_subgraph_info);
1295 }
1296
1297 static void verify_the_heap(Klass* k, const char* which) {
1298 if (VerifyArchivedFields > 0) {
1299 ResourceMark rm;
1300 log_info(cds, heap)("Verify heap %s initializing static field(s) in %s",
1301 which, k->external_name());
1302
1303 VM_Verify verify_op;
1304 VMThread::execute(&verify_op);
1305
1306 if (VerifyArchivedFields > 1 && is_init_completed()) {
1307 // At this time, the oop->klass() of some archived objects in the heap may not
1308 // have been loaded into the system dictionary yet. Nevertheless, oop->klass() should
1309 // have enough information (object size, oop maps, etc) so that a GC can be safely
1310 // performed.
1311 //
1312 // -XX:VerifyArchivedFields=2 force a GC to happen in such an early stage
1313 // to check for GC safety.
1314 log_info(cds, heap)("Trigger GC %s initializing static field(s) in %s",
1315 which, k->external_name());
1316 FlagSetting fs1(VerifyBeforeGC, true);
1317 FlagSetting fs2(VerifyDuringGC, true);
1318 FlagSetting fs3(VerifyAfterGC, true);
1319 Universe::heap()->collect(GCCause::_java_lang_system_gc);
1320 }
1321 }
1322 }
1323
1324 // Before GC can execute, we must ensure that all oops reachable from HeapShared::roots()
1325 // have a valid klass. I.e., oopDesc::klass() must have already been resolved.
1326 //
1327 // Note: if a ArchivedKlassSubGraphInfoRecord contains non-early classes, and JVMTI
1328 // ClassFileLoadHook is enabled, it's possible for this class to be dynamically replaced. In
1329 // this case, we will not load the ArchivedKlassSubGraphInfoRecord and will clear its roots.
1330 void HeapShared::resolve_classes(JavaThread* current) {
1331 assert(CDSConfig::is_using_archive(), "runtime only!");
1332 if (!ArchiveHeapLoader::is_in_use()) {
1333 return; // nothing to do
1334 }
1335
1336 if (!CDSConfig::is_using_aot_linked_classes()) {
1337 assert( _runtime_default_subgraph_info != nullptr, "must be");
1338 Array<Klass*>* klasses = _runtime_default_subgraph_info->subgraph_object_klasses();
1339 if (klasses != nullptr) {
1340 for (int i = 0; i < klasses->length(); i++) {
1341 Klass* k = klasses->at(i);
1342 ExceptionMark em(current); // no exception can happen here
1343 resolve_or_init(k, /*do_init*/false, current);
1344 }
1345 }
1346 }
1347
1348 resolve_classes_for_subgraphs(current, archive_subgraph_entry_fields);
1349 resolve_classes_for_subgraphs(current, fmg_archive_subgraph_entry_fields);
1350 }
1351
1352 void HeapShared::resolve_classes_for_subgraphs(JavaThread* current, ArchivableStaticFieldInfo fields[]) {
1353 for (int i = 0; fields[i].valid(); i++) {
1354 ArchivableStaticFieldInfo* info = &fields[i];
1355 TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name);
1356 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name);
1357 assert(k != nullptr && k->is_shared_boot_class(), "sanity");
1358 resolve_classes_for_subgraph_of(current, k);
1359 }
1360 }
1361
1362 void HeapShared::resolve_classes_for_subgraph_of(JavaThread* current, Klass* k) {
1363 JavaThread* THREAD = current;
1364 ExceptionMark em(THREAD);
1365 const ArchivedKlassSubGraphInfoRecord* record =
1366 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/false, THREAD);
1367 if (HAS_PENDING_EXCEPTION) {
1368 CLEAR_PENDING_EXCEPTION;
1369 }
1370 if (record == nullptr) {
1371 clear_archived_roots_of(k);
1372 }
1373 }
1374
1375 void HeapShared::initialize_java_lang_invoke(TRAPS) {
1376 if (CDSConfig::is_loading_invokedynamic() || CDSConfig::is_dumping_invokedynamic()) {
1377 resolve_or_init("java/lang/invoke/Invokers$Holder", true, CHECK);
1378 resolve_or_init("java/lang/invoke/MethodHandle", true, CHECK);
1379 resolve_or_init("java/lang/invoke/MethodHandleNatives", true, CHECK);
1380 resolve_or_init("java/lang/invoke/DirectMethodHandle$Holder", true, CHECK);
1381 resolve_or_init("java/lang/invoke/DelegatingMethodHandle$Holder", true, CHECK);
1382 resolve_or_init("java/lang/invoke/LambdaForm$Holder", true, CHECK);
1383 resolve_or_init("java/lang/invoke/BoundMethodHandle$Species_L", true, CHECK);
1384 }
1385 }
1386
1387 void HeapShared::initialize_default_subgraph_classes(Handle class_loader, TRAPS) {
1388 if (!ArchiveHeapLoader::is_in_use()) {
1389 return;
1390 }
1391
1392 assert( _runtime_default_subgraph_info != nullptr, "must be");
1393 Array<Klass*>* klasses = _runtime_default_subgraph_info->subgraph_object_klasses();
1394 if (klasses != nullptr) {
1395 for (int pass = 0; pass < 2; pass ++) {
1396 for (int i = 0; i < klasses->length(); i++) {
1397 Klass* k = klasses->at(i);
1398 if (k->class_loader_data() == nullptr) {
1399 // This class is not yet loaded. We will initialize it in a later phase.
1400 continue;
1401 }
1402 if (k->class_loader() == class_loader()) {
1403 if (pass == 0) {
1404 if (k->is_instance_klass()) {
1405 InstanceKlass::cast(k)->link_class(CHECK);
1406 }
1407 } else {
1408 resolve_or_init(k, /*do_init*/true, CHECK);
1409 }
1410 }
1411 }
1412 }
1413 }
1414 }
1415
1416 void HeapShared::initialize_from_archived_subgraph(JavaThread* current, Klass* k) {
1417 JavaThread* THREAD = current;
1418 if (!ArchiveHeapLoader::is_in_use()) {
1419 return; // nothing to do
1420 }
1421
1422 if (k->name()->equals("jdk/internal/module/ArchivedModuleGraph") &&
1423 !CDSConfig::is_using_optimized_module_handling() &&
1424 // archive was created with --module-path
1425 ClassLoaderExt::num_module_paths() > 0) {
1426 // ArchivedModuleGraph was created with a --module-path that's different than the runtime --module-path.
1427 // Thus, it might contain references to modules that do not exist at runtime. We cannot use it.
1428 log_info(cds, heap)("Skip initializing ArchivedModuleGraph subgraph: is_using_optimized_module_handling=%s num_module_paths=%d",
1429 BOOL_TO_STR(CDSConfig::is_using_optimized_module_handling()), ClassLoaderExt::num_module_paths());
1430 return;
1431 }
1432
1433 ExceptionMark em(THREAD);
1434 const ArchivedKlassSubGraphInfoRecord* record =
1435 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/true, THREAD);
1499
1500 resolve_or_init(k, do_init, CHECK_NULL);
1501
1502 // Load/link/initialize the klasses of the objects in the subgraph.
1503 // nullptr class loader is used.
1504 Array<Klass*>* klasses = record->subgraph_object_klasses();
1505 if (klasses != nullptr) {
1506 for (int i = 0; i < klasses->length(); i++) {
1507 Klass* klass = klasses->at(i);
1508 if (!klass->is_shared()) {
1509 return nullptr;
1510 }
1511 resolve_or_init(klass, do_init, CHECK_NULL);
1512 }
1513 }
1514 }
1515
1516 return record;
1517 }
1518
1519 void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) {
1520 TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name);
1521 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym);
1522 if (k == nullptr) {
1523 return;
1524 }
1525 assert(k->is_shared_boot_class(), "sanity");
1526 resolve_or_init(k, false, CHECK);
1527 if (do_init) {
1528 resolve_or_init(k, true, CHECK);
1529 }
1530 }
1531
1532 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
1533 if (!do_init) {
1534 if (k->class_loader_data() == nullptr) {
1535 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
1536 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1537 }
1538 } else {
1539 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
1540 if (k->is_instance_klass()) {
1541 InstanceKlass* ik = InstanceKlass::cast(k);
1542 ik->initialize(CHECK);
1543 } else if (k->is_objArray_klass()) {
1544 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1545 oak->initialize(CHECK);
1546 }
1547 }
1548 }
1549
1550 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1551 verify_the_heap(k, "before");
1659
1660 template <class T> void check(T *p) {
1661 _result |= (HeapAccess<>::oop_load(p) != nullptr);
1662 }
1663
1664 public:
1665 PointsToOopsChecker() : _result(false) {}
1666 void do_oop(narrowOop *p) { check(p); }
1667 void do_oop( oop *p) { check(p); }
1668 bool result() { return _result; }
1669 };
1670
1671 HeapShared::CachedOopInfo HeapShared::make_cached_oop_info(oop obj) {
1672 WalkOopAndArchiveClosure* walker = WalkOopAndArchiveClosure::current();
1673 oop referrer = (walker == nullptr) ? nullptr : walker->referencing_obj();
1674 PointsToOopsChecker points_to_oops_checker;
1675 obj->oop_iterate(&points_to_oops_checker);
1676 return CachedOopInfo(referrer, points_to_oops_checker.result());
1677 }
1678
1679 // We currently allow only the box classes, as well as j.l.Object, which are
1680 // initialized very early by HeapShared::init_box_classes().
1681 bool HeapShared::can_mirror_be_used_in_subgraph(oop orig_java_mirror) {
1682 return java_lang_Class::is_primitive(orig_java_mirror)
1683 || orig_java_mirror == vmClasses::Boolean_klass()->java_mirror()
1684 || orig_java_mirror == vmClasses::Character_klass()->java_mirror()
1685 || orig_java_mirror == vmClasses::Float_klass()->java_mirror()
1686 || orig_java_mirror == vmClasses::Double_klass()->java_mirror()
1687 || orig_java_mirror == vmClasses::Byte_klass()->java_mirror()
1688 || orig_java_mirror == vmClasses::Short_klass()->java_mirror()
1689 || orig_java_mirror == vmClasses::Integer_klass()->java_mirror()
1690 || orig_java_mirror == vmClasses::Long_klass()->java_mirror()
1691 || orig_java_mirror == vmClasses::Void_klass()->java_mirror()
1692 || orig_java_mirror == vmClasses::Object_klass()->java_mirror();
1693 }
1694
1695 void HeapShared::init_box_classes(TRAPS) {
1696 if (ArchiveHeapLoader::is_in_use()) {
1697 vmClasses::Boolean_klass()->initialize(CHECK);
1698 vmClasses::Character_klass()->initialize(CHECK);
1699 vmClasses::Float_klass()->initialize(CHECK);
1700 vmClasses::Double_klass()->initialize(CHECK);
1701 vmClasses::Byte_klass()->initialize(CHECK);
1702 vmClasses::Short_klass()->initialize(CHECK);
1703 vmClasses::Integer_klass()->initialize(CHECK);
1704 vmClasses::Long_klass()->initialize(CHECK);
1705 vmClasses::Void_klass()->initialize(CHECK);
1706 }
1707 }
1708
1709 void HeapShared::exit_on_error() {
1710 if (_context != nullptr) {
1711 ResourceMark rm;
1712 LogStream ls(Log(cds, heap)::error());
1713 ls.print_cr("Context");
1714 for (int i = 0; i < _context->length(); i++) {
1715 const char* s = _context->at(i);
1716 ls.print_cr("- %s", s);
1717 }
1718 }
1719 if (_trace != nullptr) {
1720 ResourceMark rm;
1721 LogStream ls(Log(cds, heap)::error());
1722 ls.print_cr("Reference trace");
1723 for (int i = 0; i < _trace->length(); i++) {
1724 oop orig_obj = _trace->at(i);
1725 ls.print_cr("[%d] ========================================", i);
1726 orig_obj->print_on(&ls);
1727 ls.cr();
1728 }
1729 }
1730 MetaspaceShared::unrecoverable_writing_error();
1731 }
1732
1733 void HeapShared::debug_trace() {
1734 WalkOopAndArchiveClosure* walker = WalkOopAndArchiveClosure::current();
1735 if (walker != nullptr) {
1736 LogStream ls(Log(cds, heap)::error());
1737 CDSHeapVerifier::trace_to_root(&ls, walker->referencing_obj());
1738 }
1739 }
1740
1741 // (1) If orig_obj has not been archived yet, archive it.
1742 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
1743 // trace all objects that are reachable from it, and make sure these objects are archived.
1744 // (3) Record the klasses of all orig_obj and all reachable objects.
1745 bool HeapShared::archive_reachable_objects_from(int level,
1746 KlassSubGraphInfo* subgraph_info,
1747 oop orig_obj) {
1748 ArchivingObjectMark mark(orig_obj);
1749 assert(orig_obj != nullptr, "must be");
1750
1751 if (!JavaClasses::is_supported_for_archiving(orig_obj)) {
1752 // This object has injected fields that cannot be supported easily, so we disallow them for now.
1753 // If you get an error here, you probably made a change in the JDK library that has added
1754 // these objects that are referenced (directly or indirectly) by static fields.
1755 ResourceMark rm;
1756 log_error(cds, heap)("Cannot archive object " PTR_FORMAT " of class %s", p2i(orig_obj), orig_obj->klass()->external_name());
1757 debug_trace();
1758 exit_on_error();
1759 }
1760
1761 if (log_is_enabled(Debug, cds, heap) && java_lang_Class::is_instance(orig_obj)) {
1762 ResourceMark rm;
1763 LogTarget(Debug, cds, heap) log;
1764 LogStream out(log);
1765 out.print("Found java mirror " PTR_FORMAT " ", p2i(orig_obj));
1766 Klass* k = java_lang_Class::as_Klass(orig_obj);
1767 if (k != nullptr) {
1768 out.print("%s", k->external_name());
1769 } else {
1770 out.print("primitive");
1771 }
1772 out.print_cr("; scratch mirror = " PTR_FORMAT,
1773 p2i(scratch_java_mirror(orig_obj)));
1774 }
1775
1776 if (java_lang_Class::is_instance(orig_obj)) {
1777 orig_obj = scratch_java_mirror(orig_obj);
1778 assert(orig_obj != nullptr, "must be archived");
1779 }
1780
1781 if (has_been_seen_during_subgraph_recording(orig_obj)) {
1782 // orig_obj has already been archived and traced. Nothing more to do.
1783 return true;
1784 } else {
1785 set_has_been_seen_during_subgraph_recording(orig_obj);
1786 }
1787
1788 bool already_archived = has_been_archived(orig_obj);
1789 bool record_klasses_only = already_archived;
1790 if (!already_archived) {
1791 ++_num_new_archived_objs;
1792 if (!archive_object(orig_obj)) {
1793 // Skip archiving the sub-graph referenced from the current entry field.
1794 ResourceMark rm;
1795 log_error(cds, heap)(
1796 "Cannot archive the sub-graph referenced from %s object ("
1797 PTR_FORMAT ") size " SIZE_FORMAT ", skipped.",
1798 orig_obj->klass()->external_name(), p2i(orig_obj), orig_obj->size() * HeapWordSize);
1799 if (level == 1) {
1800 // Don't archive a subgraph root that's too big. For archives static fields, that's OK
1801 // as the Java code will take care of initializing this field dynamically.
1802 return false;
1803 } else {
1804 // We don't know how to handle an object that has been archived, but some of its reachable
1805 // objects cannot be archived. Bail out for now. We might need to fix this in the future if
1806 // we have a real use case.
1807 exit_on_error();
1808 }
1809 }
1810 }
1811
1812 Klass *orig_k = orig_obj->klass();
1813 subgraph_info->add_subgraph_object_klass(orig_k);
1814
1815 WalkOopAndArchiveClosure walker(level, record_klasses_only, subgraph_info, orig_obj);
1816 orig_obj->oop_iterate(&walker);
1817
1818 if (CDSConfig::is_initing_classes_at_dump_time()) {
1819 // The enum klasses are archived with preinitialized mirror.
1820 // See AOTClassInitializer::can_archive_initialized_mirror.
1821 } else {
1822 if (CDSEnumKlass::is_enum_obj(orig_obj)) {
1823 CDSEnumKlass::handle_enum_obj(level + 1, subgraph_info, orig_obj);
1824 }
1825 }
1826
1827 return true;
1828 }
1829
1830 //
1831 // Start from the given static field in a java mirror and archive the
1832 // complete sub-graph of java heap objects that are reached directly
1833 // or indirectly from the starting object by following references.
1834 // Sub-graph archiving restrictions (current):
1835 //
1836 // - All classes of objects in the archived sub-graph (including the
1837 // entry class) must be boot class only.
1838 // - No java.lang.Class instance (java mirror) can be included inside
1839 // an archived sub-graph. Mirror can only be the sub-graph entry object.
1840 //
1841 // The Java heap object sub-graph archiving process (see
1842 // WalkOopAndArchiveClosure):
1843 //
1844 // 1) Java object sub-graph archiving starts from a given static field
1845 // within a Class instance (java mirror). If the static field is a
1846 // reference field and points to a non-null java object, proceed to
1924 if (!CompressedOops::is_null(f)) {
1925 verify_subgraph_from(f);
1926 }
1927 }
1928
1929 void HeapShared::verify_subgraph_from(oop orig_obj) {
1930 if (!has_been_archived(orig_obj)) {
1931 // It's OK for the root of a subgraph to be not archived. See comments in
1932 // archive_reachable_objects_from().
1933 return;
1934 }
1935
1936 // Verify that all objects reachable from orig_obj are archived.
1937 init_seen_objects_table();
1938 verify_reachable_objects_from(orig_obj);
1939 delete_seen_objects_table();
1940 }
1941
1942 void HeapShared::verify_reachable_objects_from(oop obj) {
1943 _num_total_verifications ++;
1944 if (java_lang_Class::is_instance(obj)) {
1945 obj = scratch_java_mirror(obj);
1946 assert(obj != nullptr, "must be");
1947 }
1948 if (!has_been_seen_during_subgraph_recording(obj)) {
1949 set_has_been_seen_during_subgraph_recording(obj);
1950 assert(has_been_archived(obj), "must be");
1951 VerifySharedOopClosure walker;
1952 obj->oop_iterate(&walker);
1953 }
1954 }
1955 #endif
1956
1957 // The "default subgraph" contains special objects (see heapShared.hpp) that
1958 // can be accessed before we load any Java classes (including java/lang/Class).
1959 // Make sure that these are only instances of the very few specific types
1960 // that we can handle.
1961 void HeapShared::check_default_subgraph_classes() {
1962 if (CDSConfig::is_initing_classes_at_dump_time()) {
1963 return;
1964 }
1965
1966 GrowableArray<Klass*>* klasses = _default_subgraph_info->subgraph_object_klasses();
1967 int num = klasses->length();
1968 for (int i = 0; i < num; i++) {
1969 Klass* subgraph_k = klasses->at(i);
1970 Symbol* name = ArchiveBuilder::current()->get_source_addr(subgraph_k->name());
1971 if (subgraph_k->is_instance_klass() &&
1972 name != vmSymbols::java_lang_Class() &&
1973 name != vmSymbols::java_lang_String() &&
1974 name != vmSymbols::java_lang_ArithmeticException() &&
1975 name != vmSymbols::java_lang_ArrayIndexOutOfBoundsException() &&
1976 name != vmSymbols::java_lang_ArrayStoreException() &&
1977 name != vmSymbols::java_lang_ClassCastException() &&
1978 name != vmSymbols::java_lang_InternalError() &&
1979 name != vmSymbols::java_lang_NullPointerException()) {
1980 ResourceMark rm;
1981 fatal("default subgraph cannot have objects of type %s", subgraph_k->external_name());
1982 }
1983 }
1984 }
1985
1986 HeapShared::SeenObjectsTable* HeapShared::_seen_objects_table = nullptr;
1987 int HeapShared::_num_new_walked_objs;
1988 int HeapShared::_num_new_archived_objs;
1989 int HeapShared::_num_old_recorded_klasses;
1990
1991 int HeapShared::_num_total_subgraph_recordings = 0;
1992 int HeapShared::_num_total_walked_objs = 0;
1993 int HeapShared::_num_total_archived_objs = 0;
1994 int HeapShared::_num_total_recorded_klasses = 0;
1995 int HeapShared::_num_total_verifications = 0;
1996
1997 bool HeapShared::has_been_seen_during_subgraph_recording(oop obj) {
1998 return _seen_objects_table->get(obj) != nullptr;
1999 }
2000
2001 void HeapShared::set_has_been_seen_during_subgraph_recording(oop obj) {
2002 assert(!has_been_seen_during_subgraph_recording(obj), "sanity");
2185 return false;
2186 }
2187
2188 // See KlassSubGraphInfo::check_allowed_klass() - only two types of
2189 // classes are allowed:
2190 // (A) java.base classes (which must not be in the unnamed module)
2191 // (B) test classes which must be in the unnamed package of the unnamed module.
2192 // So if we see a '/' character in the class name, it must be in (A);
2193 // otherwise it must be in (B).
2194 if (name->index_of_at(0, "/", 1) >= 0) {
2195 return false; // (A)
2196 }
2197
2198 return true; // (B)
2199 }
2200 }
2201 }
2202
2203 return false;
2204 }
2205
2206 void HeapShared::initialize_test_class_from_archive(JavaThread* current) {
2207 Klass* k = _test_class;
2208 if (k != nullptr && ArchiveHeapLoader::is_in_use()) {
2209 JavaThread* THREAD = current;
2210 ExceptionMark em(THREAD);
2211 const ArchivedKlassSubGraphInfoRecord* record =
2212 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/false, THREAD);
2213
2214 // The _test_class is in the unnamed module, so it can't call CDS.initializeFromArchive()
2215 // from its <clinit> method. So we set up its "archivedObjects" field first, before
2216 // calling its <clinit>. This is not strictly clean, but it's a convenient way to write unit
2217 // test cases (see test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java).
2218 if (record != nullptr) {
2219 init_archived_fields_for(k, record);
2220 }
2221 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/true, THREAD);
2222 }
2223 }
2224 #endif
2225
2226 void HeapShared::init_for_dumping(TRAPS) {
2227 if (HeapShared::can_write()) {
2228 setup_test_class(ArchiveHeapTestClass);
2229 _dumped_interned_strings = new (mtClass)DumpedInternedStrings(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE);
2230 init_subgraph_entry_fields(CHECK);
2231 }
2232 }
2233
2234 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
2235 bool is_full_module_graph) {
2236 _num_total_subgraph_recordings = 0;
2237 _num_total_walked_objs = 0;
2238 _num_total_archived_objs = 0;
2239 _num_total_recorded_klasses = 0;
2240 _num_total_verifications = 0;
2241
2242 // For each class X that has one or more archived fields:
2243 // [1] Dump the subgraph of each archived field
2244 // [2] Create a list of all the class of the objects that can be reached
2245 // by any of these static fields.
2246 // At runtime, these classes are initialized before X's archived fields
2247 // are restored by HeapShared::initialize_from_archived_subgraph().
2248 for (int i = 0; fields[i].valid(); ) {
2249 ArchivableStaticFieldInfo* info = &fields[i];
2250 const char* klass_name = info->klass_name;
2251 start_recording_subgraph(info->klass, klass_name, is_full_module_graph);
2252
2253 ContextMark cm(klass_name);
2254 // If you have specified consecutive fields of the same klass in
2255 // fields[], these will be archived in the same
2256 // {start_recording_subgraph ... done_recording_subgraph} pass to
2257 // save time.
2258 for (; fields[i].valid(); i++) {
2259 ArchivableStaticFieldInfo* f = &fields[i];
2260 if (f->klass_name != klass_name) {
2261 break;
2262 }
2263
2264 ContextMark cm(f->field_name);
2265 archive_reachable_objects_from_static_field(f->klass, f->klass_name,
2266 f->offset, f->field_name);
2267 }
2268 done_recording_subgraph(info->klass, klass_name);
2269 }
2270
2271 log_info(cds, heap)("Archived subgraph records = %d",
2272 _num_total_subgraph_recordings);
2273 log_info(cds, heap)(" Walked %d objects", _num_total_walked_objs);
2274 log_info(cds, heap)(" Archived %d objects", _num_total_archived_objs);
2275 log_info(cds, heap)(" Recorded %d klasses", _num_total_recorded_klasses);
2276
2277 #ifndef PRODUCT
2278 for (int i = 0; fields[i].valid(); i++) {
2279 ArchivableStaticFieldInfo* f = &fields[i];
2280 verify_subgraph_from_static_field(f->klass, f->offset);
2281 }
2282 log_info(cds, heap)(" Verified %d references", _num_total_verifications);
2283 #endif
2284 }
|