24
25 #include "cds/aotMetaspace.hpp"
26 #include "cds/aotStreamedHeapLoader.hpp"
27 #include "cds/aotThread.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/filemap.hpp"
30 #include "cds/heapShared.inline.hpp"
31 #include "classfile/classLoaderDataShared.hpp"
32 #include "classfile/javaClasses.inline.hpp"
33 #include "classfile/stringTable.hpp"
34 #include "classfile/vmClasses.hpp"
35 #include "gc/shared/collectedHeap.inline.hpp"
36 #include "gc/shared/oopStorage.inline.hpp"
37 #include "gc/shared/oopStorageSet.inline.hpp"
38 #include "logging/log.hpp"
39 #include "memory/iterator.inline.hpp"
40 #include "memory/oopFactory.hpp"
41 #include "oops/access.inline.hpp"
42 #include "oops/objArrayOop.inline.hpp"
43 #include "oops/oop.inline.hpp"
44 #include "runtime/globals.hpp"
45 #include "runtime/globals_extension.hpp"
46 #include "runtime/handles.inline.hpp"
47 #include "runtime/java.hpp"
48 #include "runtime/mutex.hpp"
49 #include "runtime/thread.hpp"
50 #include "utilities/bitMap.inline.hpp"
51 #include "utilities/exceptions.hpp"
52 #include "utilities/globalDefinitions.hpp"
53 #include "utilities/stack.inline.hpp"
54 #include "utilities/ticks.hpp"
55
56 #include <type_traits>
57
58 #if INCLUDE_CDS_JAVA_HEAP
59
60 FileMapRegion* AOTStreamedHeapLoader::_heap_region;
61 FileMapRegion* AOTStreamedHeapLoader::_bitmap_region;
62 int* AOTStreamedHeapLoader::_roots_archive;
63 OopHandle AOTStreamedHeapLoader::_roots;
978 _bitmap_region = FileMapInfo::current_info()->region_at(AOTMetaspace::bm);
979
980 assert(_heap_region->used() > 0, "empty heap archive?");
981
982 _is_in_use = true;
983
984 // archived roots are at this offset in the stream.
985 size_t roots_offset = FileMapInfo::current_info()->streamed_heap()->roots_offset();
986 size_t forwarding_offset = FileMapInfo::current_info()->streamed_heap()->forwarding_offset();
987 size_t root_highest_object_index_table_offset = FileMapInfo::current_info()->streamed_heap()->root_highest_object_index_table_offset();
988 _num_archived_objects = FileMapInfo::current_info()->streamed_heap()->num_archived_objects();
989
990 // The first int is the length of the array
991 _roots_archive = ((int*)(((address)_heap_region->mapped_base()) + roots_offset)) + 1;
992 _num_roots = _roots_archive[-1];
993 _heap_region_used = _heap_region->used();
994
995 // We can't retire a TLAB until the filler klass is set; set it to the archived object klass.
996 CollectedHeap::set_filler_object_klass(vmClasses::Object_klass());
997
998 objArrayOop roots = oopFactory::new_objectArray(_num_roots, CHECK);
999 _roots = OopHandle(Universe::vm_global(), roots);
1000
1001 _object_index_to_buffer_offset_table = (size_t*)(((address)_heap_region->mapped_base()) + forwarding_offset);
1002 // We allocate the first entry for "null"
1003 _object_index_to_heap_object_table = NEW_C_HEAP_ARRAY(void*, _num_archived_objects + 1, mtClassShared);
1004 Copy::zero_to_bytes(_object_index_to_heap_object_table, (_num_archived_objects + 1) * sizeof(void*));
1005
1006 _root_highest_object_index_table = (int*)(((address)_heap_region->mapped_base()) + root_highest_object_index_table_offset);
1007
1008 address start = (address)(_bitmap_region->mapped_base()) + _heap_region->oopmap_offset();
1009 _oopmap = BitMapView((BitMap::bm_word_t*)start, _heap_region->oopmap_size_in_bits());
1010
1011
1012 if (FLAG_IS_DEFAULT(AOTEagerlyLoadObjects)) {
1013 // Concurrency will not help much if there are no extra cores available.
1014 FLAG_SET_ERGO(AOTEagerlyLoadObjects, os::initial_active_processor_count() <= 1);
1015 }
1016
1017 // If the full module graph is not available or the JVMTI class file load hook is on, we
1018 // will prune the object graph to not include cached objects in subgraphs that are not intended
1034 bool finished_before_gc_allowed = materialize_early(CHECK);
1035 if (finished_before_gc_allowed) {
1036 cleanup();
1037 }
1038 } else {
1039 AOTThread::initialize();
1040 }
1041 }
1042
1043 oop AOTStreamedHeapLoader::materialize_root(int root_index) {
1044 Ticks start = Ticks::now();
1045 // We cannot handle any exception when materializing a root. Exits the VM.
1046 EXCEPTION_MARK
1047 Stack<AOTHeapTraversalEntry, mtClassShared> dfs_stack;
1048 HandleMark hm(THREAD);
1049
1050 oop result;
1051 {
1052 MutexLocker ml(AOTHeapLoading_lock, Mutex::_safepoint_check_flag);
1053
1054 oop root = objArrayOop(_roots.resolve())->obj_at(root_index);
1055
1056 if (root != nullptr) {
1057 // The root has already been materialized
1058 result = root;
1059 } else {
1060 // The root has not been materialized, start tracing materialization
1061 result = TracingObjectLoader::materialize_root(root_index, dfs_stack, CHECK_NULL);
1062 }
1063 }
1064
1065 uint64_t duration = (Ticks::now() - start).nanoseconds();
1066
1067 account_lazy_materialization_time_ns(duration, "root", root_index);
1068
1069 return result;
1070 }
1071
1072 oop AOTStreamedHeapLoader::get_root(int index) {
1073 oop result = objArrayOop(_roots.resolve())->obj_at(index);
1074 if (result == nullptr) {
1075 // Materialize root
1076 result = materialize_root(index);
1077 }
1078 if (result == _roots.resolve()) {
1079 // A self-reference to the roots array acts as a sentinel object for null,
1080 // indicating that the root has been cleared.
1081 result = nullptr;
1082 }
1083 // Acquire the root transitive object payload
1084 OrderAccess::acquire();
1085 return result;
1086 }
1087
1088 void AOTStreamedHeapLoader::clear_root(int index) {
1089 // Self-reference to the roots array acts as a sentinel object for null,
1090 // indicating that the root has been cleared.
1091 objArrayOop(_roots.resolve())->obj_at_put(index, _roots.resolve());
1092 }
1093
|
24
25 #include "cds/aotMetaspace.hpp"
26 #include "cds/aotStreamedHeapLoader.hpp"
27 #include "cds/aotThread.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/filemap.hpp"
30 #include "cds/heapShared.inline.hpp"
31 #include "classfile/classLoaderDataShared.hpp"
32 #include "classfile/javaClasses.inline.hpp"
33 #include "classfile/stringTable.hpp"
34 #include "classfile/vmClasses.hpp"
35 #include "gc/shared/collectedHeap.inline.hpp"
36 #include "gc/shared/oopStorage.inline.hpp"
37 #include "gc/shared/oopStorageSet.inline.hpp"
38 #include "logging/log.hpp"
39 #include "memory/iterator.inline.hpp"
40 #include "memory/oopFactory.hpp"
41 #include "oops/access.inline.hpp"
42 #include "oops/objArrayOop.inline.hpp"
43 #include "oops/oop.inline.hpp"
44 #include "oops/oopCast.inline.hpp"
45 #include "runtime/globals.hpp"
46 #include "runtime/globals_extension.hpp"
47 #include "runtime/handles.inline.hpp"
48 #include "runtime/java.hpp"
49 #include "runtime/mutex.hpp"
50 #include "runtime/thread.hpp"
51 #include "utilities/bitMap.inline.hpp"
52 #include "utilities/exceptions.hpp"
53 #include "utilities/globalDefinitions.hpp"
54 #include "utilities/stack.inline.hpp"
55 #include "utilities/ticks.hpp"
56
57 #include <type_traits>
58
59 #if INCLUDE_CDS_JAVA_HEAP
60
61 FileMapRegion* AOTStreamedHeapLoader::_heap_region;
62 FileMapRegion* AOTStreamedHeapLoader::_bitmap_region;
63 int* AOTStreamedHeapLoader::_roots_archive;
64 OopHandle AOTStreamedHeapLoader::_roots;
979 _bitmap_region = FileMapInfo::current_info()->region_at(AOTMetaspace::bm);
980
981 assert(_heap_region->used() > 0, "empty heap archive?");
982
983 _is_in_use = true;
984
985 // archived roots are at this offset in the stream.
986 size_t roots_offset = FileMapInfo::current_info()->streamed_heap()->roots_offset();
987 size_t forwarding_offset = FileMapInfo::current_info()->streamed_heap()->forwarding_offset();
988 size_t root_highest_object_index_table_offset = FileMapInfo::current_info()->streamed_heap()->root_highest_object_index_table_offset();
989 _num_archived_objects = FileMapInfo::current_info()->streamed_heap()->num_archived_objects();
990
991 // The first int is the length of the array
992 _roots_archive = ((int*)(((address)_heap_region->mapped_base()) + roots_offset)) + 1;
993 _num_roots = _roots_archive[-1];
994 _heap_region_used = _heap_region->used();
995
996 // We can't retire a TLAB until the filler klass is set; set it to the archived object klass.
997 CollectedHeap::set_filler_object_klass(vmClasses::Object_klass());
998
999 refArrayOop roots = oopFactory::new_objectArray(_num_roots, CHECK);
1000 _roots = OopHandle(Universe::vm_global(), roots);
1001
1002 _object_index_to_buffer_offset_table = (size_t*)(((address)_heap_region->mapped_base()) + forwarding_offset);
1003 // We allocate the first entry for "null"
1004 _object_index_to_heap_object_table = NEW_C_HEAP_ARRAY(void*, _num_archived_objects + 1, mtClassShared);
1005 Copy::zero_to_bytes(_object_index_to_heap_object_table, (_num_archived_objects + 1) * sizeof(void*));
1006
1007 _root_highest_object_index_table = (int*)(((address)_heap_region->mapped_base()) + root_highest_object_index_table_offset);
1008
1009 address start = (address)(_bitmap_region->mapped_base()) + _heap_region->oopmap_offset();
1010 _oopmap = BitMapView((BitMap::bm_word_t*)start, _heap_region->oopmap_size_in_bits());
1011
1012
1013 if (FLAG_IS_DEFAULT(AOTEagerlyLoadObjects)) {
1014 // Concurrency will not help much if there are no extra cores available.
1015 FLAG_SET_ERGO(AOTEagerlyLoadObjects, os::initial_active_processor_count() <= 1);
1016 }
1017
1018 // If the full module graph is not available or the JVMTI class file load hook is on, we
1019 // will prune the object graph to not include cached objects in subgraphs that are not intended
1035 bool finished_before_gc_allowed = materialize_early(CHECK);
1036 if (finished_before_gc_allowed) {
1037 cleanup();
1038 }
1039 } else {
1040 AOTThread::initialize();
1041 }
1042 }
1043
1044 oop AOTStreamedHeapLoader::materialize_root(int root_index) {
1045 Ticks start = Ticks::now();
1046 // We cannot handle any exception when materializing a root. Exits the VM.
1047 EXCEPTION_MARK
1048 Stack<AOTHeapTraversalEntry, mtClassShared> dfs_stack;
1049 HandleMark hm(THREAD);
1050
1051 oop result;
1052 {
1053 MutexLocker ml(AOTHeapLoading_lock, Mutex::_safepoint_check_flag);
1054
1055 oop root = oop_cast<refArrayOop>(_roots.resolve())->obj_at(root_index);
1056
1057 if (root != nullptr) {
1058 // The root has already been materialized
1059 result = root;
1060 } else {
1061 // The root has not been materialized, start tracing materialization
1062 result = TracingObjectLoader::materialize_root(root_index, dfs_stack, CHECK_NULL);
1063 }
1064 }
1065
1066 uint64_t duration = (Ticks::now() - start).nanoseconds();
1067
1068 account_lazy_materialization_time_ns(duration, "root", root_index);
1069
1070 return result;
1071 }
1072
1073 oop AOTStreamedHeapLoader::get_root(int index) {
1074 oop result = oop_cast<refArrayOop>(_roots.resolve())->obj_at(index);
1075 if (result == nullptr) {
1076 // Materialize root
1077 result = materialize_root(index);
1078 }
1079 if (result == _roots.resolve()) {
1080 // A self-reference to the roots array acts as a sentinel object for null,
1081 // indicating that the root has been cleared.
1082 result = nullptr;
1083 }
1084 // Acquire the root transitive object payload
1085 OrderAccess::acquire();
1086 return result;
1087 }
1088
1089 void AOTStreamedHeapLoader::clear_root(int index) {
1090 // Self-reference to the roots array acts as a sentinel object for null,
1091 // indicating that the root has been cleared.
1092 objArrayOop(_roots.resolve())->obj_at_put(index, _roots.resolve());
1093 }
1094
|