8194741: Refactor oops in constant pool from CDS to use the Access API
authoreosterlund
Wed, 10 Jan 2018 22:43:42 +0100
changeset 48784 899b522ed65c
parent 48783 bade224cc81e
child 48785 4d1970962ee9
8194741: Refactor oops in constant pool from CDS to use the Access API Reviewed-by: coleenp, jiangli
src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp
src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp
src/hotspot/share/oops/access.hpp
src/hotspot/share/oops/access.inline.hpp
src/hotspot/share/oops/constantPool.cpp
src/hotspot/share/oops/cpCache.cpp
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp	Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp	Wed Jan 10 22:43:42 2018 +0100
@@ -54,7 +54,7 @@
   // pre-marking object graph.
   static void enqueue(oop pre_val);
 
-  static void enqueue_if_weak(DecoratorSet decorators, oop value);
+  static void enqueue_if_weak_or_archive(DecoratorSet decorators, oop value);
 
   template <class T> void write_ref_array_pre_work(T* dst, int count);
   virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized);
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp	Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp	Wed Jan 10 22:43:42 2018 +0100
@@ -60,12 +60,17 @@
   _byte_map[card_index] = val;
 }
 
-inline void G1SATBCardTableModRefBS::enqueue_if_weak(DecoratorSet decorators, oop value) {
+inline void G1SATBCardTableModRefBS::enqueue_if_weak_or_archive(DecoratorSet decorators, oop value) {
   assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known");
+  // Archive roots need to be enqueued since they add subgraphs to the
+  // Java heap that were not there at the snapshot when marking started.
+  // Weak and phantom references also need enqueueing for similar reasons.
+  const bool in_archive_root   = (decorators & IN_ARCHIVE_ROOT) != 0;
   const bool on_strong_oop_ref = (decorators & ON_STRONG_OOP_REF) != 0;
   const bool peek              = (decorators & AS_NO_KEEPALIVE) != 0;
+  const bool needs_enqueue     = in_archive_root || (!peek && !on_strong_oop_ref);
 
-  if (!peek && !on_strong_oop_ref && value != NULL) {
+  if (needs_enqueue && value != NULL) {
     enqueue(value);
   }
 }
@@ -75,7 +80,7 @@
 inline oop G1SATBCardTableLoggingModRefBS::AccessBarrier<decorators, BarrierSetT>::
 oop_load_not_in_heap(T* addr) {
   oop value = ModRef::oop_load_not_in_heap(addr);
-  enqueue_if_weak(decorators, value);
+  enqueue_if_weak_or_archive(decorators, value);
   return value;
 }
 
@@ -84,7 +89,7 @@
 inline oop G1SATBCardTableLoggingModRefBS::AccessBarrier<decorators, BarrierSetT>::
 oop_load_in_heap(T* addr) {
   oop value = ModRef::oop_load_in_heap(addr);
-  enqueue_if_weak(decorators, value);
+  enqueue_if_weak_or_archive(decorators, value);
   return value;
 }
 
@@ -92,7 +97,7 @@
 inline oop G1SATBCardTableLoggingModRefBS::AccessBarrier<decorators, BarrierSetT>::
 oop_load_in_heap_at(oop base, ptrdiff_t offset) {
   oop value = ModRef::oop_load_in_heap_at(base, offset);
-  enqueue_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
+  enqueue_if_weak_or_archive(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
   return value;
 }
 
--- a/src/hotspot/share/oops/access.hpp	Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/oops/access.hpp	Wed Jan 10 22:43:42 2018 +0100
@@ -200,12 +200,14 @@
 const DecoratorSet IN_HEAP_ARRAY      = UCONST64(1) << 19;
 const DecoratorSet IN_ROOT            = UCONST64(1) << 20;
 const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 21;
+const DecoratorSet IN_ARCHIVE_ROOT    = UCONST64(1) << 22;
 const DecoratorSet IN_DECORATOR_MASK  = IN_HEAP | IN_HEAP_ARRAY |
-                                        IN_ROOT | IN_CONCURRENT_ROOT;
+                                        IN_ROOT | IN_CONCURRENT_ROOT |
+                                        IN_ARCHIVE_ROOT;
 
 // == Value Decorators ==
 // * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
-const DecoratorSet OOP_NOT_NULL       = UCONST64(1) << 22;
+const DecoratorSet OOP_NOT_NULL       = UCONST64(1) << 23;
 const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
 
 // == Arraycopy Decorators ==
--- a/src/hotspot/share/oops/access.inline.hpp	Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/oops/access.inline.hpp	Wed Jan 10 22:43:42 2018 +0100
@@ -788,7 +788,9 @@
       ((IN_HEAP_ARRAY & barrier_strength_default) != 0 ? IN_HEAP : INTERNAL_EMPTY);
     static const DecoratorSet conc_root_is_root = heap_array_is_in_heap |
       ((IN_CONCURRENT_ROOT & heap_array_is_in_heap) != 0 ? IN_ROOT : INTERNAL_EMPTY);
-    static const DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
+    static const DecoratorSet archive_root_is_root = conc_root_is_root |
+      ((IN_ARCHIVE_ROOT & conc_root_is_root) != 0 ? IN_ROOT : INTERNAL_EMPTY);
+    static const DecoratorSet value = archive_root_is_root | BT_BUILDTIME_DECORATORS;
   };
 
   // Step 2: Reduce types.
@@ -1082,7 +1084,8 @@
     (location_decorators ^ IN_ROOT) == 0 ||
     (location_decorators ^ IN_HEAP) == 0 ||
     (location_decorators ^ (IN_HEAP | IN_HEAP_ARRAY)) == 0 ||
-    (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0
+    (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0 ||
+    (location_decorators ^ (IN_ROOT | IN_ARCHIVE_ROOT)) == 0
   ));
 }
 
--- a/src/hotspot/share/oops/constantPool.cpp	Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/oops/constantPool.cpp	Wed Jan 10 22:43:42 2018 +0100
@@ -49,9 +49,6 @@
 #include "runtime/signature.hpp"
 #include "runtime/vframe.hpp"
 #include "utilities/copy.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1SATBCardTableModRefBS.hpp"
-#endif // INCLUDE_ALL_GCS
 
 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
   Array<u1>* tags = MetadataFactory::new_array<u1>(loader_data, length, 0, CHECK_NULL);
@@ -330,17 +327,13 @@
   if (SystemDictionary::Object_klass_loaded()) {
     ClassLoaderData* loader_data = pool_holder()->class_loader_data();
 #if INCLUDE_CDS_JAVA_HEAP
-    if (MetaspaceShared::open_archive_heap_region_mapped() &&
-        _cache->archived_references() != NULL) {
+    if (MetaspaceShared::open_archive_heap_region_mapped()) {
       oop archived = _cache->archived_references();
-      // Make sure GC knows the cached object is now live. This is necessary after
-      // initial GC marking and during concurrent marking as strong roots are only
-      // scanned during initial marking (at the start of the GC marking).
-      assert(UseG1GC, "Requires G1 GC");
-      G1SATBCardTableModRefBS::enqueue(archived);
-      // Create handle for the archived resolved reference array object
-      Handle refs_handle(THREAD, (oop)archived);
-      set_resolved_references(loader_data->add_handle(refs_handle));
+      if (archived != NULL) {
+        // Create handle for the archived resolved reference array object
+        Handle refs_handle(THREAD, archived);
+        set_resolved_references(loader_data->add_handle(refs_handle));
+      }
     } else
 #endif
     {
--- a/src/hotspot/share/oops/cpCache.cpp	Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/oops/cpCache.cpp	Wed Jan 10 22:43:42 2018 +0100
@@ -33,6 +33,7 @@
 #include "memory/metaspaceClosure.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
+#include "oops/access.inline.hpp"
 #include "oops/cpCache.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -753,13 +754,16 @@
 
 #if INCLUDE_CDS_JAVA_HEAP
 oop ConstantPoolCache::archived_references() {
-  assert(UseSharedSpaces, "UseSharedSpaces expected.");
-  return oopDesc::decode_heap_oop(_archived_references);
+  // Loading an archive root forces the oop to become strongly reachable.
+  // For example, if it is loaded during concurrent marking in a SATB
+  // collector, it will be enqueued to the SATB queue, effectively
+  // shading the previously white object gray.
+  return RootAccess<IN_ARCHIVE_ROOT>::oop_load(&_archived_references);
 }
 
 void ConstantPoolCache::set_archived_references(oop o) {
   assert(DumpSharedSpaces, "called only during runtime");
-  _archived_references = oopDesc::encode_heap_oop(o);
+  RootAccess<IN_ARCHIVE_ROOT>::oop_store(&_archived_references, o);
 }
 #endif