mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-05 03:05:47 +00:00
8360555: Archive all unnamed modules in CDS full module graph
Reviewed-by: coleenp, vlivanov
This commit is contained in:
parent
ea6674fec8
commit
aae9902234
@ -110,11 +110,13 @@ CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0)
|
||||
|
||||
ADD_EXCL("java/lang/System", "bootLayer"); // A
|
||||
|
||||
ADD_EXCL("java/util/Collections", "EMPTY_LIST"); // E
|
||||
ADD_EXCL("java/util/Collections", "EMPTY_LIST"); // E
|
||||
|
||||
// A dummy object used by HashSet. The value doesn't matter and it's never
|
||||
// tested for equality.
|
||||
ADD_EXCL("java/util/HashSet", "PRESENT"); // E
|
||||
|
||||
ADD_EXCL("jdk/internal/loader/BootLoader", "UNNAMED_MODULE"); // A
|
||||
ADD_EXCL("jdk/internal/loader/BuiltinClassLoader", "packageToModule"); // A
|
||||
ADD_EXCL("jdk/internal/loader/ClassLoaders", "BOOT_LOADER", // A
|
||||
"APP_LOADER", // A
|
||||
|
||||
@ -120,7 +120,6 @@ PackageEntry* CDSProtectionDomain::get_package_entry_from_class(InstanceKlass* i
|
||||
if (CDSConfig::is_using_full_module_graph() && ik->is_shared() && pkg_entry != nullptr) {
|
||||
assert(MetaspaceShared::is_in_shared_metaspace(pkg_entry), "must be");
|
||||
assert(!ik->defined_by_other_loaders(), "unexpected archived package entry for an unregistered class");
|
||||
assert(ik->module()->is_named(), "unexpected archived package entry for a class in an unnamed module");
|
||||
return pkg_entry;
|
||||
}
|
||||
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(ik->name());
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include "cds/aotLogging.hpp"
|
||||
#include "cds/cdsConfig.hpp"
|
||||
#include "cds/heapShared.hpp"
|
||||
#include "cds/serializeClosure.hpp"
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/classLoaderDataShared.hpp"
|
||||
@ -42,6 +43,7 @@ bool ClassLoaderDataShared::_full_module_graph_loaded = false;
|
||||
class ArchivedClassLoaderData {
|
||||
Array<PackageEntry*>* _packages;
|
||||
Array<ModuleEntry*>* _modules;
|
||||
ModuleEntry* _unnamed_module;
|
||||
|
||||
void assert_valid(ClassLoaderData* loader_data) {
|
||||
// loader_data may be null if the boot layer has loaded no modules for the platform or
|
||||
@ -52,15 +54,19 @@ class ArchivedClassLoaderData {
|
||||
}
|
||||
}
|
||||
public:
|
||||
ArchivedClassLoaderData() : _packages(nullptr), _modules(nullptr) {}
|
||||
ArchivedClassLoaderData() : _packages(nullptr), _modules(nullptr), _unnamed_module(nullptr) {}
|
||||
|
||||
void iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure);
|
||||
void allocate(ClassLoaderData* loader_data);
|
||||
void init_archived_entries(ClassLoaderData* loader_data);
|
||||
ModuleEntry* unnamed_module() {
|
||||
return _unnamed_module;
|
||||
}
|
||||
|
||||
void serialize(SerializeClosure* f) {
|
||||
f->do_ptr(&_packages);
|
||||
f->do_ptr(&_modules);
|
||||
f->do_ptr(&_unnamed_module);
|
||||
}
|
||||
|
||||
void restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops);
|
||||
@ -71,6 +77,8 @@ static ArchivedClassLoaderData _archived_boot_loader_data;
|
||||
static ArchivedClassLoaderData _archived_platform_loader_data;
|
||||
static ArchivedClassLoaderData _archived_system_loader_data;
|
||||
static ModuleEntry* _archived_javabase_moduleEntry = nullptr;
|
||||
static int _platform_loader_root_index = -1;
|
||||
static int _system_loader_root_index = -1;
|
||||
|
||||
void ArchivedClassLoaderData::iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure) {
|
||||
assert(CDSConfig::is_dumping_full_module_graph(), "must be");
|
||||
@ -78,6 +86,7 @@ void ArchivedClassLoaderData::iterate_symbols(ClassLoaderData* loader_data, Meta
|
||||
if (loader_data != nullptr) {
|
||||
loader_data->packages()->iterate_symbols(closure);
|
||||
loader_data->modules() ->iterate_symbols(closure);
|
||||
loader_data->unnamed_module()->iterate_symbols(closure);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,6 +100,7 @@ void ArchivedClassLoaderData::allocate(ClassLoaderData* loader_data) {
|
||||
// the hashtables using these arrays.
|
||||
_packages = loader_data->packages()->allocate_archived_entries();
|
||||
_modules = loader_data->modules() ->allocate_archived_entries();
|
||||
_unnamed_module = loader_data->unnamed_module()->allocate_archived_entry();
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,6 +110,7 @@ void ArchivedClassLoaderData::init_archived_entries(ClassLoaderData* loader_data
|
||||
if (loader_data != nullptr) {
|
||||
loader_data->packages()->init_archived_entries(_packages);
|
||||
loader_data->modules() ->init_archived_entries(_modules);
|
||||
_unnamed_module->init_as_archived_entry();
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +128,12 @@ void ArchivedClassLoaderData::restore(ClassLoaderData* loader_data, bool do_entr
|
||||
}
|
||||
if (do_oops) {
|
||||
modules->restore_archived_oops(loader_data, _modules);
|
||||
if (_unnamed_module != nullptr) {
|
||||
oop module_oop = _unnamed_module->module_oop();
|
||||
assert(module_oop != nullptr, "must be already set");
|
||||
assert(_unnamed_module == java_lang_Module::module_entry(module_oop), "must be already set");
|
||||
assert(loader_data->class_loader() == java_lang_Module::loader(module_oop), "must be set in dump time");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,6 +144,9 @@ void ArchivedClassLoaderData::clear_archived_oops() {
|
||||
for (int i = 0; i < _modules->length(); i++) {
|
||||
_modules->at(i)->clear_archived_oops();
|
||||
}
|
||||
if (_unnamed_module != nullptr) {
|
||||
_unnamed_module->clear_archived_oops();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,10 +197,15 @@ void ClassLoaderDataShared::allocate_archived_tables() {
|
||||
|
||||
void ClassLoaderDataShared::init_archived_tables() {
|
||||
assert(CDSConfig::is_dumping_full_module_graph(), "must be");
|
||||
|
||||
_archived_boot_loader_data.init_archived_entries (null_class_loader_data());
|
||||
_archived_platform_loader_data.init_archived_entries(java_platform_loader_data_or_null());
|
||||
_archived_system_loader_data.init_archived_entries (java_system_loader_data_or_null());
|
||||
|
||||
_archived_javabase_moduleEntry = ModuleEntry::get_archived_entry(ModuleEntryTable::javabase_moduleEntry());
|
||||
|
||||
_platform_loader_root_index = HeapShared::append_root(SystemDictionary::java_platform_loader());
|
||||
_system_loader_root_index = HeapShared::append_root(SystemDictionary::java_system_loader());
|
||||
}
|
||||
|
||||
void ClassLoaderDataShared::serialize(SerializeClosure* f) {
|
||||
@ -188,21 +213,54 @@ void ClassLoaderDataShared::serialize(SerializeClosure* f) {
|
||||
_archived_platform_loader_data.serialize(f);
|
||||
_archived_system_loader_data.serialize(f);
|
||||
f->do_ptr(&_archived_javabase_moduleEntry);
|
||||
f->do_int(&_platform_loader_root_index);
|
||||
f->do_int(&_system_loader_root_index);
|
||||
}
|
||||
|
||||
if (f->reading() && CDSConfig::is_using_full_module_graph()) {
|
||||
// Must be done before ClassLoader::create_javabase()
|
||||
_archived_boot_loader_data.restore(null_class_loader_data(), true, false);
|
||||
ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry);
|
||||
aot_log_info(aot)("use_full_module_graph = true; java.base = " INTPTR_FORMAT,
|
||||
p2i(_archived_javabase_moduleEntry));
|
||||
ModuleEntry* ClassLoaderDataShared::archived_boot_unnamed_module() {
|
||||
if (CDSConfig::is_using_full_module_graph()) {
|
||||
return _archived_boot_loader_data.unnamed_module();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ModuleEntry* ClassLoaderDataShared::archived_unnamed_module(ClassLoaderData* loader_data) {
|
||||
ModuleEntry* archived_module = nullptr;
|
||||
|
||||
if (!Universe::is_module_initialized() && CDSConfig::is_using_full_module_graph()) {
|
||||
precond(_platform_loader_root_index >= 0);
|
||||
precond(_system_loader_root_index >= 0);
|
||||
|
||||
if (loader_data->class_loader() == HeapShared::get_root(_platform_loader_root_index)) {
|
||||
archived_module = _archived_platform_loader_data.unnamed_module();
|
||||
} else if (loader_data->class_loader() == HeapShared::get_root(_system_loader_root_index)) {
|
||||
archived_module = _archived_system_loader_data.unnamed_module();
|
||||
}
|
||||
}
|
||||
|
||||
return archived_module;
|
||||
}
|
||||
|
||||
|
||||
void ClassLoaderDataShared::clear_archived_oops() {
|
||||
assert(!CDSConfig::is_using_full_module_graph(), "must be");
|
||||
_archived_boot_loader_data.clear_archived_oops();
|
||||
_archived_platform_loader_data.clear_archived_oops();
|
||||
_archived_system_loader_data.clear_archived_oops();
|
||||
if (_platform_loader_root_index >= 0) {
|
||||
HeapShared::clear_root(_platform_loader_root_index);
|
||||
HeapShared::clear_root(_system_loader_root_index);
|
||||
}
|
||||
}
|
||||
|
||||
// Must be done before ClassLoader::create_javabase()
|
||||
void ClassLoaderDataShared::restore_archived_entries_for_null_class_loader_data() {
|
||||
precond(CDSConfig::is_using_full_module_graph());
|
||||
_archived_boot_loader_data.restore(null_class_loader_data(), true, false);
|
||||
ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry);
|
||||
aot_log_info(aot)("use_full_module_graph = true; java.base = " INTPTR_FORMAT,
|
||||
p2i(_archived_javabase_moduleEntry));
|
||||
}
|
||||
|
||||
oop ClassLoaderDataShared::restore_archived_oops_for_null_class_loader_data() {
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
class ClassLoaderData;
|
||||
class MetaspaceClosure;
|
||||
class ModuleEntry;
|
||||
class SerializeClosure;
|
||||
|
||||
class ClassLoaderDataShared : AllStatic {
|
||||
@ -42,9 +43,12 @@ public:
|
||||
static void init_archived_tables();
|
||||
static void serialize(SerializeClosure* f);
|
||||
static void clear_archived_oops();
|
||||
static void restore_archived_entries_for_null_class_loader_data();
|
||||
static oop restore_archived_oops_for_null_class_loader_data();
|
||||
static void restore_java_platform_loader_from_archive(ClassLoaderData* loader_data);
|
||||
static void restore_java_system_loader_from_archive(ClassLoaderData* loader_data);
|
||||
static ModuleEntry* archived_boot_unnamed_module();
|
||||
static ModuleEntry* archived_unnamed_module(ClassLoaderData* loader_data);
|
||||
static bool is_full_module_graph_loaded() { return _full_module_graph_loaded; }
|
||||
};
|
||||
|
||||
|
||||
@ -29,9 +29,11 @@
|
||||
#include "cds/heapShared.hpp"
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/classLoaderDataShared.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "classfile/moduleEntry.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/systemDictionaryShared.hpp"
|
||||
#include "jni.h"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
@ -317,6 +319,15 @@ ModuleEntry* ModuleEntry::create_unnamed_module(ClassLoaderData* cld) {
|
||||
// corresponding unnamed module can be found in the java.lang.ClassLoader object.
|
||||
oop module = java_lang_ClassLoader::unnamedModule(cld->class_loader());
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
ModuleEntry* archived_unnamed_module = ClassLoaderDataShared::archived_unnamed_module(cld);
|
||||
if (archived_unnamed_module != nullptr) {
|
||||
archived_unnamed_module->load_from_archive(cld);
|
||||
archived_unnamed_module->restore_archived_oops(cld);
|
||||
return archived_unnamed_module;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ensure that the unnamed module was correctly set when the class loader was constructed.
|
||||
// Guarantee will cause a recognizable crash if the user code has circumvented calling the ClassLoader constructor.
|
||||
ResourceMark rm;
|
||||
@ -333,6 +344,16 @@ ModuleEntry* ModuleEntry::create_unnamed_module(ClassLoaderData* cld) {
|
||||
}
|
||||
|
||||
ModuleEntry* ModuleEntry::create_boot_unnamed_module(ClassLoaderData* cld) {
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
ModuleEntry* archived_unnamed_module = ClassLoaderDataShared::archived_boot_unnamed_module();
|
||||
if (archived_unnamed_module != nullptr) {
|
||||
archived_unnamed_module->load_from_archive(cld);
|
||||
// It's too early to call archived_unnamed_module->restore_archived_oops(cld).
|
||||
// We will do it inside Modules::set_bootloader_unnamed_module()
|
||||
return archived_unnamed_module;
|
||||
}
|
||||
#endif
|
||||
|
||||
// For the boot loader, the java.lang.Module for the unnamed module
|
||||
// is not known until a call to JVM_SetBootLoaderUnnamedModule is made. At
|
||||
// this point initially create the ModuleEntry for the unnamed module.
|
||||
@ -345,7 +366,6 @@ ModuleEntry* ModuleEntry::create_boot_unnamed_module(ClassLoaderData* cld) {
|
||||
// This is okay because the unnamed module gets created before the ClassLoaderData
|
||||
// is available to other threads.
|
||||
ModuleEntry* ModuleEntry::new_unnamed_module_entry(Handle module_handle, ClassLoaderData* cld) {
|
||||
|
||||
ModuleEntry* entry = new ModuleEntry(module_handle, /*is_open*/true, /*name*/nullptr,
|
||||
/*version*/ nullptr, /*location*/ nullptr,
|
||||
cld);
|
||||
@ -395,17 +415,17 @@ static int _num_archived_module_entries = 0;
|
||||
static int _num_inited_module_entries = 0;
|
||||
#endif
|
||||
|
||||
bool ModuleEntry::should_be_archived() const {
|
||||
return SystemDictionaryShared::is_builtin_loader(loader_data());
|
||||
}
|
||||
|
||||
ModuleEntry* ModuleEntry::allocate_archived_entry() const {
|
||||
assert(is_named(), "unnamed packages/modules are not archived");
|
||||
precond(should_be_archived());
|
||||
precond(CDSConfig::is_dumping_full_module_graph());
|
||||
ModuleEntry* archived_entry = (ModuleEntry*)ArchiveBuilder::rw_region_alloc(sizeof(ModuleEntry));
|
||||
memcpy((void*)archived_entry, (void*)this, sizeof(ModuleEntry));
|
||||
|
||||
if (CDSConfig::is_dumping_full_module_graph()) {
|
||||
archived_entry->_archived_module_index = HeapShared::append_root(module_oop());
|
||||
} else {
|
||||
archived_entry->_archived_module_index = -1;
|
||||
}
|
||||
|
||||
archived_entry->_archived_module_index = HeapShared::append_root(module_oop());
|
||||
if (_archive_modules_entries == nullptr) {
|
||||
_archive_modules_entries = new (mtClass)ArchivedModuleEntries();
|
||||
}
|
||||
@ -489,10 +509,14 @@ void ModuleEntry::init_as_archived_entry() {
|
||||
set_archived_reads(write_growable_array(reads()));
|
||||
|
||||
_loader_data = nullptr; // re-init at runtime
|
||||
_shared_path_index = AOTClassLocationConfig::dumptime()->get_module_shared_path_index(_location);
|
||||
if (name() != nullptr) {
|
||||
_shared_path_index = AOTClassLocationConfig::dumptime()->get_module_shared_path_index(_location);
|
||||
_name = ArchiveBuilder::get_buffered_symbol(_name);
|
||||
ArchivePtrMarker::mark_pointer((address*)&_name);
|
||||
} else {
|
||||
// _shared_path_index is used only by SystemDictionary::is_shared_class_visible_impl()
|
||||
// for checking classes in named modules.
|
||||
_shared_path_index = -1;
|
||||
}
|
||||
if (_version != nullptr) {
|
||||
_version = ArchiveBuilder::get_buffered_symbol(_version);
|
||||
@ -741,7 +765,7 @@ void ModuleEntryTable::modules_do(ModuleClosure* closure) {
|
||||
_table.iterate_all(do_f);
|
||||
}
|
||||
|
||||
void ModuleEntry::print(outputStream* st) {
|
||||
void ModuleEntry::print(outputStream* st) const {
|
||||
st->print_cr("entry " PTR_FORMAT " name %s module " PTR_FORMAT " loader %s version %s location %s strict %s",
|
||||
p2i(this),
|
||||
name_as_C_string(),
|
||||
|
||||
@ -186,10 +186,10 @@ public:
|
||||
static ModuleEntry* new_unnamed_module_entry(Handle module_handle, ClassLoaderData* cld);
|
||||
|
||||
// Note caller requires ResourceMark
|
||||
const char* name_as_C_string() {
|
||||
const char* name_as_C_string() const {
|
||||
return is_named() ? name()->as_C_string() : UNNAMED_MODULE;
|
||||
}
|
||||
void print(outputStream* st = tty);
|
||||
void print(outputStream* st = tty) const;
|
||||
void verify();
|
||||
|
||||
CDS_ONLY(int shared_path_index() { return _shared_path_index;})
|
||||
@ -197,6 +197,7 @@ public:
|
||||
JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
bool should_be_archived() const;
|
||||
void iterate_symbols(MetaspaceClosure* closure);
|
||||
ModuleEntry* allocate_archived_entry() const;
|
||||
void init_as_archived_entry();
|
||||
|
||||
@ -474,6 +474,7 @@ void Modules::define_module(Handle module, jboolean is_open, jstring version,
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
static bool _seen_boot_unnamed_module = false;
|
||||
static bool _seen_platform_unnamed_module = false;
|
||||
static bool _seen_system_unnamed_module = false;
|
||||
|
||||
@ -509,24 +510,20 @@ void Modules::check_archived_module_oop(oop orig_module_obj) {
|
||||
// For each named module, we archive both the java.lang.Module oop and the ModuleEntry.
|
||||
assert(orig_module_ent->has_been_archived(), "sanity");
|
||||
} else {
|
||||
// We only archive two unnamed module oops (for platform and system loaders). These do NOT have an archived
|
||||
// ModuleEntry.
|
||||
//
|
||||
// At runtime, these oops are fetched from java_lang_ClassLoader::unnamedModule(loader) and
|
||||
// are initialized in ClassLoaderData::ClassLoaderData() => ModuleEntry::create_unnamed_module(), where
|
||||
// a new ModuleEntry is allocated.
|
||||
assert(!loader_data->is_boot_class_loader_data(), "unnamed module for boot loader should be not archived");
|
||||
assert(!orig_module_ent->has_been_archived(), "sanity");
|
||||
// We always archive unnamed module oop for boot, platform, and system loaders.
|
||||
precond(orig_module_ent->should_be_archived());
|
||||
precond(orig_module_ent->has_been_archived());
|
||||
|
||||
if (SystemDictionary::is_platform_class_loader(loader_data->class_loader())) {
|
||||
if (loader_data->is_boot_class_loader_data()) {
|
||||
assert(!_seen_boot_unnamed_module, "only once");
|
||||
_seen_boot_unnamed_module = true;
|
||||
} else if (SystemDictionary::is_platform_class_loader(loader_data->class_loader())) {
|
||||
assert(!_seen_platform_unnamed_module, "only once");
|
||||
_seen_platform_unnamed_module = true;
|
||||
} else if (SystemDictionary::is_system_class_loader(loader_data->class_loader())) {
|
||||
assert(!_seen_system_unnamed_module, "only once");
|
||||
_seen_system_unnamed_module = true;
|
||||
} else {
|
||||
// The java.lang.Module oop and ModuleEntry of the unnamed module of the boot loader are
|
||||
// not in the archived module graph. These are always allocated at runtime.
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
@ -777,9 +774,18 @@ void Modules::set_bootloader_unnamed_module(Handle module, TRAPS) {
|
||||
ClassLoaderData* boot_loader_data = ClassLoaderData::the_null_class_loader_data();
|
||||
ModuleEntry* unnamed_module = boot_loader_data->unnamed_module();
|
||||
assert(unnamed_module != nullptr, "boot loader's unnamed ModuleEntry not defined");
|
||||
unnamed_module->set_module_handle(boot_loader_data->add_handle(module));
|
||||
// Store pointer to the ModuleEntry in the unnamed module's java.lang.Module object.
|
||||
java_lang_Module::set_module_entry(module(), unnamed_module);
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
if (CDSConfig::is_using_full_module_graph()) {
|
||||
precond(unnamed_module == ClassLoaderDataShared::archived_boot_unnamed_module());
|
||||
unnamed_module->restore_archived_oops(boot_loader_data);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
unnamed_module->set_module_handle(boot_loader_data->add_handle(module));
|
||||
// Store pointer to the ModuleEntry in the unnamed module's java.lang.Module object.
|
||||
java_lang_Module::set_module_entry(module(), unnamed_module);
|
||||
}
|
||||
}
|
||||
|
||||
void Modules::add_module_exports(Handle from_module, jstring package_name, Handle to_module, TRAPS) {
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "classfile/packageEntry.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/array.hpp"
|
||||
#include "oops/symbol.hpp"
|
||||
@ -218,8 +219,12 @@ typedef ResourceHashtable<
|
||||
AnyObj::C_HEAP> ArchivedPackageEntries;
|
||||
static ArchivedPackageEntries* _archived_packages_entries = nullptr;
|
||||
|
||||
bool PackageEntry::should_be_archived() const {
|
||||
return module()->should_be_archived();
|
||||
}
|
||||
|
||||
PackageEntry* PackageEntry::allocate_archived_entry() const {
|
||||
assert(!in_unnamed_module(), "unnamed packages/modules are not archived");
|
||||
precond(should_be_archived());
|
||||
PackageEntry* archived_entry = (PackageEntry*)ArchiveBuilder::rw_region_alloc(sizeof(PackageEntry));
|
||||
memcpy((void*)archived_entry, (void*)this, sizeof(PackageEntry));
|
||||
|
||||
@ -257,6 +262,12 @@ void PackageEntry::init_as_archived_entry() {
|
||||
ArchivePtrMarker::mark_pointer((address*)&_name);
|
||||
ArchivePtrMarker::mark_pointer((address*)&_module);
|
||||
ArchivePtrMarker::mark_pointer((address*)&_qualified_exports);
|
||||
|
||||
LogStreamHandle(Info, aot, package) st;
|
||||
if (st.is_enabled()) {
|
||||
st.print("archived ");
|
||||
print(&st);
|
||||
}
|
||||
}
|
||||
|
||||
void PackageEntry::load_from_archive() {
|
||||
@ -280,7 +291,7 @@ Array<PackageEntry*>* PackageEntryTable::allocate_archived_entries() {
|
||||
// First count the packages in named modules
|
||||
int n = 0;
|
||||
auto count = [&] (const SymbolHandle& key, PackageEntry*& p) {
|
||||
if (p->module()->is_named()) {
|
||||
if (p->should_be_archived()) {
|
||||
n++;
|
||||
}
|
||||
};
|
||||
@ -290,9 +301,7 @@ Array<PackageEntry*>* PackageEntryTable::allocate_archived_entries() {
|
||||
// reset n
|
||||
n = 0;
|
||||
auto grab = [&] (const SymbolHandle& key, PackageEntry*& p) {
|
||||
if (p->module()->is_named()) {
|
||||
// We don't archive unnamed modules, or packages in unnamed modules. They will be
|
||||
// created on-demand at runtime as classes in such packages are loaded.
|
||||
if (p->should_be_archived()) {
|
||||
archived_packages->at_put(n++, p);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -208,6 +208,7 @@ public:
|
||||
void print(outputStream* st = tty);
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
bool should_be_archived() const;
|
||||
void iterate_symbols(MetaspaceClosure* closure);
|
||||
PackageEntry* allocate_archived_entry() const;
|
||||
void init_as_archived_entry();
|
||||
|
||||
@ -149,6 +149,7 @@ class outputStream;
|
||||
LOG_TAG(oopstorage) \
|
||||
LOG_TAG(os) \
|
||||
LOG_TAG(owner) \
|
||||
LOG_TAG(package) \
|
||||
LOG_TAG(page) \
|
||||
LOG_TAG(pagesize) \
|
||||
LOG_TAG(parser) \
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include "cds/metaspaceShared.hpp"
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/classLoaderDataGraph.hpp"
|
||||
#include "classfile/classLoaderDataShared.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
@ -897,14 +898,20 @@ jint universe_init() {
|
||||
return JNI_EINVAL;
|
||||
}
|
||||
|
||||
ClassLoaderData::init_null_class_loader_data();
|
||||
|
||||
#if INCLUDE_CDS
|
||||
if (CDSConfig::is_using_archive()) {
|
||||
// Read the data structures supporting the shared spaces (shared
|
||||
// system dictionary, symbol table, etc.)
|
||||
MetaspaceShared::initialize_shared_spaces();
|
||||
}
|
||||
#endif
|
||||
|
||||
ClassLoaderData::init_null_class_loader_data();
|
||||
|
||||
#if INCLUDE_CDS
|
||||
if (CDSConfig::is_using_full_module_graph()) {
|
||||
ClassLoaderDataShared::restore_archived_entries_for_null_class_loader_data();
|
||||
}
|
||||
if (CDSConfig::is_dumping_archive()) {
|
||||
CDSConfig::prepare_for_dumping();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -40,6 +40,7 @@ class ArchivedClassLoaders {
|
||||
private final ClassLoader appLoader;
|
||||
private final ServicesCatalog[] servicesCatalogs;
|
||||
private final Map<String, ?> packageToModule;
|
||||
private final Module unnamedModuleForBootLoader;
|
||||
|
||||
private ArchivedClassLoaders() {
|
||||
bootLoader = ClassLoaders.bootLoader();
|
||||
@ -52,6 +53,7 @@ class ArchivedClassLoaders {
|
||||
servicesCatalogs[2] = ServicesCatalog.getServicesCatalog(appLoader);
|
||||
|
||||
packageToModule = BuiltinClassLoader.packageToModule();
|
||||
unnamedModuleForBootLoader = BootLoader.getUnnamedModule();
|
||||
}
|
||||
|
||||
ClassLoader bootLoader() {
|
||||
@ -82,6 +84,10 @@ class ArchivedClassLoaders {
|
||||
return packageToModule;
|
||||
}
|
||||
|
||||
Module unnamedModuleForBootLoader() {
|
||||
return unnamedModuleForBootLoader;
|
||||
}
|
||||
|
||||
static void archive() {
|
||||
archivedClassLoaders = new ArchivedClassLoaders();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -61,7 +61,12 @@ public class BootLoader {
|
||||
|
||||
static {
|
||||
JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
|
||||
UNNAMED_MODULE = jla.defineUnnamedModule(null);
|
||||
ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
|
||||
if (archivedClassLoaders != null) {
|
||||
UNNAMED_MODULE = archivedClassLoaders.unnamedModuleForBootLoader();
|
||||
} else {
|
||||
UNNAMED_MODULE = jla.defineUnnamedModule(null);
|
||||
}
|
||||
jla.addEnableNativeAccess(UNNAMED_MODULE);
|
||||
setBootLoaderUnnamedModule0(UNNAMED_MODULE);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user