--- old/src/hotspot/share/classfile/javaClasses.cpp 2019-10-16 19:29:40.684297727 -0700 +++ new/src/hotspot/share/classfile/javaClasses.cpp 2019-10-16 19:29:40.428288452 -0700 @@ -1215,15 +1215,26 @@ return archived_mirror; } +void java_lang_Class::update_archived_primitive_mirror_native_pointers(oop archived_mirror) { + if (MetaspaceShared::mapping_delta() != 0) { + assert(archived_mirror->metadata_field(_klass_offset) == NULL, "must be for primitive class"); + + Klass* ak = ((Klass*)archived_mirror->metadata_field(_array_klass_offset)); + if (ak != NULL) { + archived_mirror->metadata_field_put(_array_klass_offset, (Klass*)(address(ak) + MetaspaceShared::mapping_delta())); + } + } +} + void java_lang_Class::update_archived_mirror_native_pointers(oop archived_mirror) { - Klass* k = ((Klass*)archived_mirror->metadata_field(_klass_offset)); - if (k != NULL) { // k is NULL for the primitive classes such as java.lang.Byte::TYPE + if (MetaspaceShared::mapping_delta() != 0) { + Klass* k = ((Klass*)archived_mirror->metadata_field(_klass_offset)); archived_mirror->metadata_field_put(_klass_offset, (Klass*)(address(k) + MetaspaceShared::mapping_delta())); - } - Klass* ak = ((Klass*)archived_mirror->metadata_field(_array_klass_offset)); - if (ak != NULL) { - archived_mirror->metadata_field_put(_array_klass_offset, (Klass*)(address(ak) + MetaspaceShared::mapping_delta())); + Klass* ak = ((Klass*)archived_mirror->metadata_field(_array_klass_offset)); + if (ak != NULL) { + archived_mirror->metadata_field_put(_array_klass_offset, (Klass*)(address(ak) + MetaspaceShared::mapping_delta())); + } } } @@ -1243,16 +1254,15 @@ } oop m = HeapShared::materialize_archived_object(k->archived_java_mirror_raw_narrow()); - if (m == NULL) { return false; } - log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m)); - update_archived_mirror_native_pointers(m); - // mirror is archived, restore + log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m)); assert(HeapShared::is_archived_object(m), "must be archived mirror object"); + update_archived_mirror_native_pointers(m); + assert(as_Klass(m) == k, "must be"); Handle mirror(THREAD, m); if (!k->is_array_klass()) { --- old/src/hotspot/share/classfile/javaClasses.hpp 2019-10-16 19:29:41.376322799 -0700 +++ new/src/hotspot/share/classfile/javaClasses.hpp 2019-10-16 19:29:41.116313379 -0700 @@ -272,6 +272,7 @@ Handle protection_domain, TRAPS); static void fixup_mirror(Klass* k, TRAPS); static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS); + static void update_archived_primitive_mirror_native_pointers(oop archived_mirror) NOT_CDS_JAVA_HEAP_RETURN; static void update_archived_mirror_native_pointers(oop archived_mirror) NOT_CDS_JAVA_HEAP_RETURN; // Archiving --- old/src/hotspot/share/memory/dynamicArchive.cpp 2019-10-16 19:29:42.028346422 -0700 +++ new/src/hotspot/share/memory/dynamicArchive.cpp 2019-10-16 19:29:41.772337147 -0700 @@ -137,11 +137,9 @@ // Translate it to point to the output space, so that it can be compared with // Symbols in the base archive. a_name = (Symbol*)(address(a_name) + _method_comparator_name_delta); - //tty->print_cr("%p", a_name); } if (!MetaspaceShared::is_in_shared_metaspace(b_name)) { b_name = (Symbol*)(address(b_name) + _method_comparator_name_delta); - //tty->print_cr("%p", b_name); } return a_name->fast_compare(b_name); --- old/src/hotspot/share/memory/filemap.cpp 2019-10-16 19:29:42.676369901 -0700 +++ new/src/hotspot/share/memory/filemap.cpp 2019-10-16 19:29:42.424360770 -0700 @@ -602,8 +602,11 @@ return path_array; } -bool FileMapInfo::fail(const char* msg, const char* name) { +bool FileMapInfo::classpath_failure(const char* msg, const char* name) { ClassLoader::trace_class_path(msg, name); + if (PrintSharedArchiveAndExit) { + MetaspaceShared::set_archive_loading_failed(); + } return false; } @@ -678,7 +681,7 @@ if (mismatch) { // The paths are different - return fail("[BOOT classpath mismatch, actual =", runtime_boot_path); + return classpath_failure("[BOOT classpath mismatch, actual =", runtime_boot_path); } return true; } @@ -689,7 +692,7 @@ int rp_len = num_paths(appcp); bool mismatch = false; if (rp_len < shared_app_paths_len) { - return fail("Run time APP classpath is shorter than the one at dump time: ", appcp); + return classpath_failure("Run time APP classpath is shorter than the one at dump time: ", appcp); } if (shared_app_paths_len != 0 && rp_len != 0) { // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar. @@ -697,7 +700,7 @@ GrowableArray* rp_array = create_path_array(appcp); if (rp_array->length() == 0) { // None of the jar file specified in the runtime -cp exists. - return fail("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp); + return classpath_failure("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp); } // Handling of non-existent entries in the classpath: we eliminate all the non-existent @@ -712,7 +715,7 @@ int j = header()->app_class_paths_start_index(); mismatch = check_paths(j, shared_app_paths_len, rp_array); if (mismatch) { - return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp); + return classpath_failure("[APP classpath mismatch, actual: -Djava.class.path=", appcp); } } return true; --- old/src/hotspot/share/memory/filemap.hpp 2019-10-16 19:29:43.348394249 -0700 +++ new/src/hotspot/share/memory/filemap.hpp 2019-10-16 19:29:43.092384973 -0700 @@ -534,7 +534,7 @@ char* skip_first_path_entry(const char* path) NOT_CDS_RETURN_(NULL); int num_paths(const char* path) NOT_CDS_RETURN_(0); GrowableArray* create_path_array(const char* path) NOT_CDS_RETURN_(NULL); - bool fail(const char* msg, const char* name) NOT_CDS_RETURN_(false); + bool classpath_failure(const char* msg, const char* name) NOT_CDS_RETURN_(false); bool check_paths(int shared_path_start_idx, int num_paths, GrowableArray* rp_array) NOT_CDS_RETURN_(false); bool validate_boot_class_paths() NOT_CDS_RETURN_(false); --- old/src/hotspot/share/memory/iterator.hpp 2019-10-16 19:29:43.992417581 -0700 +++ new/src/hotspot/share/memory/iterator.hpp 2019-10-16 19:29:43.736408306 -0700 @@ -347,9 +347,6 @@ // Read/write the oop virtual void do_oop(oop* o) = 0; - // Read/write a oop that's the type of java.lang.Class - virtual void do_mirror_oop(oop* o) = 0; - bool writing() { return !reading(); } --- old/src/hotspot/share/memory/metaspaceShared.cpp 2019-10-16 19:29:44.632440770 -0700 +++ new/src/hotspot/share/memory/metaspaceShared.cpp 2019-10-16 19:29:44.376431495 -0700 @@ -1992,14 +1992,6 @@ } } -void ReadClosure::do_mirror_oop(oop *p) { - do_oop(p); - oop mirror = *p; - if (mirror != NULL) { - java_lang_Class::update_archived_mirror_native_pointers(mirror); - } -} - void ReadClosure::do_region(u_char* start, size_t size) { assert((intptr_t)start % sizeof(intptr_t) == 0, "bad alignment"); assert(size % sizeof(intptr_t) == 0, "bad size"); --- old/src/hotspot/share/memory/metaspaceShared.hpp 2019-10-16 19:29:45.300464973 -0700 +++ new/src/hotspot/share/memory/metaspaceShared.hpp 2019-10-16 19:29:45.044455698 -0700 @@ -135,8 +135,6 @@ void do_oop(oop* o); - void do_mirror_oop(oop* o) { do_oop(o); } - void do_region(u_char* start, size_t size); bool reading() const { return false; } @@ -166,8 +164,6 @@ void do_oop(oop *p); - void do_mirror_oop(oop* o); - void do_region(u_char* start, size_t size); bool reading() const { return true; } --- old/src/hotspot/share/memory/universe.cpp 2019-10-16 19:29:45.944488306 -0700 +++ new/src/hotspot/share/memory/universe.cpp 2019-10-16 19:29:45.688479030 -0700 @@ -85,18 +85,24 @@ #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::_int_mirror = NULL; -oop Universe::_float_mirror = NULL; -oop Universe::_double_mirror = NULL; -oop Universe::_byte_mirror = NULL; -oop Universe::_bool_mirror = NULL; -oop Universe::_char_mirror = NULL; -oop Universe::_long_mirror = NULL; -oop Universe::_short_mirror = NULL; -oop Universe::_void_mirror = NULL; oop Universe::_mirrors[T_VOID+1] = { NULL /*, NULL...*/ }; oop Universe::_main_thread_group = NULL; oop Universe::_system_thread_group = NULL; @@ -167,17 +173,11 @@ } } -void Universe::oops_do(OopClosure* f) { +#define DO_PRIMITIVE_MIRROR(m) \ + f->do_oop((oop*) &m); - f->do_oop((oop*) &_int_mirror); - f->do_oop((oop*) &_float_mirror); - f->do_oop((oop*) &_double_mirror); - f->do_oop((oop*) &_byte_mirror); - f->do_oop((oop*) &_bool_mirror); - f->do_oop((oop*) &_char_mirror); - f->do_oop((oop*) &_long_mirror); - f->do_oop((oop*) &_short_mirror); - f->do_oop((oop*) &_void_mirror); +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((oop*) &_mirrors[i]); @@ -231,6 +231,13 @@ _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) { @@ -239,25 +246,12 @@ } f->do_ptr((void**)&_objectArrayKlassObj); + #if INCLUDE_CDS_JAVA_HEAP -#ifdef ASSERT - if (DumpSharedSpaces && !HeapShared::is_heap_object_archiving_allowed()) { - assert(_int_mirror == NULL && _float_mirror == NULL && - _double_mirror == NULL && _byte_mirror == NULL && - _bool_mirror == NULL && _char_mirror == NULL && - _long_mirror == NULL && _short_mirror == NULL && - _void_mirror == NULL, "mirrors should be NULL"); - } -#endif - f->do_mirror_oop(&_int_mirror); - f->do_mirror_oop(&_float_mirror); - f->do_mirror_oop(&_double_mirror); - f->do_mirror_oop(&_byte_mirror); - f->do_mirror_oop(&_bool_mirror); - f->do_mirror_oop(&_char_mirror); - f->do_mirror_oop(&_long_mirror); - f->do_mirror_oop(&_short_mirror); - f->do_mirror_oop(&_void_mirror); + 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); @@ -424,18 +418,18 @@ #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) { assert(HeapShared::is_heap_object_archiving_allowed(), "Sanity"); - assert(_float_mirror != NULL && _double_mirror != NULL && - _byte_mirror != NULL && _byte_mirror != NULL && - _bool_mirror != NULL && _char_mirror != NULL && - _long_mirror != NULL && _short_mirror != NULL && - _void_mirror != NULL, "Sanity"); + PRIMITIVE_MIRRORS_DO(ASSERT_MIRROR_NOT_NULL); } else + // _int_mirror could be NULL if archived heap is not mapped. #endif { _int_mirror = --- old/test/hotspot/jtreg/TEST.groups 2019-10-16 19:29:46.604512219 -0700 +++ new/test/hotspot/jtreg/TEST.groups 2019-10-16 19:29:46.340502654 -0700 @@ -325,6 +325,7 @@ -runtime/cds/appcds/javaldr/GCSharedStringsDuringDump.java \ -runtime/cds/appcds/javaldr/HumongousDuringDump.java \ -runtime/cds/appcds/sharedStrings \ + -runtime/cds/appcds/ArchiveRelocationTest.java \ -runtime/cds/appcds/DumpClassList.java \ -runtime/cds/appcds/ExtraSymbols.java \ -runtime/cds/appcds/LongClassListPath.java \