6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "cds/aotArtifactFinder.hpp"
26 #include "cds/aotClassInitializer.hpp"
27 #include "cds/aotClassLocation.hpp"
28 #include "cds/aotCompressedPointers.hpp"
29 #include "cds/aotLogging.hpp"
30 #include "cds/aotMappedHeapLoader.hpp"
31 #include "cds/aotMappedHeapWriter.hpp"
32 #include "cds/aotMetaspace.hpp"
33 #include "cds/aotOopChecker.hpp"
34 #include "cds/aotReferenceObjSupport.hpp"
35 #include "cds/aotStreamedHeapLoader.hpp"
36 #include "cds/aotStreamedHeapWriter.hpp"
37 #include "cds/archiveBuilder.hpp"
38 #include "cds/archiveUtils.hpp"
39 #include "cds/cds_globals.hpp"
40 #include "cds/cdsConfig.hpp"
41 #include "cds/cdsEnumKlass.hpp"
42 #include "cds/cdsHeapVerifier.hpp"
43 #include "cds/heapShared.inline.hpp"
44 #include "cds/regeneratedClasses.hpp"
45 #include "classfile/classLoaderData.hpp"
46 #include "classfile/javaClasses.inline.hpp"
47 #include "classfile/modules.hpp"
48 #include "classfile/stringTable.hpp"
49 #include "classfile/symbolTable.hpp"
50 #include "classfile/systemDictionary.hpp"
51 #include "classfile/systemDictionaryShared.hpp"
52 #include "classfile/vmClasses.hpp"
53 #include "classfile/vmSymbols.hpp"
54 #include "gc/shared/collectedHeap.hpp"
55 #include "gc/shared/gcLocker.hpp"
56 #include "gc/shared/gcVMOperations.hpp"
57 #include "logging/log.hpp"
58 #include "logging/logStream.hpp"
59 #include "memory/iterator.inline.hpp"
60 #include "memory/resourceArea.hpp"
61 #include "memory/universe.hpp"
62 #include "oops/compressedOops.inline.hpp"
63 #include "oops/fieldStreams.inline.hpp"
64 #include "oops/objArrayOop.inline.hpp"
65 #include "oops/oop.inline.hpp"
66 #include "oops/oopHandle.inline.hpp"
67 #include "oops/typeArrayOop.inline.hpp"
68 #include "prims/jvmtiExport.hpp"
69 #include "runtime/arguments.hpp"
70 #include "runtime/fieldDescriptor.inline.hpp"
71 #include "runtime/globals_extension.hpp"
72 #include "runtime/init.hpp"
73 #include "runtime/javaCalls.hpp"
113 #endif
114
115
116 //
117 // If you add new entries to the following tables, you should know what you're doing!
118 //
119
120 static ArchivableStaticFieldInfo archive_subgraph_entry_fields[] = {
121 {"java/lang/Integer$IntegerCache", "archivedCache"},
122 {"java/lang/Long$LongCache", "archivedCache"},
123 {"java/lang/Byte$ByteCache", "archivedCache"},
124 {"java/lang/Short$ShortCache", "archivedCache"},
125 {"java/lang/Character$CharacterCache", "archivedCache"},
126 {"java/util/jar/Attributes$Name", "KNOWN_NAMES"},
127 {"sun/util/locale/BaseLocale", "constantBaseLocales"},
128 {"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"},
129 {"java/util/ImmutableCollections", "archivedObjects"},
130 {"java/lang/ModuleLayer", "EMPTY_LAYER"},
131 {"java/lang/module/Configuration", "EMPTY_CONFIGURATION"},
132 {"jdk/internal/math/FDBigInteger", "archivedCaches"},
133
134 #ifndef PRODUCT
135 {nullptr, nullptr}, // Extra slot for -XX:ArchiveHeapTestClass
136 #endif
137 {nullptr, nullptr},
138 };
139
140 // full module graph
141 static ArchivableStaticFieldInfo fmg_archive_subgraph_entry_fields[] = {
142 {"jdk/internal/loader/ArchivedClassLoaders", "archivedClassLoaders"},
143 {ARCHIVED_BOOT_LAYER_CLASS, ARCHIVED_BOOT_LAYER_FIELD},
144 {"java/lang/Module$ArchivedData", "archivedData"},
145 {nullptr, nullptr},
146 };
147
148 KlassSubGraphInfo* HeapShared::_dump_time_special_subgraph;
149 ArchivedKlassSubGraphInfoRecord* HeapShared::_run_time_special_subgraph;
150 GrowableArrayCHeap<oop, mtClassShared>* HeapShared::_pending_roots = nullptr;
151 OopHandle HeapShared::_scratch_basic_type_mirrors[T_VOID+1];
152 MetaspaceObjToOopHandleTable* HeapShared::_scratch_objects_table = nullptr;
601 // returned from jdk.internal.misc.CDS::initializeFromArchive().
602 // See HeapShared::initialize_from_archived_subgraph().
603 {
604 AOTArtifactFinder::add_aot_inited_class(InstanceKlass::cast(k));
605 }
606
607 if (java_lang_Class::is_instance(obj)) {
608 Klass* mirror_k = java_lang_Class::as_Klass(obj);
609 if (mirror_k != nullptr) {
610 AOTArtifactFinder::add_cached_class(mirror_k);
611 }
612 } else if (java_lang_invoke_ResolvedMethodName::is_instance(obj)) {
613 Method* m = java_lang_invoke_ResolvedMethodName::vmtarget(obj);
614 if (m != nullptr) {
615 if (RegeneratedClasses::has_been_regenerated(m)) {
616 m = RegeneratedClasses::get_regenerated_object(m);
617 }
618 InstanceKlass* method_holder = m->method_holder();
619 AOTArtifactFinder::add_cached_class(method_holder);
620 }
621 }
622 }
623
624 if (log_is_enabled(Debug, aot, heap)) {
625 ResourceMark rm;
626 LogTarget(Debug, aot, heap) log;
627 LogStream out(log);
628 out.print("Archived heap object " PTR_FORMAT " : %s ",
629 p2i(obj), obj->klass()->external_name());
630 if (java_lang_Class::is_instance(obj)) {
631 Klass* k = java_lang_Class::as_Klass(obj);
632 if (k != nullptr) {
633 out.print("%s", k->external_name());
634 } else {
635 out.print("primitive");
636 }
637 }
638 out.cr();
639 }
640
788 if (RegeneratedClasses::is_regenerated_object(ik)) {
789 InstanceKlass* orig_ik = RegeneratedClasses::get_original_object(ik);
790 precond(orig_ik->is_initialized());
791 orig_mirror = orig_ik->java_mirror();
792 } else {
793 precond(ik->is_initialized());
794 orig_mirror = ik->java_mirror();
795 }
796
797 oop m = scratch_java_mirror(ik);
798 int nfields = 0;
799 for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {
800 if (fs.access_flags().is_static()) {
801 fieldDescriptor& fd = fs.field_descriptor();
802 int offset = fd.offset();
803 switch (fd.field_type()) {
804 case T_OBJECT:
805 case T_ARRAY:
806 {
807 oop field_obj = orig_mirror->obj_field(offset);
808 if (offset == java_lang_Class::reflection_data_offset()) {
809 // Class::reflectData use SoftReference, which cannot be archived. Set it
810 // to null and it will be recreated at runtime.
811 field_obj = nullptr;
812 }
813 m->obj_field_put(offset, field_obj);
814 if (field_obj != nullptr) {
815 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, field_obj);
816 assert(success, "sanity");
817 }
818 }
819 break;
820 case T_BOOLEAN:
821 m->bool_field_put(offset, orig_mirror->bool_field(offset));
822 break;
823 case T_BYTE:
824 m->byte_field_put(offset, orig_mirror->byte_field(offset));
825 break;
826 case T_SHORT:
827 m->short_field_put(offset, orig_mirror->short_field(offset));
828 break;
829 case T_CHAR:
830 m->char_field_put(offset, orig_mirror->char_field(offset));
831 break;
832 case T_INT:
867 // We need to retain the identity_hash, because it may have been used by some hashtables
868 // in the shared heap.
869 if (!orig_mirror->fast_no_hash_check()) {
870 intptr_t src_hash = orig_mirror->identity_hash();
871 if (UseCompactObjectHeaders) {
872 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
873 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
874 } else {
875 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
876 }
877 assert(scratch_m->mark().is_unlocked(), "sanity");
878
879 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
880 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
881 }
882
883 if (CDSConfig::is_dumping_aot_linked_classes()) {
884 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
885 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
886 }
887 }
888
889 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
890 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
891 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
892 if (rr != nullptr && !HeapShared::is_too_large_to_archive(rr)) {
893 return HeapShared::scratch_resolved_references(src_ik->constants());
894 }
895 }
896 return nullptr;
897 }
898
899 int HeapShared::archive_exception_instance(oop exception) {
900 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, exception);
901 assert(success, "sanity");
902 return append_root(exception);
903 }
904
905 void HeapShared::get_pointer_info(oop src_obj, bool& has_oop_pointers, bool& has_native_pointers) {
906 OopHandle oh(&src_obj);
938 p2i((address)G1CollectedHeap::heap()->reserved().end()));
939 }
940
941 archive_subgraphs();
942 }
943
944 init_seen_objects_table();
945 Universe::archive_exception_instances();
946 }
947
948 void HeapShared::end_scanning_for_oops() {
949 if (is_writing_mapping_mode()) {
950 StringTable::init_shared_table();
951 }
952 delete_seen_objects_table();
953 }
954
955 void HeapShared::write_heap(AOTMappedHeapInfo* mapped_heap_info, AOTStreamedHeapInfo* streamed_heap_info) {
956 {
957 NoSafepointVerifier nsv;
958 CDSHeapVerifier::verify();
959 check_special_subgraph_classes();
960 }
961
962 if (HeapShared::is_writing_mapping_mode()) {
963 StringTable::write_shared_table();
964 AOTMappedHeapWriter::write(_pending_roots, mapped_heap_info);
965 } else {
966 assert(HeapShared::is_writing_streaming_mode(), "are there more modes?");
967 AOTStreamedHeapWriter::write(_pending_roots, streamed_heap_info);
968 }
969
970 ArchiveBuilder::OtherROAllocMark mark;
971 write_subgraph_info_table();
972
973 delete _pending_roots;
974 _pending_roots = nullptr;
975
976 make_archived_object_cache_gc_safe();
977 }
978
979 void HeapShared::scan_java_mirror(oop orig_mirror) {
980 oop m = scratch_java_mirror(orig_mirror);
981 if (m != nullptr) { // nullptr if for custom class loader
982 copy_java_mirror(orig_mirror, m);
983 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, m);
984 assert(success, "sanity");
985 }
986 }
987
988 void HeapShared::scan_java_class(Klass* orig_k) {
989 scan_java_mirror(orig_k->java_mirror());
990
991 if (orig_k->is_instance_klass()) {
992 InstanceKlass* orig_ik = InstanceKlass::cast(orig_k);
993 orig_ik->constants()->prepare_resolved_references_for_archiving();
994 objArrayOop rr = get_archived_resolved_references(orig_ik);
995 if (rr != nullptr) {
996 bool success = HeapShared::archive_reachable_objects_from(1, _dump_time_special_subgraph, rr);
997 assert(success, "must be");
998 }
999 }
1000 }
1001
1002 void HeapShared::archive_subgraphs() {
1003 assert(CDSConfig::is_dumping_heap(), "must be");
1004
1029 &created);
1030 assert(created, "must not initialize twice");
1031 return info;
1032 }
1033
1034 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
1035 assert(CDSConfig::is_dumping_heap(), "dump time only");
1036 KlassSubGraphInfo* info = _dump_time_subgraph_info_table->get(k);
1037 assert(info != nullptr, "must have been initialized");
1038 return info;
1039 }
1040
1041 // Add an entry field to the current KlassSubGraphInfo.
1042 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
1043 assert(CDSConfig::is_dumping_heap(), "dump time only");
1044 if (_subgraph_entry_fields == nullptr) {
1045 _subgraph_entry_fields =
1046 new (mtClass) GrowableArray<int>(10, mtClass);
1047 }
1048 _subgraph_entry_fields->append(static_field_offset);
1049 _subgraph_entry_fields->append(HeapShared::append_root(v));
1050 }
1051
1052 // Add the Klass* for an object in the current KlassSubGraphInfo's subgraphs.
1053 // Only objects of boot classes can be included in sub-graph.
1054 void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) {
1055 assert(CDSConfig::is_dumping_heap(), "dump time only");
1056
1057 if (_subgraph_object_klasses == nullptr) {
1058 _subgraph_object_klasses =
1059 new (mtClass) GrowableArray<Klass*>(50, mtClass);
1060 }
1061
1062 if (_k == orig_k) {
1063 // Don't add the Klass containing the sub-graph to it's own klass
1064 // initialization list.
1065 return;
1066 }
1067
1068 if (orig_k->is_instance_klass()) {
1069 #ifdef ASSERT
1371 TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name);
1372 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name);
1373 assert(k != nullptr && k->defined_by_boot_loader(), "sanity");
1374 resolve_classes_for_subgraph_of(current, k);
1375 }
1376 }
1377
1378 void HeapShared::resolve_classes_for_subgraph_of(JavaThread* current, Klass* k) {
1379 JavaThread* THREAD = current;
1380 ExceptionMark em(THREAD);
1381 const ArchivedKlassSubGraphInfoRecord* record =
1382 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/false, THREAD);
1383 if (HAS_PENDING_EXCEPTION) {
1384 CLEAR_PENDING_EXCEPTION;
1385 }
1386 if (record == nullptr) {
1387 clear_archived_roots_of(k);
1388 }
1389 }
1390
1391 void HeapShared::initialize_java_lang_invoke(TRAPS) {
1392 if (CDSConfig::is_using_aot_linked_classes() || CDSConfig::is_dumping_method_handles()) {
1393 resolve_or_init("java/lang/invoke/Invokers$Holder", true, CHECK);
1394 resolve_or_init("java/lang/invoke/MethodHandle", true, CHECK);
1395 resolve_or_init("java/lang/invoke/MethodHandleNatives", true, CHECK);
1396 resolve_or_init("java/lang/invoke/DirectMethodHandle$Holder", true, CHECK);
1397 resolve_or_init("java/lang/invoke/DelegatingMethodHandle$Holder", true, CHECK);
1398 resolve_or_init("java/lang/invoke/LambdaForm$Holder", true, CHECK);
1399 resolve_or_init("java/lang/invoke/BoundMethodHandle$Species_L", true, CHECK);
1400 }
1401 }
1402
1403 // Initialize the InstanceKlasses of objects that are reachable from the following roots:
1404 // - interned strings
1405 // - Klass::java_mirror() -- including aot-initialized mirrors such as those of Enum klasses.
1406 // - ConstantPool::resolved_references()
1407 // - Universe::<xxx>_exception_instance()
1408 //
1409 // For example, if this enum class is initialized at AOT cache assembly time:
1410 //
1411 // enum Fruit {
1412 // APPLE, ORANGE, BANANA;
1413 // static final Set<Fruit> HAVE_SEEDS = new HashSet<>(Arrays.asList(APPLE, ORANGE));
1414 // }
1415 //
1416 // the aot-initialized mirror of Fruit has a static field that references HashSet, which
1417 // should be initialized before any Java code can access the Fruit class. Note that
1418 // HashSet itself doesn't necessary need to be an aot-initialized class.
1419 void HeapShared::init_classes_for_special_subgraph(Handle class_loader, TRAPS) {
1577 ik->initialize(CHECK);
1578 } else if (k->is_objArray_klass()) {
1579 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1580 oak->initialize(CHECK);
1581 }
1582 }
1583 }
1584
1585 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1586 verify_the_heap(k, "before");
1587
1588 Array<int>* entry_field_records = record->entry_field_records();
1589 if (entry_field_records != nullptr) {
1590 int efr_len = entry_field_records->length();
1591 assert(efr_len % 2 == 0, "sanity");
1592 for (int i = 0; i < efr_len; i += 2) {
1593 int field_offset = entry_field_records->at(i);
1594 int root_index = entry_field_records->at(i+1);
1595 // Load the subgraph entry fields from the record and store them back to
1596 // the corresponding fields within the mirror.
1597 oop v = get_root(root_index, /*clear=*/true);
1598 oop m = k->java_mirror();
1599 if (k->has_aot_initialized_mirror()) {
1600 assert(v == m->obj_field(field_offset), "must be aot-initialized");
1601 } else {
1602 m->obj_field_put(field_offset, v);
1603 }
1604 log_debug(aot, heap)(" " PTR_FORMAT " init field @ %2d = " PTR_FORMAT, p2i(k), field_offset, p2i(v));
1605 }
1606
1607 // Done. Java code can see the archived sub-graphs referenced from k's
1608 // mirror after this point.
1609 if (log_is_enabled(Info, aot, heap)) {
1610 ResourceMark rm;
1611 log_info(aot, heap)("initialize_from_archived_subgraph %s " PTR_FORMAT "%s%s",
1612 k->external_name(), p2i(k), JvmtiExport::is_early_phase() ? " (early)" : "",
1613 k->has_aot_initialized_mirror() ? " (aot-inited)" : "");
1614 }
1615 }
1616
1617 verify_the_heap(k, "after ");
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "cds/aotArtifactFinder.hpp"
26 #include "cds/aotCacheAccess.hpp"
27 #include "cds/aotClassInitializer.hpp"
28 #include "cds/aotClassLocation.hpp"
29 #include "cds/aotCompressedPointers.hpp"
30 #include "cds/aotConstantPoolResolver.hpp"
31 #include "cds/aotLogging.hpp"
32 #include "cds/aotMappedHeapLoader.hpp"
33 #include "cds/aotMappedHeapWriter.hpp"
34 #include "cds/aotMetaspace.hpp"
35 #include "cds/aotOopChecker.hpp"
36 #include "cds/aotReferenceObjSupport.hpp"
37 #include "cds/aotStreamedHeapLoader.hpp"
38 #include "cds/aotStreamedHeapWriter.hpp"
39 #include "cds/archiveBuilder.hpp"
40 #include "cds/archiveUtils.hpp"
41 #include "cds/cds_globals.hpp"
42 #include "cds/cdsConfig.hpp"
43 #include "cds/cdsEnumKlass.hpp"
44 #include "cds/cdsHeapVerifier.hpp"
45 #include "cds/heapShared.inline.hpp"
46 #include "cds/regeneratedClasses.hpp"
47 #include "classfile/classLoaderData.hpp"
48 #include "classfile/javaClasses.inline.hpp"
49 #include "classfile/modules.hpp"
50 #include "classfile/stringTable.hpp"
51 #include "classfile/symbolTable.hpp"
52 #include "classfile/systemDictionary.hpp"
53 #include "classfile/systemDictionaryShared.hpp"
54 #include "classfile/vmClasses.hpp"
55 #include "classfile/vmSymbols.hpp"
56 #include "code/aotCodeCache.hpp"
57 #include "gc/shared/collectedHeap.hpp"
58 #include "gc/shared/gcLocker.hpp"
59 #include "gc/shared/gcVMOperations.hpp"
60 #include "logging/log.hpp"
61 #include "logging/logStream.hpp"
62 #include "memory/iterator.inline.hpp"
63 #include "memory/resourceArea.hpp"
64 #include "memory/universe.hpp"
65 #include "oops/compressedOops.inline.hpp"
66 #include "oops/fieldStreams.inline.hpp"
67 #include "oops/objArrayOop.inline.hpp"
68 #include "oops/oop.inline.hpp"
69 #include "oops/oopHandle.inline.hpp"
70 #include "oops/typeArrayOop.inline.hpp"
71 #include "prims/jvmtiExport.hpp"
72 #include "runtime/arguments.hpp"
73 #include "runtime/fieldDescriptor.inline.hpp"
74 #include "runtime/globals_extension.hpp"
75 #include "runtime/init.hpp"
76 #include "runtime/javaCalls.hpp"
116 #endif
117
118
119 //
120 // If you add new entries to the following tables, you should know what you're doing!
121 //
122
123 static ArchivableStaticFieldInfo archive_subgraph_entry_fields[] = {
124 {"java/lang/Integer$IntegerCache", "archivedCache"},
125 {"java/lang/Long$LongCache", "archivedCache"},
126 {"java/lang/Byte$ByteCache", "archivedCache"},
127 {"java/lang/Short$ShortCache", "archivedCache"},
128 {"java/lang/Character$CharacterCache", "archivedCache"},
129 {"java/util/jar/Attributes$Name", "KNOWN_NAMES"},
130 {"sun/util/locale/BaseLocale", "constantBaseLocales"},
131 {"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"},
132 {"java/util/ImmutableCollections", "archivedObjects"},
133 {"java/lang/ModuleLayer", "EMPTY_LAYER"},
134 {"java/lang/module/Configuration", "EMPTY_CONFIGURATION"},
135 {"jdk/internal/math/FDBigInteger", "archivedCaches"},
136 {"java/lang/reflect/Proxy$ProxyBuilder", "archivedData"}, // FIXME -- requires AOTClassLinking
137
138 #ifndef PRODUCT
139 {nullptr, nullptr}, // Extra slot for -XX:ArchiveHeapTestClass
140 #endif
141 {nullptr, nullptr},
142 };
143
144 // full module graph
145 static ArchivableStaticFieldInfo fmg_archive_subgraph_entry_fields[] = {
146 {"jdk/internal/loader/ArchivedClassLoaders", "archivedClassLoaders"},
147 {ARCHIVED_BOOT_LAYER_CLASS, ARCHIVED_BOOT_LAYER_FIELD},
148 {"java/lang/Module$ArchivedData", "archivedData"},
149 {nullptr, nullptr},
150 };
151
152 KlassSubGraphInfo* HeapShared::_dump_time_special_subgraph;
153 ArchivedKlassSubGraphInfoRecord* HeapShared::_run_time_special_subgraph;
154 GrowableArrayCHeap<oop, mtClassShared>* HeapShared::_pending_roots = nullptr;
155 OopHandle HeapShared::_scratch_basic_type_mirrors[T_VOID+1];
156 MetaspaceObjToOopHandleTable* HeapShared::_scratch_objects_table = nullptr;
605 // returned from jdk.internal.misc.CDS::initializeFromArchive().
606 // See HeapShared::initialize_from_archived_subgraph().
607 {
608 AOTArtifactFinder::add_aot_inited_class(InstanceKlass::cast(k));
609 }
610
611 if (java_lang_Class::is_instance(obj)) {
612 Klass* mirror_k = java_lang_Class::as_Klass(obj);
613 if (mirror_k != nullptr) {
614 AOTArtifactFinder::add_cached_class(mirror_k);
615 }
616 } else if (java_lang_invoke_ResolvedMethodName::is_instance(obj)) {
617 Method* m = java_lang_invoke_ResolvedMethodName::vmtarget(obj);
618 if (m != nullptr) {
619 if (RegeneratedClasses::has_been_regenerated(m)) {
620 m = RegeneratedClasses::get_regenerated_object(m);
621 }
622 InstanceKlass* method_holder = m->method_holder();
623 AOTArtifactFinder::add_cached_class(method_holder);
624 }
625 } else if (AOTCodeCache::is_dumping_code() &&
626 (java_lang_invoke_MethodHandle::is_instance(obj) || is_interned_string(obj))) {
627 // Needed by AOT compiler.
628 append_root(obj);
629 }
630 }
631
632 if (log_is_enabled(Debug, aot, heap)) {
633 ResourceMark rm;
634 LogTarget(Debug, aot, heap) log;
635 LogStream out(log);
636 out.print("Archived heap object " PTR_FORMAT " : %s ",
637 p2i(obj), obj->klass()->external_name());
638 if (java_lang_Class::is_instance(obj)) {
639 Klass* k = java_lang_Class::as_Klass(obj);
640 if (k != nullptr) {
641 out.print("%s", k->external_name());
642 } else {
643 out.print("primitive");
644 }
645 }
646 out.cr();
647 }
648
796 if (RegeneratedClasses::is_regenerated_object(ik)) {
797 InstanceKlass* orig_ik = RegeneratedClasses::get_original_object(ik);
798 precond(orig_ik->is_initialized());
799 orig_mirror = orig_ik->java_mirror();
800 } else {
801 precond(ik->is_initialized());
802 orig_mirror = ik->java_mirror();
803 }
804
805 oop m = scratch_java_mirror(ik);
806 int nfields = 0;
807 for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {
808 if (fs.access_flags().is_static()) {
809 fieldDescriptor& fd = fs.field_descriptor();
810 int offset = fd.offset();
811 switch (fd.field_type()) {
812 case T_OBJECT:
813 case T_ARRAY:
814 {
815 oop field_obj = orig_mirror->obj_field(offset);
816 m->obj_field_put(offset, field_obj);
817 if (field_obj != nullptr) {
818 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, field_obj);
819 assert(success, "sanity");
820 }
821 }
822 break;
823 case T_BOOLEAN:
824 m->bool_field_put(offset, orig_mirror->bool_field(offset));
825 break;
826 case T_BYTE:
827 m->byte_field_put(offset, orig_mirror->byte_field(offset));
828 break;
829 case T_SHORT:
830 m->short_field_put(offset, orig_mirror->short_field(offset));
831 break;
832 case T_CHAR:
833 m->char_field_put(offset, orig_mirror->char_field(offset));
834 break;
835 case T_INT:
870 // We need to retain the identity_hash, because it may have been used by some hashtables
871 // in the shared heap.
872 if (!orig_mirror->fast_no_hash_check()) {
873 intptr_t src_hash = orig_mirror->identity_hash();
874 if (UseCompactObjectHeaders) {
875 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
876 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
877 } else {
878 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
879 }
880 assert(scratch_m->mark().is_unlocked(), "sanity");
881
882 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
883 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
884 }
885
886 if (CDSConfig::is_dumping_aot_linked_classes()) {
887 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
888 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
889 }
890
891 Klass* k = java_lang_Class::as_Klass(orig_mirror); // is null Universe::void_mirror();
892 if (CDSConfig::is_dumping_reflection_data() &&
893 k != nullptr && k->is_instance_klass() &&
894 java_lang_Class::reflection_data(orig_mirror) != nullptr &&
895 AOTConstantPoolResolver::can_archive_reflection_data(InstanceKlass::cast(k))) {
896 java_lang_Class::set_reflection_data(scratch_m, java_lang_Class::reflection_data(orig_mirror));
897 }
898 }
899
900 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
901 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
902 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
903 if (rr != nullptr && !HeapShared::is_too_large_to_archive(rr)) {
904 return HeapShared::scratch_resolved_references(src_ik->constants());
905 }
906 }
907 return nullptr;
908 }
909
910 int HeapShared::archive_exception_instance(oop exception) {
911 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, exception);
912 assert(success, "sanity");
913 return append_root(exception);
914 }
915
916 void HeapShared::get_pointer_info(oop src_obj, bool& has_oop_pointers, bool& has_native_pointers) {
917 OopHandle oh(&src_obj);
949 p2i((address)G1CollectedHeap::heap()->reserved().end()));
950 }
951
952 archive_subgraphs();
953 }
954
955 init_seen_objects_table();
956 Universe::archive_exception_instances();
957 }
958
959 void HeapShared::end_scanning_for_oops() {
960 if (is_writing_mapping_mode()) {
961 StringTable::init_shared_table();
962 }
963 delete_seen_objects_table();
964 }
965
966 void HeapShared::write_heap(AOTMappedHeapInfo* mapped_heap_info, AOTStreamedHeapInfo* streamed_heap_info) {
967 {
968 NoSafepointVerifier nsv;
969 if (!SkipArchiveHeapVerification) {
970 CDSHeapVerifier::verify();
971 }
972 check_special_subgraph_classes();
973 }
974
975 if (HeapShared::is_writing_mapping_mode()) {
976 StringTable::write_shared_table();
977 AOTMappedHeapWriter::write(_pending_roots, mapped_heap_info);
978 } else {
979 assert(HeapShared::is_writing_streaming_mode(), "are there more modes?");
980 AOTStreamedHeapWriter::write(_pending_roots, streamed_heap_info);
981 }
982
983 ArchiveBuilder::OtherROAllocMark mark;
984 write_subgraph_info_table();
985
986 delete _pending_roots;
987 _pending_roots = nullptr;
988
989 make_archived_object_cache_gc_safe();
990 }
991
992 void HeapShared::scan_java_mirror(oop orig_mirror) {
993 oop m = scratch_java_mirror(orig_mirror);
994 if (m != nullptr) { // nullptr if for custom class loader
995 copy_java_mirror(orig_mirror, m);
996 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, m);
997 assert(success, "sanity");
998
999 oop extra;
1000 if ((extra = java_lang_Class::reflection_data(m)) != nullptr) {
1001 success = archive_reachable_objects_from(1, _dump_time_special_subgraph, extra);
1002 assert(success, "sanity");
1003 }
1004 }
1005 }
1006
1007 void HeapShared::scan_java_class(Klass* orig_k) {
1008 scan_java_mirror(orig_k->java_mirror());
1009
1010 if (orig_k->is_instance_klass()) {
1011 InstanceKlass* orig_ik = InstanceKlass::cast(orig_k);
1012 orig_ik->constants()->prepare_resolved_references_for_archiving();
1013 objArrayOop rr = get_archived_resolved_references(orig_ik);
1014 if (rr != nullptr) {
1015 bool success = HeapShared::archive_reachable_objects_from(1, _dump_time_special_subgraph, rr);
1016 assert(success, "must be");
1017 }
1018 }
1019 }
1020
1021 void HeapShared::archive_subgraphs() {
1022 assert(CDSConfig::is_dumping_heap(), "must be");
1023
1048 &created);
1049 assert(created, "must not initialize twice");
1050 return info;
1051 }
1052
1053 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
1054 assert(CDSConfig::is_dumping_heap(), "dump time only");
1055 KlassSubGraphInfo* info = _dump_time_subgraph_info_table->get(k);
1056 assert(info != nullptr, "must have been initialized");
1057 return info;
1058 }
1059
1060 // Add an entry field to the current KlassSubGraphInfo.
1061 void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) {
1062 assert(CDSConfig::is_dumping_heap(), "dump time only");
1063 if (_subgraph_entry_fields == nullptr) {
1064 _subgraph_entry_fields =
1065 new (mtClass) GrowableArray<int>(10, mtClass);
1066 }
1067 _subgraph_entry_fields->append(static_field_offset);
1068
1069 // Leyden: Temp fix for JDK-8371655 {
1070 if (v == nullptr) {
1071 _subgraph_entry_fields->append(-1);
1072 } else {
1073 _subgraph_entry_fields->append(HeapShared::append_root(v));
1074 }
1075 // }
1076 }
1077
1078 // Add the Klass* for an object in the current KlassSubGraphInfo's subgraphs.
1079 // Only objects of boot classes can be included in sub-graph.
1080 void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) {
1081 assert(CDSConfig::is_dumping_heap(), "dump time only");
1082
1083 if (_subgraph_object_klasses == nullptr) {
1084 _subgraph_object_klasses =
1085 new (mtClass) GrowableArray<Klass*>(50, mtClass);
1086 }
1087
1088 if (_k == orig_k) {
1089 // Don't add the Klass containing the sub-graph to it's own klass
1090 // initialization list.
1091 return;
1092 }
1093
1094 if (orig_k->is_instance_klass()) {
1095 #ifdef ASSERT
1397 TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name);
1398 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name);
1399 assert(k != nullptr && k->defined_by_boot_loader(), "sanity");
1400 resolve_classes_for_subgraph_of(current, k);
1401 }
1402 }
1403
1404 void HeapShared::resolve_classes_for_subgraph_of(JavaThread* current, Klass* k) {
1405 JavaThread* THREAD = current;
1406 ExceptionMark em(THREAD);
1407 const ArchivedKlassSubGraphInfoRecord* record =
1408 resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/false, THREAD);
1409 if (HAS_PENDING_EXCEPTION) {
1410 CLEAR_PENDING_EXCEPTION;
1411 }
1412 if (record == nullptr) {
1413 clear_archived_roots_of(k);
1414 }
1415 }
1416
1417 static const char* java_lang_invoke_core_klasses[] = {
1418 "java/lang/invoke/Invokers$Holder",
1419 "java/lang/invoke/MethodHandle",
1420 "java/lang/invoke/MethodHandleNatives",
1421 "java/lang/invoke/DirectMethodHandle$Holder",
1422 "java/lang/invoke/DelegatingMethodHandle$Holder",
1423 "java/lang/invoke/LambdaForm$Holder",
1424 "java/lang/invoke/BoundMethodHandle$Species_L",
1425 };
1426
1427 void HeapShared::initialize_java_lang_invoke(TRAPS) {
1428 if (CDSConfig::is_using_aot_linked_classes() || CDSConfig::is_dumping_method_handles()) {
1429 int len = sizeof(java_lang_invoke_core_klasses)/sizeof(char*);
1430 for (int i = 0; i < len; i++) {
1431 resolve_or_init(java_lang_invoke_core_klasses[i], true, CHECK);
1432 }
1433 }
1434 }
1435
1436 // Initialize the InstanceKlasses of objects that are reachable from the following roots:
1437 // - interned strings
1438 // - Klass::java_mirror() -- including aot-initialized mirrors such as those of Enum klasses.
1439 // - ConstantPool::resolved_references()
1440 // - Universe::<xxx>_exception_instance()
1441 //
1442 // For example, if this enum class is initialized at AOT cache assembly time:
1443 //
1444 // enum Fruit {
1445 // APPLE, ORANGE, BANANA;
1446 // static final Set<Fruit> HAVE_SEEDS = new HashSet<>(Arrays.asList(APPLE, ORANGE));
1447 // }
1448 //
1449 // the aot-initialized mirror of Fruit has a static field that references HashSet, which
1450 // should be initialized before any Java code can access the Fruit class. Note that
1451 // HashSet itself doesn't necessary need to be an aot-initialized class.
1452 void HeapShared::init_classes_for_special_subgraph(Handle class_loader, TRAPS) {
1610 ik->initialize(CHECK);
1611 } else if (k->is_objArray_klass()) {
1612 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1613 oak->initialize(CHECK);
1614 }
1615 }
1616 }
1617
1618 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1619 verify_the_heap(k, "before");
1620
1621 Array<int>* entry_field_records = record->entry_field_records();
1622 if (entry_field_records != nullptr) {
1623 int efr_len = entry_field_records->length();
1624 assert(efr_len % 2 == 0, "sanity");
1625 for (int i = 0; i < efr_len; i += 2) {
1626 int field_offset = entry_field_records->at(i);
1627 int root_index = entry_field_records->at(i+1);
1628 // Load the subgraph entry fields from the record and store them back to
1629 // the corresponding fields within the mirror.
1630
1631 // Leyden: Temp fix for JDK-8371655 {
1632 oop v;
1633 if (root_index < 0) {
1634 v = nullptr;
1635 } else {
1636 v = get_root(root_index, /*clear=*/true);
1637 }
1638 // }
1639
1640 oop m = k->java_mirror();
1641 if (k->has_aot_initialized_mirror()) {
1642 assert(v == m->obj_field(field_offset), "must be aot-initialized");
1643 } else {
1644 m->obj_field_put(field_offset, v);
1645 }
1646 log_debug(aot, heap)(" " PTR_FORMAT " init field @ %2d = " PTR_FORMAT, p2i(k), field_offset, p2i(v));
1647 }
1648
1649 // Done. Java code can see the archived sub-graphs referenced from k's
1650 // mirror after this point.
1651 if (log_is_enabled(Info, aot, heap)) {
1652 ResourceMark rm;
1653 log_info(aot, heap)("initialize_from_archived_subgraph %s " PTR_FORMAT "%s%s",
1654 k->external_name(), p2i(k), JvmtiExport::is_early_phase() ? " (early)" : "",
1655 k->has_aot_initialized_mirror() ? " (aot-inited)" : "");
1656 }
1657 }
1658
1659 verify_the_heap(k, "after ");
|