src/hotspot/share/oops/klass.cpp
changeset 49329 04ed29f9ef33
parent 49066 4aa67aba6c85
child 49368 2ed1c37df3a5
--- a/src/hotspot/share/oops/klass.cpp	Fri Mar 02 10:42:32 2018 -0800
+++ b/src/hotspot/share/oops/klass.cpp	Fri Mar 02 17:25:55 2018 -0500
@@ -183,7 +183,8 @@
 Klass::Klass() : _prototype_header(markOopDesc::prototype()),
                  _shared_class_path_index(-1),
                  _java_mirror(NULL) {
-
+  CDS_ONLY(_shared_class_flags = 0;)
+  CDS_JAVA_HEAP_ONLY(_archived_mirror = 0;)
   _primary_supers[0] = this;
   set_super_check_offset(in_bytes(primary_supers_offset()));
 }
@@ -519,29 +520,71 @@
     loader_data->add_class(this);
   }
 
-  // Recreate the class mirror.
+  Handle loader(THREAD, loader_data->class_loader());
+  ModuleEntry* module_entry = NULL;
+  Klass* k = this;
+  if (k->is_objArray_klass()) {
+    k = ObjArrayKlass::cast(k)->bottom_klass();
+  }
+  // Obtain klass' module.
+  if (k->is_instance_klass()) {
+    InstanceKlass* ik = (InstanceKlass*) k;
+    module_entry = ik->module();
+  } else {
+    module_entry = ModuleEntryTable::javabase_moduleEntry();
+  }
+  // Obtain java.lang.Module, if available
+  Handle module_handle(THREAD, ((module_entry != NULL) ? module_entry->module() : (oop)NULL));
+
+  if (this->has_raw_archived_mirror()) {
+    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(oopDesc::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);
+        return;
+      }
+    }
+
+    // No archived mirror data
+    _java_mirror = NULL;
+    this->clear_has_raw_archived_mirror();
+  }
+
   // Only recreate it if not present.  A previous attempt to restore may have
   // gotten an OOM later but keep the mirror if it was created.
   if (java_mirror() == NULL) {
-    Handle loader(THREAD, loader_data->class_loader());
-    ModuleEntry* module_entry = NULL;
-    Klass* k = this;
-    if (k->is_objArray_klass()) {
-      k = ObjArrayKlass::cast(k)->bottom_klass();
-    }
-    // Obtain klass' module.
-    if (k->is_instance_klass()) {
-      InstanceKlass* ik = (InstanceKlass*) k;
-      module_entry = ik->module();
-    } else {
-      module_entry = ModuleEntryTable::javabase_moduleEntry();
-    }
-    // Obtain java.lang.Module, if available
-    Handle module_handle(THREAD, ((module_entry != NULL) ? module_entry->module() : (oop)NULL));
+    log_trace(cds, mirror)("Recreate mirror for %s", external_name());
     java_lang_Class::create_mirror(this, loader, module_handle, protection_domain, CHECK);
   }
 }
 
+#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 oopDesc::decode_heap_oop(_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");
+  _archived_mirror = oopDesc::encode_heap_oop(m);
+}
+#endif // INCLUDE_CDS_JAVA_HEAP
+
 Klass* Klass::array_klass_or_null(int rank) {
   EXCEPTION_MARK;
   // No exception can be thrown by array_klass_impl when called with or_null == true.