8209971: TestOptionsWithRanges.java crashes in CDS mode with G1UpdateBufferSize=1.
authorjiangli
Fri, 07 Sep 2018 15:18:14 -0400
changeset 51674 d7dcaacb95dd
parent 51673 53e61697a020
child 51675 b487c1e914d0
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
src/hotspot/share/classfile/javaClasses.cpp
src/hotspot/share/classfile/systemDictionary.cpp
src/hotspot/share/memory/metaspaceShared.cpp
src/hotspot/share/memory/metaspaceShared.hpp
src/hotspot/share/memory/universe.cpp
--- 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
     {