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.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,8 @@
#if INCLUDE_CDS_JAVA_HEAP
bool ClassLoaderDataShared::_full_module_graph_loaded = false;
class ArchivedClassLoaderData {
Array<PackageEntry*>* _packages;
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) {
assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
_archived_system_loader_data.restore(loader_data, true, true);
_full_module_graph_loaded = true;
}
#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.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ class MetaspaceClosure;
class SerializeClosure;
class ClassLoaderDataShared : AllStatic {
static bool _full_module_graph_loaded;
public:
static void allocate_archived_tables();
static void iterate_symbols(MetaspaceClosure* closure);
@ -43,6 +44,7 @@ public:
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 bool is_full_module_graph_loaded() { return _full_module_graph_loaded; }
};
#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.
*
* 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** ptr = _archived_packages_entries->get(orig_entry);
assert(ptr != NULL && *ptr != NULL, "must have been allocated");
return *ptr;
if (ptr != NULL) {
return *ptr;
} else {
return NULL;
}
}
void PackageEntry::iterate_symbols(MetaspaceClosure* closure) {

View file

@ -1053,11 +1053,19 @@ InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
return k;
}
PackageEntry* SystemDictionaryShared::get_package_entry_from_class_name(Handle class_loader, Symbol* class_name) {
PackageEntry* pkg_entry = NULL;
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
PackageEntry* SystemDictionaryShared::get_package_entry_from_class(InstanceKlass* ik, Handle class_loader) {
PackageEntry* pkg_entry = ik->package();
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) {
pkg_entry = class_loader_data(class_loader)->packages()->lookup_only(pkg_name);
} else {
pkg_entry = NULL;
}
return pkg_entry;
}
@ -1072,7 +1080,7 @@ InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
SystemDictionary::is_system_class_loader(class_loader())) ||
(ik->is_shared_platform_class() &&
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 =
SystemDictionaryShared::init_security_info(class_loader, ik, pkg_entry, CHECK_NULL);
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);
// 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
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) {
Handle class_loader(THREAD, caller_ik->class_loader());
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) {
protection_domain = SystemDictionaryShared::init_security_info(class_loader, caller_ik, pkg_entry, CHECK_NULL);
}

View file

@ -135,7 +135,7 @@ private:
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:

View file

@ -1846,6 +1846,11 @@ intx MetaspaceShared::final_delta() {
}
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 &&
(UseSharedSpaces || DumpSharedSpaces) && HeapShared::is_heap_object_archiving_allowed();
if (result && UseSharedSpaces) {

View file

@ -2538,7 +2538,7 @@ void InstanceKlass::remove_unshareable_info() {
_oop_map_cache = NULL;
// clear _nest_host to ensure re-load at runtime
_nest_host = NULL;
_package_entry = NULL;
init_shared_package_entry();
_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,
PackageEntry* pkg_entry, TRAPS) {
// 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);
}
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
// it returns, so we need to decrement it when the current function exits.
TempNewSymbol from_class_name =