--- old/src/hotspot/share/classfile/classLoaderData.cpp 2020-07-22 12:00:26.539611001 -0700 +++ new/src/hotspot/share/classfile/classLoaderData.cpp 2020-07-22 12:00:26.359604225 -0700 @@ -59,9 +59,12 @@ #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" @@ -73,6 +76,146 @@ #include "utilities/macros.hpp" #include "utilities/ostream.hpp" + +#if INCLUDE_CDS_JAVA_HEAP +// Support for archiving full module graph in CDS + +class ArchivedClassLoaderData { + Array* _packages; + Array* _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() {