8204585: Remove IN_ARCHIVE_ROOT from Access API
authorkbarrett
Tue, 12 Jun 2018 18:12:59 -0400
changeset 50532 a18c60527166
parent 50531 aeb7fb702890
child 50533 7c5fbc953121
child 50546 52b866a1a63a
8204585: Remove IN_ARCHIVE_ROOT from Access API Summary: Replaced Access API with API on heap. Reviewed-by: jiangli, coleenp, tschatzl Contributed-by: stefan.karlsson@oracle.com, kim.barrett@oracle.com
src/hotspot/share/classfile/javaClasses.cpp
src/hotspot/share/classfile/javaClasses.hpp
src/hotspot/share/gc/g1/g1BarrierSet.hpp
src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp
src/hotspot/share/gc/g1/g1CollectedHeap.cpp
src/hotspot/share/gc/g1/g1CollectedHeap.hpp
src/hotspot/share/gc/z/zBarrierSet.cpp
src/hotspot/share/memory/metaspaceShared.cpp
src/hotspot/share/memory/metaspaceShared.hpp
src/hotspot/share/oops/access.hpp
src/hotspot/share/oops/accessDecorators.hpp
src/hotspot/share/oops/cpCache.cpp
src/hotspot/share/oops/klass.cpp
src/hotspot/share/oops/klass.hpp
--- a/src/hotspot/share/classfile/javaClasses.cpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Tue Jun 12 18:12:59 2018 -0400
@@ -63,7 +63,6 @@
 #include "runtime/vframe.inline.hpp"
 #include "utilities/align.hpp"
 #include "utilities/preserveException.hpp"
-
 #if INCLUDE_JVMCI
 #include "jvmci/jvmciJavaClasses.hpp"
 #endif
@@ -798,7 +797,7 @@
       // During bootstrap, java.lang.Class wasn't loaded so static field
       // offsets were computed without the size added it.  Go back and
       // update all the static field offsets to included the size.
