src/hotspot/share/ci/ciInstanceKlass.cpp
changeset 47887 e20d8f168bb6
parent 47551 4d034d861e13
child 48614 c39ae979ca35
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp	Mon Nov 13 14:53:28 2017 -0500
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp	Mon Nov 13 17:29:00 2017 -0500
@@ -34,6 +34,9 @@
 #include "oops/oop.inline.hpp"
 #include "oops/fieldStreams.hpp"
 #include "runtime/fieldDescriptor.hpp"
+#if INCLUDE_ALL_GCS
+# include "gc/g1/g1SATBCardTableModRefBS.hpp"
+#endif
 
 // ciInstanceKlass
 //
@@ -41,6 +44,27 @@
 // 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.
@@ -64,6 +88,18 @@
   _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.
+    assert(holder != NULL, "holder of anonymous class is the mirror which is never null");
+    (void)CURRENT_ENV->get_object(holder);
+  }
+
   Thread *thread = Thread::current();
   if (ciObjectFactory::is_initialized()) {
     _loader = JNIHandles::make_local(thread, ik->class_loader());