< prev index next >

src/hotspot/share/classfile/classLoaderData.cpp

Print this page

@@ -57,13 +57,16 @@
 #include "classfile/systemDictionary.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/metadataFactory.hpp"
+#include "memory/metaspaceShared.hpp"
+#include "memory/iterator.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/array.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/oopHandle.inline.hpp"
 #include "oops/weakHandle.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"

@@ -71,10 +74,150 @@
 #include "runtime/safepoint.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
 
+
+#if INCLUDE_CDS_JAVA_HEAP
+// Support for archiving full module graph in CDS
+
+class ArchivedClassLoaderData {
+  Array<PackageEntry*>* _packages;
+  Array<ModuleEntry*>* _modules;
+
+public:
+  ArchivedClassLoaderData() : _packages(NULL), _modules(NULL) {}
+
+  void allocate(ClassLoaderData* loader_data);
+  void init_archived_entries(ClassLoaderData* loader_data);
+  void init_archived_oops(ClassLoaderData* loader_data);
+
+  void serialize(SerializeClosure* f) {
+    f->do_ptr((void**)&_packages);
+    f->do_ptr((void**)&_modules);
+  }
+
+  void load_archived_entries(ClassLoaderData* loader_data);
+  void restore_archived_oops(ClassLoaderData* loader_data);
+};
+
+static ArchivedClassLoaderData _archived_boot_loader_data;
+static ArchivedClassLoaderData _archived_platform_loader_data;
+static ArchivedClassLoaderData _archived_system_loader_data;
+static ModuleEntry* _archived_javabase_moduleEntry = NULL;
+
+void ArchivedClassLoaderData::allocate(ClassLoaderData* loader_data) {
+  assert(DumpSharedSpaces, "must be");
+
+  // We can't create a hashtable at dump time because the hashcode dependes on the
+  // address of the Symbols, which may be relocated at run time due to ASLR.
+  if (loader_data) {
+    _packages = loader_data->packages()->allocate_archived_entries();
+    _modules  = loader_data->modules() ->allocate_archived_entries();
+  }
+}
+
+void ArchivedClassLoaderData::init_archived_entries(ClassLoaderData* loader_data) {
+  assert(DumpSharedSpaces, "must be");
+  if (loader_data) {
+    loader_data->packages()->init_archived_entries(_packages);
+    loader_data->modules() ->init_archived_entries(_modules);
+  }
+}
+
+void ArchivedClassLoaderData::init_archived_oops(ClassLoaderData* loader_data) {
+  assert(DumpSharedSpaces, "must be");
+  if (loader_data) {
+    loader_data->modules()->init_archived_oops(_modules);
+  }
+}
+
+void ArchivedClassLoaderData::load_archived_entries(ClassLoaderData* loader_data) {
+  assert(UseSharedSpaces, "must be");
+  if (_modules) {
+    loader_data->modules()->load_archived_entries(loader_data, _modules);
+    loader_data->packages()->load_archived_entries(_packages);
+  }
+}
+
+void ArchivedClassLoaderData::restore_archived_oops(ClassLoaderData* loader_data) {
+  assert(UseSharedSpaces, "must be");
+  if (_modules) {
+    loader_data->modules()->restore_archived_oops(loader_data, _modules);
+  }
+}
+
+// ------------------------------
+
+void ClassLoaderData::allocate_archived_tables() {
+  assert(DumpSharedSpaces, "must be");
+  if (MetaspaceShared::use_full_module_graph()) {
+    _archived_boot_loader_data.allocate    (_the_null_class_loader_data);
+    _archived_platform_loader_data.allocate(class_loader_data_or_null(SystemDictionary::java_platform_loader()));
+    _archived_system_loader_data.allocate  (class_loader_data_or_null(SystemDictionary::java_system_loader()));
+  }
+}
+
+void ClassLoaderData::init_archived_tables() {
+  assert(DumpSharedSpaces, "must be");
+  if (MetaspaceShared::use_full_module_graph()) {
+    _archived_boot_loader_data.init_archived_entries    (_the_null_class_loader_data);
+    _archived_platform_loader_data.init_archived_entries(class_loader_data_or_null(SystemDictionary::java_platform_loader()));
+    _archived_system_loader_data.init_archived_entries  (class_loader_data_or_null(SystemDictionary::java_system_loader()));
+    _archived_javabase_moduleEntry = ModuleEntry::get_archived_entry(ModuleEntryTable::javabase_moduleEntry());
+  }
+}
+
+void ClassLoaderData::init_archived_oops() {
+  assert(DumpSharedSpaces, "must be");
+  if (MetaspaceShared::use_full_module_graph()) {
+    _archived_boot_loader_data.init_archived_oops    (_the_null_class_loader_data);
+    _archived_platform_loader_data.init_archived_oops(class_loader_data_or_null(SystemDictionary::java_platform_loader()));
+    _archived_system_loader_data.init_archived_oops  (class_loader_data_or_null(SystemDictionary::java_system_loader()));
+  }
+}
+
+void ClassLoaderData::serialize(class SerializeClosure* f) {
+  _archived_boot_loader_data.serialize(f);
+  _archived_platform_loader_data.serialize(f);
+  _archived_system_loader_data.serialize(f);
+  f->do_ptr((void**)&_archived_javabase_moduleEntry);
+
+  if (f->reading() && MetaspaceShared::use_full_module_graph()) {
+    // Must be done before ClassLoader::create_javabase()
+    _archived_boot_loader_data.load_archived_entries(_the_null_class_loader_data);
+    ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry);
+    log_info(cds)("use_full_module_graph = true; java.base = " INTPTR_FORMAT,
+                  p2i(_archived_javabase_moduleEntry));
+  }
+}
+
+void ClassLoaderData::restore_archived_oops_for_null_class_loader_data() {
+  assert(UseSharedSpaces, "must be");
+  if (MetaspaceShared::use_full_module_graph()) {
+    _archived_boot_loader_data.restore_archived_oops(_the_null_class_loader_data);
+  }
+}
+
+void ClassLoaderData::restore_java_platform_loader_from_archive() {
+  assert(UseSharedSpaces, "must be");
+  assert(MetaspaceShared::use_full_module_graph(), "must be");
+  assert(class_loader() == SystemDictionary::java_platform_loader(), "must be");
+  _archived_platform_loader_data.load_archived_entries(this);
+  _archived_platform_loader_data.restore_archived_oops(this);
+}
+
+void ClassLoaderData::restore_java_system_loader_from_archive() {
+  assert(UseSharedSpaces, "must be");
+  assert(MetaspaceShared::use_full_module_graph(), "must be");
+  assert(class_loader() == SystemDictionary::java_system_loader(), "must be");
+  _archived_system_loader_data.load_archived_entries(this);
+  _archived_system_loader_data.restore_archived_oops(this);
+}
+
+#endif // INCLUDE_JAVA_HEAP
+
 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
 
 void ClassLoaderData::init_null_class_loader_data() {
   assert(_the_null_class_loader_data == NULL, "cannot initialize twice");
   assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice");
< prev index next >