< 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 >