< prev index next >

src/hotspot/share/ci/ciInstanceKlass.cpp

Print this page

        

@@ -32,17 +32,41 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #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
 //
 // Loaded instance klass.
 ciInstanceKlass::ciInstanceKlass(Klass* k) :
   ciKlass(k)

@@ -62,10 +86,21 @@
   _is_anonymous = ik->is_anonymous();
   _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
   _has_injected_fields = -1;
   _implementor = NULL; // we will fill these lazily
 
+  oop holder = ik->klass_holder();
+  ensure_metadata_alive(holder);
+  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.
+    // It is enough to record a ciObject, since cached elements are never removed
+    // during ciObjectFactory lifetime. ciObjectFactory itself is created for
+    // every compilation and lives for the whole duration of the compilation.
+    ciObject* h = CURRENT_ENV->get_object(holder);
+  }
+
   Thread *thread = Thread::current();
   if (ciObjectFactory::is_initialized()) {
     _loader = JNIHandles::make_local(thread, ik->class_loader());
     _protection_domain = JNIHandles::make_local(thread,
                                                 ik->protection_domain());
< prev index next >