8185103: TestThreadDumpMonitorContention.java crashed due to SIGSEGV in G1SATBCardTableModRefBS::write_ref_field_pre_work
authorhseigel
Tue, 08 Aug 2017 08:41:36 -0400
changeset 46772 902c68ab7f57
parent 46771 789534dc024a
child 46773 fb17cc9a6847
8185103: TestThreadDumpMonitorContention.java crashed due to SIGSEGV in G1SATBCardTableModRefBS::write_ref_field_pre_work Summary: Ensure that a Klass's mirror is set before putting the Klass on the fixup_module_field_list Reviewed-by: coleenp, dholmes, gtriantafill
hotspot/src/share/vm/classfile/javaClasses.cpp
hotspot/src/share/vm/classfile/javaClasses.hpp
hotspot/src/share/vm/memory/universe.cpp
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Aug 08 02:10:30 2017 +0000
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Aug 08 08:41:36 2017 -0400
@@ -787,12 +787,9 @@
       MutexLocker m1(Module_lock, THREAD);
       // Keep list of classes needing java.base module fixup
       if (!ModuleEntryTable::javabase_defined()) {
-        if (fixup_module_field_list() == NULL) {
-          GrowableArray<Klass*>* list =
-            new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
-          set_fixup_module_field_list(list);
-        }
+        assert(k->java_mirror() != NULL, "Class's mirror is null");
         k->class_loader_data()->inc_keep_alive();
+        assert(fixup_module_field_list() != NULL, "fixup_module_field_list not initialized");
         fixup_module_field_list()->push(k);
       } else {
         javabase_was_defined = true;
@@ -816,10 +813,22 @@
   }
 }
 
+// Statically allocate fixup lists because they always get created.
+void java_lang_Class::allocate_fixup_lists() {
+  GrowableArray<Klass*>* mirror_list =
+    new (ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(40, true);
+  set_fixup_mirror_list(mirror_list);
+
+  GrowableArray<Klass*>* module_list =
+    new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
+  set_fixup_module_field_list(module_list);
+}
+
 void java_lang_Class::create_mirror(Klass* k, Handle class_loader,
                                     Handle module, Handle protection_domain, TRAPS) {
   assert(k != NULL, "Use create_basic_type_mirror for primitive types");
   assert(k->java_mirror() == NULL, "should only assign mirror once");
+
   // Use this moment of initialization to cache modifier_flags also,
   // to support Class.getModifiers().  Instance classes recalculate
   // the cached flags after the class file is parsed, but before the
@@ -878,23 +887,21 @@
     assert(class_loader() == k->class_loader(), "should be same");
     set_class_loader(mirror(), class_loader());
 
-    // set the module field in the java_lang_Class instance
-    set_mirror_module_field(k, mirror, module, THREAD);
-
     // Setup indirection from klass->mirror
     // after any exceptions can happen during allocations.
     k->set_java_mirror(mirror());
+
+    // Set the module field in the java_lang_Class instance.  This must be done
+    // after the mirror is set.
+    set_mirror_module_field(k, mirror, module, THREAD);
+
     if (comp_mirror() != NULL) {
       // Set after k->java_mirror() is published, because compiled code running
       // concurrently doesn't expect a k to have a null java_mirror.
       release_set_array_klass(comp_mirror(), k);
     }
   } else {
-    if (fixup_mirror_list() == NULL) {
-      GrowableArray<Klass*>* list =
-       new (ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(40, true);
-      set_fixup_mirror_list(list);
-    }
+    assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
     fixup_mirror_list()->push(k);
   }
 }
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Tue Aug 08 02:10:30 2017 +0000
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Tue Aug 08 08:41:36 2017 -0400
@@ -212,6 +212,7 @@
   static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain, TRAPS);
   static void set_mirror_module_field(Klass* K, Handle mirror, Handle module, TRAPS);
  public:
+  static void allocate_fixup_lists();
   static void compute_offsets();
 
   // Instance creation
--- a/hotspot/src/share/vm/memory/universe.cpp	Tue Aug 08 02:10:30 2017 +0000
+++ b/hotspot/src/share/vm/memory/universe.cpp	Tue Aug 08 08:41:36 2017 -0400
@@ -320,6 +320,8 @@
 
     { MutexLocker mc(Compile_lock);
 
+      java_lang_Class::allocate_fixup_lists();
+
       // determine base vtable size; without that we cannot create the array klasses
       compute_base_vtable_size();