8249262: Initialize InstanceKlass::_package_entry during CDS dump time

Reviewed-by: iklam, minqi
This commit is contained in:
Calvin Cheung 2021-01-28 16:17:46 +00:00
parent 3aabbd7216
commit bbbfaa58c0
7 changed files with 64 additions and 13 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,8 @@
#if INCLUDE_CDS_JAVA_HEAP #if INCLUDE_CDS_JAVA_HEAP
bool ClassLoaderDataShared::_full_module_graph_loaded = false;
class ArchivedClassLoaderData { class ArchivedClassLoaderData {
Array<PackageEntry*>* _packages; Array<PackageEntry*>* _packages;
Array<ModuleEntry*>* _modules; Array<ModuleEntry*>* _modules;
@ -214,6 +216,7 @@ void ClassLoaderDataShared::restore_java_platform_loader_from_archive(ClassLoade
void ClassLoaderDataShared::restore_java_system_loader_from_archive(ClassLoaderData* loader_data) { void ClassLoaderDataShared::restore_java_system_loader_from_archive(ClassLoaderData* loader_data) {
assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be"); assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
_archived_system_loader_data.restore(loader_data, true, true); _archived_system_loader_data.restore(loader_data, true, true);
_full_module_graph_loaded = true;
} }
#endif // INCLUDE_CDS_JAVA_HEAP #endif // INCLUDE_CDS_JAVA_HEAP

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ class MetaspaceClosure;
class SerializeClosure; class SerializeClosure;
class ClassLoaderDataShared : AllStatic { class ClassLoaderDataShared : AllStatic {
static bool _full_module_graph_loaded;
public: public:
static void allocate_archived_tables(); static void allocate_archived_tables();
static void iterate_symbols(MetaspaceClosure* closure); static void iterate_symbols(MetaspaceClosure* closure);
@ -43,6 +44,7 @@ public:
static oop restore_archived_oops_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_platform_loader_from_archive(ClassLoaderData* loader_data);
static void restore_java_system_loader_from_archive(ClassLoaderData* loader_data); static void restore_java_system_loader_from_archive(ClassLoaderData* loader_data);
static bool is_full_module_graph_loaded() { return _full_module_graph_loaded; }
}; };
#endif // SHARE_CLASSFILE_CLASSLOADERDATASHARED_HPP #endif // SHARE_CLASSFILE_CLASSLOADERDATASHARED_HPP

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -222,8 +222,11 @@ PackageEntry* PackageEntry::allocate_archived_entry() const {
PackageEntry* PackageEntry::get_archived_entry(PackageEntry* orig_entry) { PackageEntry* PackageEntry::get_archived_entry(PackageEntry* orig_entry) {
PackageEntry** ptr = _archived_packages_entries->get(orig_entry); PackageEntry** ptr = _archived_packages_entries->get(orig_entry);
assert(ptr != NULL && *ptr != NULL, "must have been allocated"); if (ptr != NULL) {
return *ptr; return *ptr;
} else {
return NULL;
}
} }
void PackageEntry::iterate_symbols(MetaspaceClosure* closure) { void PackageEntry::iterate_symbols(MetaspaceClosure* closure) {

View file

@ -1053,11 +1053,19 @@ InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
return k; return k;
} }
PackageEntry* SystemDictionaryShared::get_package_entry_from_class_name(Handle class_loader, Symbol* class_name) { PackageEntry* SystemDictionaryShared::get_package_entry_from_class(InstanceKlass* ik, Handle class_loader) {
PackageEntry* pkg_entry = NULL; PackageEntry* pkg_entry = ik->package();
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name); if (MetaspaceShared::use_full_module_graph() && ik->is_shared() && pkg_entry != NULL) {
assert(MetaspaceShared::is_in_shared_metaspace(pkg_entry), "must be");
assert(!ik->is_shared_unregistered_class(), "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());
if (pkg_name != NULL) { if (pkg_name != NULL) {
pkg_entry = class_loader_data(class_loader)->packages()->lookup_only(pkg_name); pkg_entry = class_loader_data(class_loader)->packages()->lookup_only(pkg_name);
} else {
pkg_entry = NULL;
} }
return pkg_entry; return pkg_entry;
} }
@ -1072,7 +1080,7 @@ InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
SystemDictionary::is_system_class_loader(class_loader())) || SystemDictionary::is_system_class_loader(class_loader())) ||
(ik->is_shared_platform_class() && (ik->is_shared_platform_class() &&
SystemDictionary::is_platform_class_loader(class_loader()))) { SystemDictionary::is_platform_class_loader(class_loader()))) {
PackageEntry* pkg_entry = get_package_entry_from_class_name(class_loader, class_name); PackageEntry* pkg_entry = get_package_entry_from_class(ik, class_loader);
Handle protection_domain = Handle protection_domain =
SystemDictionaryShared::init_security_info(class_loader, ik, pkg_entry, CHECK_NULL); SystemDictionaryShared::init_security_info(class_loader, ik, pkg_entry, CHECK_NULL);
return load_shared_class(ik, class_loader, protection_domain, NULL, pkg_entry, THREAD); return load_shared_class(ik, class_loader, protection_domain, NULL, pkg_entry, THREAD);
@ -1172,7 +1180,7 @@ InstanceKlass* SystemDictionaryShared::acquire_class_for_current_thread(
loader_data->add_class(ik); loader_data->add_class(ik);
// Get the package entry. // Get the package entry.
PackageEntry* pkg_entry = get_package_entry_from_class_name(class_loader, ik->name()); PackageEntry* pkg_entry = get_package_entry_from_class(ik, class_loader);
// Load and check super/interfaces, restore unsharable info // Load and check super/interfaces, restore unsharable info
InstanceKlass* shared_klass = load_shared_class(ik, class_loader, protection_domain, InstanceKlass* shared_klass = load_shared_class(ik, class_loader, protection_domain,
@ -1684,7 +1692,7 @@ InstanceKlass* SystemDictionaryShared::prepare_shared_lambda_proxy_class(Instanc
InstanceKlass* caller_ik, TRAPS) { InstanceKlass* caller_ik, TRAPS) {
Handle class_loader(THREAD, caller_ik->class_loader()); Handle class_loader(THREAD, caller_ik->class_loader());
Handle protection_domain; Handle protection_domain;
PackageEntry* pkg_entry = get_package_entry_from_class_name(class_loader, caller_ik->name()); PackageEntry* pkg_entry = get_package_entry_from_class(caller_ik, class_loader);
if (caller_ik->class_loader() != NULL) { if (caller_ik->class_loader() != NULL) {
protection_domain = SystemDictionaryShared::init_security_info(class_loader, caller_ik, pkg_entry, CHECK_NULL); protection_domain = SystemDictionaryShared::init_security_info(class_loader, caller_ik, pkg_entry, CHECK_NULL);
} }

View file

@ -135,7 +135,7 @@ private:
TRAPS); TRAPS);
static Handle get_package_name(Symbol* class_name, TRAPS); static Handle get_package_name(Symbol* class_name, TRAPS);
static PackageEntry* get_package_entry_from_class_name(Handle class_loader, Symbol* class_name); static PackageEntry* get_package_entry_from_class(InstanceKlass* ik, Handle class_loader);
// Package handling: // Package handling:

View file

@ -1846,6 +1846,11 @@ intx MetaspaceShared::final_delta() {
} }
bool MetaspaceShared::use_full_module_graph() { bool MetaspaceShared::use_full_module_graph() {
#if INCLUDE_CDS_JAVA_HEAP
if (ClassLoaderDataShared::is_full_module_graph_loaded()) {
return true;
}
#endif
bool result = _use_optimized_module_handling && _use_full_module_graph && bool result = _use_optimized_module_handling && _use_full_module_graph &&
(UseSharedSpaces || DumpSharedSpaces) && HeapShared::is_heap_object_archiving_allowed(); (UseSharedSpaces || DumpSharedSpaces) && HeapShared::is_heap_object_archiving_allowed();
if (result && UseSharedSpaces) { if (result && UseSharedSpaces) {

View file

@ -2538,7 +2538,7 @@ void InstanceKlass::remove_unshareable_info() {
_oop_map_cache = NULL; _oop_map_cache = NULL;
// clear _nest_host to ensure re-load at runtime // clear _nest_host to ensure re-load at runtime
_nest_host = NULL; _nest_host = NULL;
_package_entry = NULL; init_shared_package_entry();
_dep_context_last_cleaned = 0; _dep_context_last_cleaned = 0;
} }
@ -2551,6 +2551,27 @@ void InstanceKlass::remove_java_mirror() {
} }
} }
void InstanceKlass::init_shared_package_entry() {
#if !INCLUDE_CDS_JAVA_HEAP
_package_entry = NULL;
#else
if (!MetaspaceShared::use_full_module_graph()) {
_package_entry = NULL;
} else if (DynamicDumpSharedSpaces) {
if (!MetaspaceShared::is_in_shared_metaspace(_package_entry)) {
_package_entry = NULL;
}
} else {
if (is_shared_unregistered_class()) {
_package_entry = NULL;
} else {
_package_entry = PackageEntry::get_archived_entry(_package_entry);
}
}
ArchivePtrMarker::mark_pointer((address**)&_package_entry);
#endif
}
void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain,
PackageEntry* pkg_entry, TRAPS) { PackageEntry* pkg_entry, TRAPS) {
// SystemDictionary::add_to_hierarchy() sets the init_state to loaded // SystemDictionary::add_to_hierarchy() sets the init_state to loaded
@ -2834,6 +2855,15 @@ void InstanceKlass::set_package(ClassLoaderData* loader_data, PackageEntry* pkg_
check_prohibited_package(name(), loader_data, CHECK); check_prohibited_package(name(), loader_data, CHECK);
} }
if (is_shared() && _package_entry == pkg_entry) {
if (MetaspaceShared::use_full_module_graph()) {
// we can use the saved package
return;
} else {
_package_entry = NULL;
}
}
// ClassLoader::package_from_class_name has already incremented the refcount of the symbol // ClassLoader::package_from_class_name has already incremented the refcount of the symbol
// it returns, so we need to decrement it when the current function exits. // it returns, so we need to decrement it when the current function exits.
TempNewSymbol from_class_name = TempNewSymbol from_class_name =