-        for (JavaFieldStream fs(InstanceKlass::cast(k)); !fs.done(); fs.next()) {
+      for (JavaFieldStream fs(InstanceKlass::cast(k)); !fs.done(); fs.next()) {
         if (fs.access_flags().is_static()) {
           int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
           fs.set_offset(real_offset);
@@ -809,12 +808,8 @@
 
   if (k->is_shared() && k->has_raw_archived_mirror()) {
     if (MetaspaceShared::open_archive_heap_region_mapped()) {
-      oop m = k->archived_java_mirror();
-      assert(m != NULL, "archived mirror is NULL");
-      assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
-      Handle m_h(THREAD, m);
-      // restore_archived_mirror() clears the klass' _has_raw_archived_mirror flag
-      restore_archived_mirror(k, m_h, Handle(), Handle(), Handle(), CHECK);
+      bool present = restore_archived_mirror(k, Handle(), Handle(), Handle(), CHECK);
+      assert(present, "Missing archived mirror for %s", k->external_name());
       return;
     } else {
       k->set_java_mirror_handle(NULL);
@@ -1207,11 +1202,23 @@
   return archived_mirror;
 }
 
-// After the archived mirror object is restored, the shared klass'
-// _has_raw_archived_mirror flag is cleared
-void java_lang_Class::restore_archived_mirror(Klass *k, Handle mirror,
+// Returns true if the mirror is updated, false if no archived mirror
+// data is present. After the archived mirror object is restored, the
+// shared klass' _has_raw_archived_mirror flag is cleared.
+bool java_lang_Class::restore_archived_mirror(Klass *k,
                                               Handle class_loader, Handle module,
                                               Handle protection_domain, TRAPS) {
+  oop m = MetaspaceShared::materialize_archived_object(k->archived_java_mirror_raw());
+
+  if (m == NULL) {
+    return false;
+  }
+
+  log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
+
+  // mirror is archived, restore
+  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
@@ -1221,7 +1228,7 @@
     // - local static final fields with initial values were initialized at dump time
 
     // create the init_lock
-    typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
+    typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_(false));
     set_init_lock(mirror(), r);
 
     if (protection_domain.not_null()) {
@@ -1241,6 +1248,8 @@
 
   ResourceMark rm;
   log_trace(cds, mirror)("Restored %s archived mirror " PTR_FORMAT, k->external_name(), p2i(mirror()));
+
+  return true;
 }
 #endif // INCLUDE_CDS_JAVA_HEAP
 
--- a/src/hotspot/share/classfile/javaClasses.hpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Tue Jun 12 18:12:59 2018 -0400
@@ -229,8 +229,9 @@
   static oop  archive_mirror(Klass* k, TRAPS) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
   static oop  process_archived_mirror(Klass* k, oop mirror, oop archived_mirror, Thread *THREAD)
                                       NOT_CDS_JAVA_HEAP_RETURN_(NULL);
-  static void restore_archived_mirror(Klass *k, Handle mirror, Handle class_loader, Handle module,
-                                      Handle protection_domain, TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
+  static bool restore_archived_mirror(Klass *k, Handle class_loader, Handle module,
+                                      Handle protection_domain,
+                                      TRAPS) NOT_CDS_JAVA_HEAP_RETURN_(false);
 
   static void fixup_module_field(Klass* k, Handle module);
 
--- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp	Tue Jun 12 18:12:59 2018 -0400
@@ -50,7 +50,7 @@
   // pre-marking object graph.
   static void enqueue(oop pre_val);
 
-  static void enqueue_if_weak_or_archive(DecoratorSet decorators, oop value);
+  static void enqueue_if_weak(DecoratorSet decorators, oop value);
 
   template <class T> void write_ref_array_pre_work(T* dst, size_t count);
   virtual void write_ref_array_pre(oop* dst, size_t count, bool dest_uninitialized);
--- a/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp	Tue Jun 12 18:12:59 2018 -0400
@@ -54,15 +54,14 @@
   }
 }
 
-inline void G1BarrierSet::enqueue_if_weak_or_archive(DecoratorSet decorators, oop value) {
+inline void G1BarrierSet::enqueue_if_weak(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;
+  // Loading from a weak or phantom reference needs enqueueing, as
+  // the object may not have been reachable (part of the snapshot)
+  // when marking started.
   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);
+  const bool needs_enqueue     = (!peek && !on_strong_oop_ref);
 
   if (needs_enqueue && value != NULL) {
     enqueue(value);
@@ -74,7 +73,7 @@
 inline oop G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
 oop_load_not_in_heap(T* addr) {
   oop value = ModRef::oop_load_not_in_heap(addr);
-  enqueue_if_weak_or_archive(decorators, value);
+  enqueue_if_weak(decorators, value);
   return value;
 }
 
@@ -83,7 +82,7 @@
 inline oop G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
 oop_load_in_heap(T* addr) {
   oop value = ModRef::oop_load_in_heap(addr);
-  enqueue_if_weak_or_archive(decorators, value);
+  enqueue_if_weak(decorators, value);
   return value;
 }
 
@@ -91,7 +90,7 @@
 inline oop G1BarrierSet::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_or_archive(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
+  enqueue_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
   return value;
 }
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Tue Jun 12 18:12:59 2018 -0400
@@ -78,6 +78,7 @@
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/compressedOops.inline.hpp"
@@ -823,6 +824,18 @@
   decrease_used(size_used);
 }
 
+oop G1CollectedHeap::materialize_archived_object(oop obj) {
+  assert(obj != NULL, "archived obj is NULL");
+  assert(MetaspaceShared::is_archive_object(obj), "must be archived object");
+
+  // Loading an archived object makes it strongly reachable. If it is
+  // loaded during concurrent marking, it must be enqueued to the SATB
+  // queue, shading the previously white object gray.
+  G1BarrierSet::enqueue(obj);
+
+  return obj;
+}
+
 HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size) {
   ResourceMark rm; // For retrieving the thread names in log messages.
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Tue Jun 12 18:12:59 2018 -0400
@@ -699,6 +699,8 @@
   // mapping failed, with the same non-overlapping and sorted MemRegion array.
   void dealloc_archive_regions(MemRegion* range, size_t count);
 
+  oop materialize_archived_object(oop obj);
+
 private:
 
   // Shrink the garbage-first heap by at most the given size (in bytes!).
--- a/src/hotspot/share/gc/z/zBarrierSet.cpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/z/zBarrierSet.cpp	Tue Jun 12 18:12:59 2018 -0400
@@ -45,7 +45,6 @@
 bool ZBarrierSet::barrier_needed(DecoratorSet decorators, BasicType type) {
   assert((decorators & AS_RAW) == 0, "Unexpected decorator");
   assert((decorators & AS_NO_KEEPALIVE) == 0, "Unexpected decorator");
-  assert((decorators & IN_ARCHIVE_ROOT) == 0, "Unexpected decorator");
   //assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Unexpected decorator");
 
   if (type == T_OBJECT || type == T_ARRAY) {
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Tue Jun 12 18:12:59 2018 -0400
@@ -1910,6 +1910,11 @@
   return archived_oop;
 }
 
+oop MetaspaceShared::materialize_archived_object(oop obj) {
+  assert(obj != NULL, "sanity");
+  return G1CollectedHeap::heap()->materialize_archived_object(obj);
+}
+
 void MetaspaceShared::archive_klass_objects(Thread* THREAD) {
   int i;
   for (i = 0; i < _global_klass_objects->length(); i++) {
@@ -1980,7 +1985,7 @@
              "Archived heap object is not allowed");
       assert(MetaspaceShared::open_archive_heap_region_mapped(),
              "Open archive heap region is not mapped");
-      RootAccess<IN_ARCHIVE_ROOT>::oop_store(p, CompressedOops::decode_not_null(o));
+      *p = CompressedOops::decode_not_null(o);
     }
   }
 
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Tue Jun 12 18:12:59 2018 -0400
@@ -111,6 +111,7 @@
   }
   static oop find_archived_heap_object(oop obj);
   static oop archive_heap_object(oop obj, Thread* THREAD);
+  static oop materialize_archived_object(oop obj);
   static void archive_klass_objects(Thread* THREAD);
 #endif
 
--- a/src/hotspot/share/oops/access.hpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/access.hpp	Tue Jun 12 18:12:59 2018 -0400
@@ -379,8 +379,7 @@
     (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_ARCHIVE_ROOT)) == 0
+    (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0
   ));
 }
 
--- a/src/hotspot/share/oops/accessDecorators.hpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/accessDecorators.hpp	Tue Jun 12 18:12:59 2018 -0400
@@ -192,10 +192,8 @@
 const DecoratorSet IN_HEAP_ARRAY      = UCONST64(1) << 21;
 const DecoratorSet IN_ROOT            = UCONST64(1) << 22;
 const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 23;
-const DecoratorSet IN_ARCHIVE_ROOT    = UCONST64(1) << 24;
 const DecoratorSet IN_DECORATOR_MASK  = IN_HEAP | IN_HEAP_ARRAY |
-                                        IN_ROOT | IN_CONCURRENT_ROOT |
-                                        IN_ARCHIVE_ROOT;
+                                        IN_ROOT | IN_CONCURRENT_ROOT;
 
 // == Value Decorators ==
 // * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
@@ -245,9 +243,7 @@
       ((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 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;
+    static const DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
   };
 
   // This function implements the above DecoratorFixup rules, but without meta
@@ -268,9 +264,7 @@
       ((IN_HEAP_ARRAY & barrier_strength_default) != 0 ? IN_HEAP : INTERNAL_EMPTY);
     DecoratorSet conc_root_is_root = heap_array_is_in_heap |
       ((IN_CONCURRENT_ROOT & heap_array_is_in_heap) != 0 ? IN_ROOT : INTERNAL_EMPTY);
-    DecoratorSet archive_root_is_root = conc_root_is_root |
-      ((IN_ARCHIVE_ROOT & conc_root_is_root) != 0 ? IN_ROOT : INTERNAL_EMPTY);
-    DecoratorSet value = archive_root_is_root | BT_BUILDTIME_DECORATORS;
+    DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
     return value;
   }
 }
