< prev index next > src/hotspot/share/classfile/systemDictionary.cpp
Print this page
* questions.
*
*/
#include "precompiled.hpp"
+ #include "cds/aotLinkedClassBulkLoader.hpp"
#include "cds/cdsConfig.hpp"
#include "cds/heapShared.hpp"
#include "classfile/classFileParser.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoadInfo.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/klassFactory.hpp"
#include "classfile/loaderConstraints.hpp"
+ #include "classfile/modules.hpp"
#include "classfile/packageEntry.hpp"
#include "classfile/placeholders.hpp"
#include "classfile/protectionDomainCache.hpp"
#include "classfile/resolutionErrors.hpp"
#include "classfile/stringTable.hpp"
#include "runtime/synchronizer.hpp"
#include "services/classLoadingService.hpp"
#include "services/diagnosticCommand.hpp"
#include "services/finalizerService.hpp"
#include "services/threadService.hpp"
+ #include "utilities/growableArray.hpp"
#include "utilities/macros.hpp"
#include "utilities/utf8.hpp"
#if INCLUDE_CDS
#include "classfile/systemDictionaryShared.hpp"
#endif
oop SystemDictionary::java_platform_loader() {
return _java_platform_loader.resolve();
}
void SystemDictionary::compute_java_loaders(TRAPS) {
! if (_java_system_loader.is_empty()) {
! oop system_loader = get_system_class_loader_impl(CHECK);
! _java_system_loader = OopHandle(Universe::vm_global(), system_loader);
} else {
// It must have been restored from the archived module graph
assert(CDSConfig::is_using_archive(), "must be");
assert(CDSConfig::is_using_full_module_graph(), "must be");
DEBUG_ONLY(
! oop system_loader = get_system_class_loader_impl(CHECK);
! assert(_java_system_loader.resolve() == system_loader, "must be");
)
}
! if (_java_platform_loader.is_empty()) {
! oop platform_loader = get_platform_class_loader_impl(CHECK);
! _java_platform_loader = OopHandle(Universe::vm_global(), platform_loader);
} else {
// It must have been restored from the archived module graph
assert(CDSConfig::is_using_archive(), "must be");
assert(CDSConfig::is_using_full_module_graph(), "must be");
DEBUG_ONLY(
! oop platform_loader = get_platform_class_loader_impl(CHECK);
! assert(_java_platform_loader.resolve() == platform_loader, "must be");
)
}
}
oop SystemDictionary::get_system_class_loader_impl(TRAPS) {
oop SystemDictionary::java_platform_loader() {
return _java_platform_loader.resolve();
}
void SystemDictionary::compute_java_loaders(TRAPS) {
! if (_java_platform_loader.is_empty()) {
! oop platform_loader = get_platform_class_loader_impl(CHECK);
! _java_platform_loader = OopHandle(Universe::vm_global(), platform_loader);
+ if (CDSConfig::is_dumping_final_static_archive()) {
+ AOTLinkedClassBulkLoader::load_platform_classes(THREAD);
+ }
} else {
// It must have been restored from the archived module graph
assert(CDSConfig::is_using_archive(), "must be");
assert(CDSConfig::is_using_full_module_graph(), "must be");
DEBUG_ONLY(
! oop platform_loader = get_platform_class_loader_impl(CHECK);
! assert(_java_platform_loader.resolve() == platform_loader, "must be");
)
}
! if (_java_system_loader.is_empty()) {
! oop system_loader = get_system_class_loader_impl(CHECK);
! _java_system_loader = OopHandle(Universe::vm_global(), system_loader);
+ if (CDSConfig::is_dumping_final_static_archive()) {
+ AOTLinkedClassBulkLoader::load_app_classes(THREAD);
+ }
} else {
// It must have been restored from the archived module graph
assert(CDSConfig::is_using_archive(), "must be");
assert(CDSConfig::is_using_full_module_graph(), "must be");
DEBUG_ONLY(
! oop system_loader = get_system_class_loader_impl(CHECK);
! assert(_java_system_loader.resolve() == system_loader, "must be");
)
}
}
oop SystemDictionary::get_system_class_loader_impl(TRAPS) {
ModuleEntry* mod_entry = (pkg_entry == nullptr) ? nullptr : pkg_entry->module();
bool should_be_in_named_module = (mod_entry != nullptr && mod_entry->is_named());
bool was_archived_from_named_module = scp_entry->in_named_module();
bool visible;
! if (was_archived_from_named_module) {
if (should_be_in_named_module) {
// Is the module loaded from the same location as during dump time?
visible = mod_entry->shared_path_index() == scp_index;
if (visible) {
assert(!mod_entry->is_patched(), "cannot load archived classes for patched module");
ModuleEntry* mod_entry = (pkg_entry == nullptr) ? nullptr : pkg_entry->module();
bool should_be_in_named_module = (mod_entry != nullptr && mod_entry->is_named());
bool was_archived_from_named_module = scp_entry->in_named_module();
bool visible;
! if (mod_entry != nullptr && mod_entry->location() == nullptr && mod_entry->is_named()) {
+ // Archived module for dynamic proxies. It's always visible.
+ assert(Modules::is_dynamic_proxy_module(mod_entry), "must be");
+ visible = true;
+ } else if (was_archived_from_named_module) {
if (should_be_in_named_module) {
// Is the module loaded from the same location as during dump time?
visible = mod_entry->shared_path_index() == scp_index;
if (visible) {
assert(!mod_entry->is_patched(), "cannot load archived classes for patched module");
// For boot loader, ensure that GetSystemPackage knows that a class in this
// package was loaded.
if (loader_data->is_the_null_class_loader_data()) {
s2 path_index = ik->shared_classpath_index();
! ik->set_classpath_index(path_index);
}
// notify a class loaded from shared object
ClassLoadingService::notify_class_loaded(ik, true /* shared class */);
}
#endif // INCLUDE_CDS
InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Handle class_loader, TRAPS) {
// For boot loader, ensure that GetSystemPackage knows that a class in this
// package was loaded.
if (loader_data->is_the_null_class_loader_data()) {
s2 path_index = ik->shared_classpath_index();
! if (path_index >= 0) { // FIXME ... for lambda form classes
+ ik->set_classpath_index(path_index);
+
+ if (CDSConfig::is_dumping_final_static_archive()) {
+ if (path_index > ClassLoaderExt::max_used_path_index()) {
+ ClassLoaderExt::set_max_used_path_index(path_index);
+ }
+ }
+ }
}
// notify a class loaded from shared object
ClassLoadingService::notify_class_loaded(ik, true /* shared class */);
+
+ if (CDSConfig::is_dumping_final_static_archive()) {
+ SystemDictionaryShared::init_dumptime_info(ik);
+ if (SystemDictionary::is_platform_class_loader(loader_data->class_loader())) {
+ ClassLoaderExt::set_has_platform_classes();
+ } else if (SystemDictionary::is_system_class_loader(loader_data->class_loader())) {
+ ClassLoaderExt::set_has_app_classes();
+ }
+ }
}
#endif // INCLUDE_CDS
InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Handle class_loader, TRAPS) {
InstanceKlass* k = nullptr;
#if INCLUDE_CDS
if (CDSConfig::is_using_archive())
{
! PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
if (ik != nullptr && ik->is_shared_boot_class() && !ik->shared_loading_failed()) {
SharedClassLoadingMark slm(THREAD, ik);
k = load_shared_class(ik, class_loader, Handle(), nullptr, pkg_entry, CHECK_NULL);
}
}
#endif
if (k == nullptr) {
// Use VM class loader
! PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
k = ClassLoader::load_class(class_name, pkg_entry, search_only_bootloader_append, CHECK_NULL);
}
// find_or_define_instance_class may return a different InstanceKlass
if (k != nullptr) {
InstanceKlass* k = nullptr;
#if INCLUDE_CDS
if (CDSConfig::is_using_archive())
{
! PerfTraceElapsedTime vmtimer(ClassLoader::perf_shared_classload_time());
InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
if (ik != nullptr && ik->is_shared_boot_class() && !ik->shared_loading_failed()) {
SharedClassLoadingMark slm(THREAD, ik);
k = load_shared_class(ik, class_loader, Handle(), nullptr, pkg_entry, CHECK_NULL);
}
}
#endif
if (k == nullptr) {
// Use VM class loader
! PerfTraceElapsedTime vmtimer(ClassLoader::perf_sys_classload_time());
k = ClassLoader::load_class(class_name, pkg_entry, search_only_bootloader_append, CHECK_NULL);
}
// find_or_define_instance_class may return a different InstanceKlass
if (k != nullptr) {
dictionary->add_klass(current, name, k);
}
mu1.notify_all();
}
+ #if INCLUDE_CDS
+ // Indicate that loader_data has initiated the loading of class k, which
+ // has already been defined by a parent loader.
+ // This API should be used only by AOTLinkedClassBulkLoader
+ void SystemDictionary::add_to_initiating_loader(JavaThread* current,
+ InstanceKlass* k,
+ ClassLoaderData* loader_data) {
+ assert(CDSConfig::is_using_aot_linked_classes(), "must be");
+ assert_locked_or_safepoint(SystemDictionary_lock);
+ Symbol* name = k->name();
+ Dictionary* dictionary = loader_data->dictionary();
+ assert(k->is_loaded(), "must be");
+ assert(k->class_loader_data() != loader_data, "only for classes defined by a parent loader");
+ assert(dictionary->find_class(current, name) == nullptr, "sanity");
+ dictionary->add_klass(current, name, k);
+ }
+ #endif
// Try to find a class name using the loader constraints. The
// loader constraints might know about a class that isn't fully loaded
// yet and these will be ignored.
Klass* SystemDictionary::find_constrained_instance_or_array_klass(
"Out of space in CodeCache for method handle intrinsic");
}
return nullptr;
}
+ #if INCLUDE_CDS
+ void SystemDictionary::get_all_method_handle_intrinsics(GrowableArray<Method*>* methods) {
+ auto do_method = [&] (InvokeMethodKey& key, Method*& m) {
+ methods->append(m);
+ };
+ _invoke_method_intrinsic_table->iterate_all(do_method);
+ }
+
+ void SystemDictionary::restore_archived_method_handle_intrinsics() {
+ if (UseSharedSpaces) {
+ EXCEPTION_MARK;
+ restore_archived_method_handle_intrinsics_impl(THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ vm_exit_during_initialization(err_msg("Failed to restore archived method handle intrinsics"));
+ }
+ }
+ }
+
+ void SystemDictionary::restore_archived_method_handle_intrinsics_impl(TRAPS) {
+ Array<Method*>* list = MetaspaceShared::archived_method_handle_intrinsics();
+ for (int i = 0; i < list->length(); i++) {
+ methodHandle m(THREAD, list->at(i));
+ Method::restore_archived_method_handle_intrinsic(m, CHECK);
+ m->constants()->restore_unshareable_info(CHECK);
+ if (!Arguments::is_interpreter_only() || m->intrinsic_id() == vmIntrinsics::_linkToNative) {
+ AdapterHandlerLibrary::create_native_wrapper(m);
+ if (!m->has_compiled_code()) {
+ ResourceMark rm(THREAD);
+ vm_exit_during_initialization(err_msg("Failed to initialize method %s", m->external_name()));
+ }
+ }
+
+ const int iid_as_int = vmIntrinsics::as_int(m->intrinsic_id());
+ InvokeMethodKey key(m->signature(), iid_as_int);
+ bool created = _invoke_method_intrinsic_table->put(key, m());
+ assert(created, "must be");
+ }
+ }
+ #endif
+
// Helper for unpacking the return value from linkMethod and linkCallSite.
static Method* unpack_method_and_appendix(Handle mname,
Klass* accessing_klass,
objArrayHandle appendix_box,
Handle* appendix_result,
< prev index next >