< prev index next >

src/hotspot/share/memory/heapShared.cpp

Print this page

@@ -22,12 +22,14 @@
  *
  */
 
 #include "precompiled.hpp"
 #include "classfile/javaClasses.inline.hpp"
+#include "classfile/moduleEntry.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "gc/shared/gcLocker.hpp"
 #include "logging/log.hpp"
 #include "logging/logMessage.hpp"

@@ -43,10 +45,11 @@
 #include "memory/universe.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/fieldStreams.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
+#include "runtime/javaCalls.hpp"
 #include "runtime/safepointVerifiers.hpp"
 #include "utilities/bitMap.inline.hpp"
 #if INCLUDE_G1GC
 #include "gc/g1/g1CollectedHeap.hpp"
 #endif

@@ -66,24 +69,29 @@
 
 // Entry fields for shareable subgraphs archived in the closed archive heap
 // region. Warning: Objects in the subgraphs should not have reference fields
 // assigned at runtime.
 static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = {
-  {"java/lang/Integer$IntegerCache",           "archivedCache"},
-  {"java/lang/Long$LongCache",                 "archivedCache"},
-  {"java/lang/Byte$ByteCache",                 "archivedCache"},
-  {"java/lang/Short$ShortCache",               "archivedCache"},
-  {"java/lang/Character$CharacterCache",       "archivedCache"},
-  {"java/util/jar/Attributes$Name",            "KNOWN_NAMES"},
-  {"sun/util/locale/BaseLocale",               "constantBaseLocales"},
+  {"java/lang/Integer$IntegerCache",              0, "archivedCache"},
+  {"java/lang/Long$LongCache",                    0, "archivedCache"},
+  {"java/lang/Byte$ByteCache",                    0, "archivedCache"},
+  {"java/lang/Short$ShortCache",                  0, "archivedCache"},
+  {"java/lang/Character$CharacterCache",          0, "archivedCache"},
+  {"java/util/jar/Attributes$Name",               0, "KNOWN_NAMES"},
+  {"sun/util/locale/BaseLocale",                  0, "constantBaseLocales"},
 };
 // Entry fields for subgraphs archived in the open archive heap region.
 static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = {
-  {"jdk/internal/module/ArchivedModuleGraph",  "archivedModuleGraph"},
-  {"java/util/ImmutableCollections",           "archivedObjects"},
-  {"java/lang/module/Configuration",           "EMPTY_CONFIGURATION"},
-  {"jdk/internal/math/FDBigInteger",           "archivedCaches"},
+  {"jdk/internal/loader/BuiltinClassLoader$ArchivedData",         1, "packageToModule"},
+  {"jdk/internal/loader/BootLoader$ArchivedData",                 1, "servicesCatalog"},
+  {"jdk/internal/loader/ClassLoaders$ArchivedData",               1, "singleton"},
+  {"jdk/internal/module/ModuleBootstrap$ArchivedBootLayer",       1, "archivedBootLayer"},
+  {"jdk/internal/module/ArchivedModuleGraph",                     0, "archivedModuleGraph"},
+  {"java/util/ImmutableCollections",                              0, "archivedObjects"},
+  {"java/lang/Module$ArchivedData",                               1, "singleton"},
+  {"java/lang/module/Configuration",                              0, "EMPTY_CONFIGURATION"},
+  {"jdk/internal/math/FDBigInteger",                              0, "archivedCaches"},
 };
 
 const static int num_closed_archive_subgraph_entry_fields =
   sizeof(closed_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
 const static int num_open_archive_subgraph_entry_fields =

@@ -106,10 +114,39 @@
          "this object should never have been locked");  // so identity_hash won't safepoin
   unsigned hash = (unsigned)p->identity_hash();
   return hash;
 }
 
+static void reset_states(oop obj, TRAPS) {
+  Handle h_obj(THREAD, obj);
+  InstanceKlass* klass = InstanceKlass::cast(obj->klass());
+  TempNewSymbol method_name = SymbolTable::new_symbol("resetArchivedStates");
+  Symbol* method_sig = vmSymbols::void_method_signature();
+
+  while (klass != NULL) {
+    Method* method = klass->find_method(method_name, method_sig);
+    if (method != NULL) {
+      assert(method->is_private(), "must be");
+      if (log_is_enabled(Debug, cds)) {
+        ResourceMark rm(THREAD);
+        log_debug(cds)("  calling %s", method->name_and_sig_as_C_string());
+      }
+      JavaValue result(T_VOID);
+      JavaCalls::call_special(&result, h_obj, klass,
+                              method_name, method_sig, CHECK);
+    }
+    klass = klass->java_super();
+  }
+}
+
+void HeapShared::reset_archived_object_states(TRAPS) {
+  log_debug(cds)("Resetting platform loader");
+  reset_states(SystemDictionary::java_platform_loader(), THREAD);
+  log_debug(cds)("Resetting system loader");
+  reset_states(SystemDictionary::java_system_loader(), THREAD);
+}
+
 HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = NULL;
 oop HeapShared::find_archived_heap_object(oop obj) {
   assert(DumpSharedSpaces, "dump-time only");
   ArchivedObjectCache* cache = archived_object_cache();
   oop* p = cache->get(obj);

@@ -231,10 +268,12 @@
     copy_closed_archive_heap_objects(closed);
 
     log_info(cds)("Dumping objects to open archive heap region ...");
     copy_open_archive_heap_objects(open);
 
+    ClassLoaderData::init_archived_oops();
+
     destroy_archived_object_cache();
   }
 
   G1HeapVerifier::verify_archive_regions();
 }