--- a/src/hotspot/share/oops/cpCache.cpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/cpCache.cpp	Tue Jun 12 18:12:59 2018 -0400
@@ -32,6 +32,7 @@
 #include "logging/log.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/access.inline.hpp"
@@ -743,16 +744,15 @@
 
 #if INCLUDE_CDS_JAVA_HEAP
 oop ConstantPoolCache::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);
+  if (CompressedOops::is_null(_archived_references)) {
+    return NULL;
+  }
+  return MetaspaceShared::materialize_archived_object(CompressedOops::decode_not_null(_archived_references));
 }
 
 void ConstantPoolCache::set_archived_references(oop o) {
   assert(DumpSharedSpaces, "called only during runtime");
-  RootAccess<IN_ARCHIVE_ROOT>::oop_store(&_archived_references, o);
+  _archived_references = CompressedOops::encode(o);
 }
 #endif
 
--- a/src/hotspot/share/oops/klass.cpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/klass.cpp	Tue Jun 12 18:12:59 2018 -0400
@@ -529,20 +529,19 @@
   Handle module_handle(THREAD, ((module_entry != NULL) ? module_entry->module() : (oop)NULL));
 
   if (this->has_raw_archived_mirror()) {
+    ResourceMark rm;
     log_debug(cds, mirror)("%s has raw archived mirror", external_name());
     if (MetaspaceShared::open_archive_heap_region_mapped()) {
-      oop m = archived_java_mirror();
-      log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
-      if (m != NULL) {
-        // mirror is archived, restore
-        assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
-        Handle m_h(THREAD, m);
-        java_lang_Class::restore_archived_mirror(this, m_h, loader, module_handle, protection_domain, CHECK);
+      bool present = java_lang_Class::restore_archived_mirror(this, loader, module_handle,
+                                                              protection_domain,
+                                                              CHECK);
+      if (present) {
         return;
       }
     }
 
     // No archived mirror data
+    log_debug(cds, mirror)("No archived mirror data for %s", external_name());
     _java_mirror = NULL;
     this->clear_has_raw_archived_mirror();
   }
@@ -558,18 +557,10 @@
 #if INCLUDE_CDS_JAVA_HEAP
 // Used at CDS dump time to access the archived mirror. No GC barrier.
 oop Klass::archived_java_mirror_raw() {
-  assert(DumpSharedSpaces, "called only during runtime");
   assert(has_raw_archived_mirror(), "must have raw archived mirror");
   return CompressedOops::decode(_archived_mirror);
 }
 
-// Used at CDS runtime to get the archived mirror from shared class. Uses GC barrier.
-oop Klass::archived_java_mirror() {
-  assert(UseSharedSpaces, "UseSharedSpaces expected.");
-  assert(has_raw_archived_mirror(), "must have raw archived mirror");
-  return RootAccess<IN_ARCHIVE_ROOT>::oop_load(&_archived_mirror);
-}
-
 // No GC barrier
 void Klass::set_archived_java_mirror_raw(oop m) {
   assert(DumpSharedSpaces, "called only during runtime");
--- a/src/hotspot/share/oops/klass.hpp	Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/klass.hpp	Tue Jun 12 18:12:59 2018 -0400
@@ -244,7 +244,6 @@
   void set_java_mirror(Handle m);
 
   oop archived_java_mirror_raw() NOT_CDS_JAVA_HEAP_RETURN_(NULL); // no GC barrier
-  oop archived_java_mirror() NOT_CDS_JAVA_HEAP_RETURN_(NULL);     // accessor with GC barrier
   void set_archived_java_mirror_raw(oop m) NOT_CDS_JAVA_HEAP_RETURN; // no GC barrier
 
   // Temporary mirror switch used by RedefineClasses