8209971: TestOptionsWithRanges.java crashes in CDS mode with G1UpdateBufferSize=1.
Summary: Fixup archive heap regions before restoring any archived java object at runtime.
Reviewed-by: iklam, ccheung
--- a/src/hotspot/share/classfile/javaClasses.cpp Fri Sep 07 14:44:52 2018 -0400
+++ b/src/hotspot/share/classfile/javaClasses.cpp Fri Sep 07 15:18:14 2018 -0400
@@ -1213,6 +1213,14 @@
bool java_lang_Class::restore_archived_mirror(Klass *k,
Handle class_loader, Handle module,
Handle protection_domain, TRAPS) {
+ // Postpone restoring archived mirror until java.lang.Class is loaded. Please
+ // see more details in SystemDictionary::resolve_preloaded_classes().
+ if (!SystemDictionary::Class_klass_loaded()) {
+ assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
+ fixup_mirror_list()->push(k);
+ return true;
+ }
+
oop m = MetaspaceShared::materialize_archived_object(k->archived_java_mirror_raw_narrow());
if (m == NULL) {
@@ -1225,10 +1233,6 @@
assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
Handle mirror(THREAD, m);
- // The java.lang.Class field offsets were archived and reloaded from archive.
- // No need to put classes on the fixup_mirror_list before java.lang.Class
- // is loaded.
-
if (!k->is_array_klass()) {
// - local static final fields with initial values were initialized at dump time
--- a/src/hotspot/share/classfile/systemDictionary.cpp Fri Sep 07 14:44:52 2018 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Fri Sep 07 15:18:14 2018 -0400
@@ -2028,6 +2028,22 @@
#if INCLUDE_CDS
if (UseSharedSpaces) {
resolve_wk_klasses_through(WK_KLASS_ENUM_NAME(Object_klass), scan, CHECK);
+
+ // It's unsafe to access the archived heap regions before they
+ // are fixed up, so we must do the fixup as early as possible
+ // before the archived java objects are accessed by functions
+ // such as java_lang_Class::restore_archived_mirror and
+ // ConstantPool::restore_unshareable_info (restores the archived
+ // resolved_references array object).
+ //
+ // MetaspaceShared::fixup_mapped_heap_regions() fills the empty
+ // spaces in the archived heap regions and may use
+ // SystemDictionary::Object_klass(), so we can do this only after
+ // Object_klass is resolved. See the above resolve_wk_klasses_through()
+ // call. No mirror objects are accessed/restored in the above call.
+ // Mirrors are restored after java.lang.Class is loaded.
+ MetaspaceShared::fixup_mapped_heap_regions();
+
// Initialize the constant pool for the Object_class
Object_klass()->constants()->restore_unshareable_info(CHECK);
resolve_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
--- a/src/hotspot/share/memory/metaspaceShared.cpp Fri Sep 07 14:44:52 2018 -0400
+++ b/src/hotspot/share/memory/metaspaceShared.cpp Fri Sep 07 15:18:14 2018 -0400
@@ -76,6 +76,7 @@
bool MetaspaceShared::_archive_loading_failed = false;
bool MetaspaceShared::_remapped_readwrite = false;
bool MetaspaceShared::_open_archive_heap_region_mapped = false;
+bool MetaspaceShared::_archive_heap_region_fixed = false;
address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
size_t MetaspaceShared::_core_spaces_size = 0;
@@ -1940,6 +1941,8 @@
}
oop MetaspaceShared::materialize_archived_object(narrowOop v) {
+ assert(archive_heap_region_fixed(),
+ "must be called after archive heap regions are fixed");
if (!CompressedOops::is_null(v)) {
oop obj = HeapShared::decode_with_archived_oop_encoding_mode(v);
return G1CollectedHeap::heap()->materialize_archived_object(obj);
@@ -1970,6 +1973,7 @@
void MetaspaceShared::fixup_mapped_heap_regions() {
FileMapInfo *mapinfo = FileMapInfo::current_info();
mapinfo->fixup_mapped_heap_regions();
+ set_archive_heap_region_fixed();
}
#endif // INCLUDE_CDS_JAVA_HEAP
--- a/src/hotspot/share/memory/metaspaceShared.hpp Fri Sep 07 14:44:52 2018 -0400
+++ b/src/hotspot/share/memory/metaspaceShared.hpp Fri Sep 07 15:18:14 2018 -0400
@@ -59,6 +59,7 @@
static bool _archive_loading_failed;
static bool _remapped_readwrite;
static bool _open_archive_heap_region_mapped;
+ static bool _archive_heap_region_fixed;
static address _cds_i2i_entry_code_buffers;
static size_t _cds_i2i_entry_code_buffers_size;
static size_t _core_spaces_size;
@@ -114,6 +115,14 @@
static oop archive_heap_object(oop obj, Thread* THREAD);
static oop materialize_archived_object(narrowOop v);
static void archive_klass_objects(Thread* THREAD);
+
+ static void set_archive_heap_region_fixed() {
+ _archive_heap_region_fixed = true;
+ }
+
+ static bool archive_heap_region_fixed() {
+ return _archive_heap_region_fixed;
+ }
#endif
static bool is_archive_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
--- a/src/hotspot/share/memory/universe.cpp Fri Sep 07 14:44:52 2018 -0400
+++ b/src/hotspot/share/memory/universe.cpp Fri Sep 07 15:18:14 2018 -0400
@@ -332,7 +332,6 @@
SystemDictionary::Cloneable_klass(), "u3");
assert(_the_array_interfaces_array->at(1) ==
SystemDictionary::Serializable_klass(), "u3");
- MetaspaceShared::fixup_mapped_heap_regions();
} else
#endif
{