@@ -463,10 +502,19 @@
   if (!open_archive_heap_region_mapped()) {
     return; // nothing to do
   }
   assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
 
+  if (!MetaspaceShared::use_full_module_graph()) {
+    for (int i = 0; i < num_open_archive_subgraph_entry_fields; i++) {
+      const ArchivableStaticFieldInfo* info = &open_archive_subgraph_entry_fields[i];
+      if (info->full_module_graph_only && k->name()->equals(info->klass_name)) {
+        return;
+      }
+    }
+  }
+
   unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary(k);
   const ArchivedKlassSubGraphInfoRecord* record = _run_time_subgraph_info_table.lookup(k, hash, 0);
 
   // Initialize from archived data. Currently this is done only
   // during VM initialization time. No lock is needed.

@@ -621,10 +669,29 @@
       }
     }
   }
 }
 
+void HeapShared::check_module_oop(oop orig_module_obj) {
+  assert(DumpSharedSpaces, "must be");
+  assert(java_lang_Module::is_instance(orig_module_obj), "must be");
+  ModuleEntry* orig_module_ent = java_lang_Module::module_entry_raw(orig_module_obj);
+  if (orig_module_ent == NULL) {
+    // These special Module objects are created in Java code. They are not
+    // defined via Modules::define_module(), so they don't have a ModuleEntry:
+    //     java.lang.Module::ALL_UNNAMED_MODULE
+    //     java.lang.Module::EVERYONE_MODULE
+    //     jdk.internal.loader.ClassLoaders$BootClassLoader::unnamedModule
+    assert(java_lang_Module::name(orig_module_obj) == NULL, "must be unnamed");
+    log_info(cds, heap)("Module oop with No ModuleEntry* @[" PTR_FORMAT "]", p2i(orig_module_obj));
+  } else {
+    ClassLoaderData* loader_data = orig_module_ent->loader_data();
+    assert(loader_data->is_builtin_class_loader_data(), "must be");
+  }
+}
+
+
 // (1) If orig_obj has not been archived yet, archive it.
 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
 //     trace all  objects that are reachable from it, and make sure these objects are archived.
 // (3) Record the klasses of all orig_obj and all reachable objects.
 oop HeapShared::archive_reachable_objects_from(int level,

@@ -688,10 +755,25 @@
         // objects cannot be archived. Bail out for now. We might need to fix this in the future if
         // we have a real use case.
         vm_exit(1);
       }
     }
+
+    if (java_lang_Module::is_instance(orig_obj)) {
+      check_module_oop(orig_obj);
+    }
+
+    if (java_lang_Module::is_instance(orig_obj)) {
+      java_lang_Module::set_module_entry(archived_obj, NULL);
+      java_lang_Module::set_loader(archived_obj, NULL);
+    } else if (java_lang_ClassLoader::is_instance(orig_obj)) {
+      // class_data will be restored explicitly at run time. 
+      guarantee(orig_obj == SystemDictionary::java_platform_loader() ||
+                orig_obj == SystemDictionary::java_system_loader() ||
+                java_lang_ClassLoader::loader_data_raw(orig_obj) == NULL, "must be");
+      java_lang_ClassLoader::release_set_loader_data(archived_obj, NULL);
+    }
   }
 
   assert(archived_obj != NULL, "must be");
   Klass *orig_k = orig_obj->klass();
   Klass *relocated_k = archived_obj->klass();

@@ -984,14 +1066,17 @@
     for (; i < num; i++) {
       ArchivableStaticFieldInfo* f = &fields[i];
       if (f->klass_name != klass_name) {
         break;
       }
+
+      if (!info->full_module_graph_only || MetaspaceShared::use_full_module_graph()) {
       archive_reachable_objects_from_static_field(f->klass, f->klass_name,
                                                   f->offset, f->field_name,
                                                   is_closed_archive, CHECK);
     }
+    }
     done_recording_subgraph(info->klass, klass_name);
   }
 
   log_info(cds, heap)("Archived subgraph records in %s archive heap region = %d",
                       is_closed_archive ? "closed" : "open",
< prev index next >