--- old/src/hotspot/share/classfile/javaClasses.cpp 2020-07-23 21:40:53.809573507 -0400 +++ new/src/hotspot/share/classfile/javaClasses.cpp 2020-07-23 21:40:53.317560722 -0400 @@ -1121,8 +1121,9 @@ assert(HeapShared::is_heap_object_archiving_allowed(), "HeapShared::is_heap_object_archiving_allowed() must be true"); - for (int t = 0; t <= T_VOID; t++) { - oop m = Universe::_mirrors[t]; + for (int t = T_BOOLEAN; t < T_VOID+1; t++) { + BasicType bt = (BasicType)t; + oop m = Universe::_mirrors[t].resolve(); if (m != NULL) { // Update the field at _array_klass_offset to point to the relocated array klass. oop archived_m = HeapShared::archive_heap_object(m, THREAD); @@ -1142,33 +1143,12 @@ log_trace(cds, heap, mirror)( "Archived %s mirror object from " PTR_FORMAT " ==> " PTR_FORMAT, - type2name((BasicType)t), p2i(Universe::_mirrors[t]), p2i(archived_m)); + type2name(bt), p2i(m), p2i(archived_m)); - Universe::_mirrors[t] = archived_m; + Universe::replace_mirror(bt, archived_m); } } - - assert(Universe::_mirrors[T_INT] != NULL && - Universe::_mirrors[T_FLOAT] != NULL && - Universe::_mirrors[T_DOUBLE] != NULL && - Universe::_mirrors[T_BYTE] != NULL && - Universe::_mirrors[T_BOOLEAN] != NULL && - Universe::_mirrors[T_CHAR] != NULL && - Universe::_mirrors[T_LONG] != NULL && - Universe::_mirrors[T_SHORT] != NULL && - Universe::_mirrors[T_VOID] != NULL, "sanity"); - - Universe::set_int_mirror(Universe::_mirrors[T_INT]); - Universe::set_float_mirror(Universe::_mirrors[T_FLOAT]); - Universe::set_double_mirror(Universe::_mirrors[T_DOUBLE]); - Universe::set_byte_mirror(Universe::_mirrors[T_BYTE]); - Universe::set_bool_mirror(Universe::_mirrors[T_BOOLEAN]); - Universe::set_char_mirror(Universe::_mirrors[T_CHAR]); - Universe::set_long_mirror(Universe::_mirrors[T_LONG]); - Universe::set_short_mirror(Universe::_mirrors[T_SHORT]); - Universe::set_void_mirror(Universe::_mirrors[T_VOID]); } - // // After the mirror object is successfully archived, the archived // klass is set with _has_archived_raw_mirror flag. --- old/src/hotspot/share/memory/metaspaceShared.cpp 2020-07-23 21:40:54.425589515 -0400 +++ new/src/hotspot/share/memory/metaspaceShared.cpp 2020-07-23 21:40:53.961577457 -0400 @@ -714,19 +714,6 @@ } } -static void clear_basic_type_mirrors() { - assert(!HeapShared::is_heap_object_archiving_allowed(), "Sanity"); - Universe::set_int_mirror(NULL); - Universe::set_float_mirror(NULL); - Universe::set_double_mirror(NULL); - Universe::set_byte_mirror(NULL); - Universe::set_bool_mirror(NULL); - Universe::set_char_mirror(NULL); - Universe::set_long_mirror(NULL); - Universe::set_short_mirror(NULL); - Universe::set_void_mirror(NULL); -} - static void rewrite_nofast_bytecode(const methodHandle& method) { BytecodeStream bcs(method); while (!bcs.is_last_bytecode()) { @@ -1540,7 +1527,7 @@ log_info(cds)("Removing java_mirror ... "); if (!HeapShared::is_heap_object_archiving_allowed()) { - clear_basic_type_mirrors(); + Universe::clear_basic_type_mirrors(); } remove_java_mirror_in_classes(); log_info(cds)("done. "); @@ -2092,7 +2079,7 @@ void ReadClosure::do_oop(oop *p) { narrowOop o = (narrowOop)nextPtr(); if (o == 0 || !HeapShared::open_archive_heap_region_mapped()) { - p = NULL; + *p = NULL; } else { assert(HeapShared::is_heap_object_archiving_allowed(), "Archived heap object is not allowed"); --- old/src/hotspot/share/memory/universe.cpp 2020-07-23 21:40:55.037605418 -0400 +++ new/src/hotspot/share/memory/universe.cpp 2020-07-23 21:40:54.545592633 -0400 @@ -88,25 +88,10 @@ #include "utilities/ostream.hpp" #include "utilities/preserveException.hpp" -#define PRIMITIVE_MIRRORS_DO(func) \ - func(_int_mirror) \ - func(_float_mirror) \ - func(_double_mirror) \ - func(_byte_mirror) \ - func(_bool_mirror) \ - func(_char_mirror) \ - func(_long_mirror) \ - func(_short_mirror) \ - func(_void_mirror) - -#define DEFINE_PRIMITIVE_MIRROR(m) \ - oop Universe::m = NULL; - // Known objects -PRIMITIVE_MIRRORS_DO(DEFINE_PRIMITIVE_MIRROR) Klass* Universe::_typeArrayKlassObjs[T_LONG+1] = { NULL /*, NULL...*/ }; Klass* Universe::_objectArrayKlassObj = NULL; -oop Universe::_mirrors[T_VOID+1] = { NULL /*, NULL...*/ }; +OopHandle Universe::_mirrors[T_VOID+1]; OopHandle Universe::_main_thread_group; OopHandle Universe::_system_thread_group; @@ -196,6 +181,35 @@ oop Universe::the_null_sentinel() { return _the_null_sentinel.resolve(); } +oop Universe::int_mirror() { return check_mirror(_mirrors[T_INT].resolve()); } +oop Universe::float_mirror() { return check_mirror(_mirrors[T_FLOAT].resolve()); } +oop Universe::double_mirror() { return check_mirror(_mirrors[T_DOUBLE].resolve()); } +oop Universe::byte_mirror() { return check_mirror(_mirrors[T_BYTE].resolve()); } +oop Universe::bool_mirror() { return check_mirror(_mirrors[T_BOOLEAN].resolve()); } +oop Universe::char_mirror() { return check_mirror(_mirrors[T_CHAR].resolve()); } +oop Universe::long_mirror() { return check_mirror(_mirrors[T_LONG].resolve()); } +oop Universe::short_mirror() { return check_mirror(_mirrors[T_SHORT].resolve()); } +oop Universe::void_mirror() { return check_mirror(_mirrors[T_VOID].resolve()); } + +oop Universe::java_mirror(BasicType t) { + assert((uint)t < T_VOID+1, "range check"); + return check_mirror(_mirrors[t].resolve()); +} + +// Used by CDS dumping +void Universe::replace_mirror(BasicType t, oop new_mirror) { + Universe::_mirrors[t].replace(new_mirror); +} + +// Not sure why CDS has to do this +void Universe::clear_basic_type_mirrors() { + for (int i = T_BOOLEAN; i < T_VOID+1; i++) { + if (!is_reference_type((BasicType)i)) { + Universe::_mirrors[i].replace(NULL); + } + } +} + void Universe::basic_type_classes_do(void f(Klass*)) { for (int i = T_BOOLEAN; i < T_LONG+1; i++) { f(_typeArrayKlassObjs[i]); @@ -208,16 +222,7 @@ } } -#define DO_PRIMITIVE_MIRROR(m) \ - f->do_oop((oop*) &m); - void Universe::oops_do(OopClosure* f) { - PRIMITIVE_MIRRORS_DO(DO_PRIMITIVE_MIRROR); - - for (int i = T_BOOLEAN; i < T_VOID+1; i++) { - f->do_oop(&_mirrors[i]); - } - assert(_mirrors[0] == NULL && _mirrors[T_BOOLEAN - 1] == NULL, "checking"); f->do_oop(&_reference_pending_list); ThreadsSMRSupport::exiting_threads_oops_do(f); @@ -247,29 +252,33 @@ _do_stack_walk_cache->metaspace_pointers_do(it); } -#define ASSERT_MIRROR_NULL(m) \ - assert(m == NULL, "archived mirrors should be NULL"); - -#define SERIALIZE_MIRROR(m) \ - f->do_oop(&m); \ - if (m != NULL) { java_lang_Class::update_archived_primitive_mirror_native_pointers(m); } - // Serialize metadata and pointers to primitive type mirrors in and out of CDS archive void Universe::serialize(SerializeClosure* f) { +#if INCLUDE_CDS_JAVA_HEAP + { + oop mirror_oop; + for (int i = T_BOOLEAN; i < T_VOID+1; i++) { + if (f->reading()) { + f->do_oop(&mirror_oop); // read from archive + assert(oopDesc::is_oop_or_null(mirror_oop), "is oop"); + _mirrors[i] = OopHandle(vm_global(), mirror_oop); + } else { + mirror_oop = _mirrors[i].resolve(); + f->do_oop(&mirror_oop); // write to archive + } + if (mirror_oop != NULL) { // may be null if archived heap is disabled + java_lang_Class::update_archived_primitive_mirror_native_pointers(mirror_oop); + } + } + } +#endif + for (int i = 0; i < T_LONG+1; i++) { f->do_ptr((void**)&_typeArrayKlassObjs[i]); } f->do_ptr((void**)&_objectArrayKlassObj); - -#if INCLUDE_CDS_JAVA_HEAP - DEBUG_ONLY(if (DumpSharedSpaces && !HeapShared::is_heap_object_archiving_allowed()) { - PRIMITIVE_MIRRORS_DO(ASSERT_MIRROR_NULL); - }); - PRIMITIVE_MIRRORS_DO(SERIALIZE_MIRROR); -#endif - f->do_ptr((void**)&_the_array_interfaces_array); f->do_ptr((void**)&_the_empty_int_array); f->do_ptr((void**)&_the_empty_short_array); @@ -283,6 +292,7 @@ _do_stack_walk_cache->serialize(f); } + void Universe::check_alignment(uintx size, uintx alignment, const char* name) { if (size < alignment || size % alignment != 0) { vm_exit_during_initialization( @@ -434,51 +444,32 @@ #endif } -#define ASSERT_MIRROR_NOT_NULL(m) \ - assert(m != NULL, "archived mirrors should not be NULL"); - void Universe::initialize_basic_type_mirrors(TRAPS) { #if INCLUDE_CDS_JAVA_HEAP if (UseSharedSpaces && HeapShared::open_archive_heap_region_mapped() && - _int_mirror != NULL) { + _mirrors[T_INT].resolve() != NULL) { assert(HeapShared::is_heap_object_archiving_allowed(), "Sanity"); - PRIMITIVE_MIRRORS_DO(ASSERT_MIRROR_NOT_NULL); + + // check that all mirrors are mapped also + for (int i = T_BOOLEAN; i < T_VOID+1; i++) { + if (!is_reference_type((BasicType)i)) { + oop m = _mirrors[i].resolve(); + assert(m != NULL, "archived mirrors should not be NULL"); + } + } } else - // _int_mirror could be NULL if archived heap is not mapped. + // _mirror[T_INT} could be NULL if archived heap is not mapped. #endif { - _int_mirror = - java_lang_Class::create_basic_type_mirror("int", T_INT, CHECK); - _float_mirror = - java_lang_Class::create_basic_type_mirror("float", T_FLOAT, CHECK); - _double_mirror = - java_lang_Class::create_basic_type_mirror("double", T_DOUBLE, CHECK); - _byte_mirror = - java_lang_Class::create_basic_type_mirror("byte", T_BYTE, CHECK); - _bool_mirror = - java_lang_Class::create_basic_type_mirror("boolean",T_BOOLEAN, CHECK); - _char_mirror = - java_lang_Class::create_basic_type_mirror("char", T_CHAR, CHECK); - _long_mirror = - java_lang_Class::create_basic_type_mirror("long", T_LONG, CHECK); - _short_mirror = - java_lang_Class::create_basic_type_mirror("short", T_SHORT, CHECK); - _void_mirror = - java_lang_Class::create_basic_type_mirror("void", T_VOID, CHECK); + for (int i = T_BOOLEAN; i < T_VOID+1; i++) { + BasicType bt = (BasicType)i; + if (!is_reference_type(bt)) { + oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK); + _mirrors[i] = OopHandle(vm_global(), m); + } + } } - - _mirrors[T_INT] = _int_mirror; - _mirrors[T_FLOAT] = _float_mirror; - _mirrors[T_DOUBLE] = _double_mirror; - _mirrors[T_BYTE] = _byte_mirror; - _mirrors[T_BOOLEAN] = _bool_mirror; - _mirrors[T_CHAR] = _char_mirror; - _mirrors[T_LONG] = _long_mirror; - _mirrors[T_SHORT] = _short_mirror; - _mirrors[T_VOID] = _void_mirror; - //_mirrors[T_OBJECT] = _object_klass->java_mirror(); - //_mirrors[T_ARRAY] = _object_klass->java_mirror(); } void Universe::fixup_mirrors(TRAPS) { --- old/src/hotspot/share/memory/universe.hpp 2020-07-23 21:40:55.625620699 -0400 +++ new/src/hotspot/share/memory/universe.hpp 2020-07-23 21:40:55.153608433 -0400 @@ -95,18 +95,6 @@ static Klass* _objectArrayKlassObj; // Known objects in the VM - - // Primitive objects - static oop _int_mirror; - static oop _float_mirror; - static oop _double_mirror; - static oop _byte_mirror; - static oop _bool_mirror; - static oop _char_mirror; - static oop _long_mirror; - static oop _short_mirror; - static oop _void_mirror; - static OopHandle _main_thread_group; // Reference to the main thread group object static OopHandle _system_thread_group; // Reference to the system thread group object @@ -232,33 +220,24 @@ } // Known objects in the VM - static oop int_mirror() { return check_mirror(_int_mirror); } - static oop float_mirror() { return check_mirror(_float_mirror); } - static oop double_mirror() { return check_mirror(_double_mirror); } - static oop byte_mirror() { return check_mirror(_byte_mirror); } - static oop bool_mirror() { return check_mirror(_bool_mirror); } - static oop char_mirror() { return check_mirror(_char_mirror); } - static oop long_mirror() { return check_mirror(_long_mirror); } - static oop short_mirror() { return check_mirror(_short_mirror); } - static oop void_mirror() { return check_mirror(_void_mirror); } - - static void set_int_mirror(oop m) { _int_mirror = m; } - static void set_float_mirror(oop m) { _float_mirror = m; } - static void set_double_mirror(oop m) { _double_mirror = m; } - static void set_byte_mirror(oop m) { _byte_mirror = m; } - static void set_bool_mirror(oop m) { _bool_mirror = m; } - static void set_char_mirror(oop m) { _char_mirror = m; } - static void set_long_mirror(oop m) { _long_mirror = m; } - static void set_short_mirror(oop m) { _short_mirror = m; } - static void set_void_mirror(oop m) { _void_mirror = m; } - - // table of same - static oop _mirrors[T_VOID+1]; - - static oop java_mirror(BasicType t) { - assert((uint)t < T_VOID+1, "range check"); - return check_mirror(_mirrors[t]); - } + static oop int_mirror(); + static oop float_mirror(); + static oop double_mirror(); + static oop byte_mirror(); + static oop bool_mirror(); + static oop char_mirror(); + static oop long_mirror(); + static oop short_mirror(); + static oop void_mirror(); + + // Table of primitive type mirrors, excluding T_OBJECT and T_ARRAY + // but including T_VOID, hence the index including T_VOID + static OopHandle _mirrors[T_VOID+1]; + + static oop java_mirror(BasicType t); + static void replace_mirror(BasicType t, oop obj); + static void clear_basic_type_mirrors(); + static oop main_thread_group(); static void set_main_thread_group(oop group); --- old/src/hotspot/share/oops/oopHandle.hpp 2020-07-23 21:40:56.177635044 -0400 +++ new/src/hotspot/share/oops/oopHandle.hpp 2020-07-23 21:40:55.717623090 -0400 @@ -52,6 +52,8 @@ inline void release(OopStorage* storage); + inline void replace(oop obj); + // Used only for removing handle. oop* ptr_raw() const { return _obj; } }; --- old/src/hotspot/share/oops/oopHandle.inline.hpp 2020-07-23 21:40:56.721649181 -0400 +++ new/src/hotspot/share/oops/oopHandle.inline.hpp 2020-07-23 21:40:56.257637123 -0400 @@ -54,4 +54,10 @@ } } +inline void OopHandle::replace(oop obj) { + oop* ptr = ptr_raw(); + assert(ptr != NULL, "should not use replace"); + NativeAccess<>::oop_store(ptr, obj); +} + #endif // SHARE_OOPS_OOPHANDLE_INLINE_HPP