8191567: Refactor ciInstanceKlass G1 keep alive barrier to use Access API.
authoreosterlund
Mon, 08 Jan 2018 13:22:05 +0100
changeset 48614 c39ae979ca35
parent 48613 d8bdf14c4f1e
child 48615 31cd0c16f4d2
child 48619 1703d83b3ffe
8191567: Refactor ciInstanceKlass G1 keep alive barrier to use Access API. Reviewed-by: dholmes, rkennke, tschatzl
src/hotspot/share/ci/ciInstanceKlass.cpp
src/hotspot/share/classfile/classLoaderData.hpp
src/hotspot/share/oops/instanceKlass.cpp
src/hotspot/share/oops/instanceKlass.hpp
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp	Mon Jan 08 13:13:05 2018 +0100
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp	Mon Jan 08 13:22:05 2018 +0100
@@ -34,35 +34,12 @@
 #include "oops/oop.inline.hpp"
 #include "oops/fieldStreams.hpp"
 #include "runtime/fieldDescriptor.hpp"
-#if INCLUDE_ALL_GCS
-# include "gc/g1/g1SATBCardTableModRefBS.hpp"
-#endif
 
 // ciInstanceKlass
 //
 // This class represents a Klass* in the HotSpot virtual machine
 // whose Klass part in an InstanceKlass.
 
-// ------------------------------------------------------------------
-// ensure_metadata_alive
-//
-// Ensure that the metadata wrapped by the ciMetadata is kept alive by GC.
-// This is primarily useful for metadata which is considered as weak roots
-// by the GC but need to be strong roots if reachable from a current compilation.
-// InstanceKlass are created for both weak and strong metadata.  Ensuring this metadata
-// alive covers the cases where there are weak roots without performance cost.
-//
-static void ensure_metadata_alive(oop metadata_holder) {
-#if INCLUDE_ALL_GCS
-  if (!UseG1GC) {
-    return;
-  }
-  if (metadata_holder != NULL) {
-    G1SATBCardTableModRefBS::enqueue(metadata_holder);
-  }
-#endif
-}
-
 
 // ------------------------------------------------------------------
 // ciInstanceKlass::ciInstanceKlass
@@ -88,8 +65,12 @@
   _has_injected_fields = -1;
   _implementor = NULL; // we will fill these lazily
 
-  oop holder = ik->klass_holder();
-  ensure_metadata_alive(holder);
+  // Ensure that the metadata wrapped by the ciMetadata is kept alive by GC.
+  // This is primarily useful for metadata which is considered as weak roots
+  // by the GC but need to be strong roots if reachable from a current compilation.
+  // InstanceKlass are created for both weak and strong metadata.  Ensuring this metadata
+  // alive covers the cases where there are weak roots without performance cost.
+  oop holder = ik->klass_holder_phantom();
   if (ik->is_anonymous()) {
     // Though ciInstanceKlass records class loader oop, it's not enough to keep
     // VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
--- a/src/hotspot/share/classfile/classLoaderData.hpp	Mon Jan 08 13:13:05 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderData.hpp	Mon Jan 08 13:22:05 2018 +0100
@@ -217,6 +217,7 @@
   friend class ClassLoaderDataGraphKlassIteratorAtomic;
   friend class ClassLoaderDataGraphKlassIteratorStatic;
   friend class ClassLoaderDataGraphMetaspaceIterator;
+  friend class InstanceKlass;
   friend class MetaDataFactory;
   friend class Method;
 
--- a/src/hotspot/share/oops/instanceKlass.cpp	Mon Jan 08 13:13:05 2018 +0100
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Mon Jan 08 13:22:05 2018 +0100
@@ -3421,6 +3421,15 @@
   }
 }
 
+oop InstanceKlass::klass_holder_phantom() {
+  oop* addr;
+  if (is_anonymous()) {
+    addr = _java_mirror.ptr_raw();
+  } else {
+    addr = &class_loader_data()->_class_loader;
+  }
+  return RootAccess<IN_CONCURRENT_ROOT | ON_PHANTOM_OOP_REF>::oop_load(addr);
+}
 
 #ifdef ASSERT
 void InstanceKlass::set_init_state(ClassState state) {
--- a/src/hotspot/share/oops/instanceKlass.hpp	Mon Jan 08 13:13:05 2018 +0100
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Mon Jan 08 13:22:05 2018 +0100
@@ -640,6 +640,11 @@
     return is_anonymous() ? java_mirror() : class_loader();
   }
 
+  // Load the klass_holder as a phantom. This is useful when a weak Klass
+  // pointer has been "peeked" and then must be kept alive before it may
+  // be used safely.
+  oop klass_holder_phantom();
+
   bool is_contended() const                {
     return (_misc_flags & _misc_is_contended) != 0;
   }