mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8186842: Use Java class loaders for creating the CDS archive
Co-authored-by: Ioi Lam <ioi.lam@oracle.com> Reviewed-by: coleenp, jiangli, iklam, mseledtsov
This commit is contained in:
parent
de3cc93ca6
commit
cf223c0791
33 changed files with 662 additions and 130 deletions
|
@ -147,6 +147,7 @@ ClassPathEntry* ClassLoader::_jrt_entry = NULL;
|
|||
ClassPathEntry* ClassLoader::_first_append_entry = NULL;
|
||||
ClassPathEntry* ClassLoader::_last_append_entry = NULL;
|
||||
int ClassLoader::_num_entries = 0;
|
||||
int ClassLoader::_num_boot_entries = -1;
|
||||
#if INCLUDE_CDS
|
||||
GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL;
|
||||
GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL;
|
||||
|
@ -242,7 +243,7 @@ const char* ClassLoader::package_from_name(const char* const class_name, bool* b
|
|||
|
||||
// Given a fully qualified class name, find its defining package in the class loader's
|
||||
// package entry table.
|
||||
static PackageEntry* get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) {
|
||||
PackageEntry* ClassLoader::get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) {
|
||||
ResourceMark rm(THREAD);
|
||||
const char *pkg_name = ClassLoader::package_from_name(class_name);
|
||||
if (pkg_name == NULL) {
|
||||
|
@ -509,7 +510,7 @@ ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
|
|||
#endif
|
||||
|
||||
} else {
|
||||
PackageEntry* package_entry = get_package_entry(name, ClassLoaderData::the_null_class_loader_data(), CHECK_NULL);
|
||||
PackageEntry* package_entry = ClassLoader::get_package_entry(name, ClassLoaderData::the_null_class_loader_data(), CHECK_NULL);
|
||||
if (package_entry != NULL) {
|
||||
ResourceMark rm;
|
||||
// Get the module name
|
||||
|
@ -540,6 +541,13 @@ ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JImageLocationRef ClassLoader::jimage_find_resource(JImageFile* jf,
|
||||
const char* module_name,
|
||||
const char* file_name,
|
||||
jlong &size) {
|
||||
return ((*JImageFindResource)(jf, module_name, get_jimage_version_string(), file_name, &size));
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
bool ctw_visitor(JImageFile* jimage,
|
||||
const char* module_name, const char* version, const char* package,
|
||||
|
@ -1459,9 +1467,6 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
|
|||
// This would include:
|
||||
// [--patch-module=<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build]
|
||||
//
|
||||
// DumpSharedSpaces and search_append_only are mutually exclusive and cannot
|
||||
// be true at the same time.
|
||||
assert(!(DumpSharedSpaces && search_append_only), "DumpSharedSpaces and search_append_only are both true");
|
||||
|
||||
// Load Attempt #1: --patch-module
|
||||
// Determine the class' defining module. If it appears in the _patch_mod_entries,
|
||||
|
@ -1507,6 +1512,11 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
|
|||
|
||||
e = _first_append_entry;
|
||||
while (e != NULL) {
|
||||
if (DumpSharedSpaces && classpath_index >= _num_boot_entries) {
|
||||
// Do not load any class from the app classpath using the boot loader. Let
|
||||
// the built-in app class laoder load them.
|
||||
break;
|
||||
}
|
||||
stream = e->open_stream(file_name, CHECK_NULL);
|
||||
if (!context.check(stream, classpath_index)) {
|
||||
return NULL;
|
||||
|
@ -1520,9 +1530,6 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
|
|||
}
|
||||
|
||||
if (NULL == stream) {
|
||||
if (DumpSharedSpaces) {
|
||||
tty->print_cr("Preload Warning: Cannot find %s", class_name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1548,6 +1555,100 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
|
|||
return context.record_result(name, e, classpath_index, result, THREAD);
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
static char* skip_uri_protocol(char* source) {
|
||||
if (strncmp(source, "file:", 5) == 0) {
|
||||
// file: protocol path could start with file:/ or file:///
|
||||
// locate the char after all the forward slashes
|
||||
int offset = 5;
|
||||
while (*(source + offset) == '/') {
|
||||
offset++;
|
||||
}
|
||||
source += offset;
|
||||
// for non-windows platforms, move back one char as the path begins with a '/'
|
||||
#ifndef _WINDOWS
|
||||
source -= 1;
|
||||
#endif
|
||||
} else if (strncmp(source, "jrt:/", 5) == 0) {
|
||||
source += 5;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
void ClassLoader::record_shared_class_loader_type(InstanceKlass* ik, const ClassFileStream* stream) {
|
||||
assert(DumpSharedSpaces, "sanity");
|
||||
assert(stream != NULL, "sanity");
|
||||
|
||||
if (ik->is_anonymous()) {
|
||||
// We do not archive anonymous classes.
|
||||
return;
|
||||
}
|
||||
|
||||
if (stream->source() == NULL) {
|
||||
if (ik->class_loader() == NULL) {
|
||||
// JFR classes
|
||||
ik->set_shared_classpath_index(0);
|
||||
ik->set_class_loader_type(ClassLoader::BOOT_LOADER);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build");
|
||||
|
||||
ModuleEntry* module = ik->module();
|
||||
ClassPathEntry* e = NULL;
|
||||
int classpath_index = 0;
|
||||
|
||||
// Check if the class is from the runtime image
|
||||
if (module != NULL && (module->location() != NULL) &&
|
||||
(module->location()->starts_with("jrt:"))) {
|
||||
e = _jrt_entry;
|
||||
classpath_index = 0;
|
||||
} else {
|
||||
classpath_index = 1;
|
||||
ResourceMark rm;
|
||||
char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN);
|
||||
for (e = _first_append_entry; e != NULL; e = e->next()) {
|
||||
if (get_canonical_path(e->name(), canonical_path, JVM_MAXPATHLEN)) {
|
||||
char* src = (char*)stream->source();
|
||||
// save the path from the file: protocol or the module name from the jrt: protocol
|
||||
// if no protocol prefix is found, src is the same as stream->source() after the following call
|
||||
src = skip_uri_protocol(src);
|
||||
if (strcmp(canonical_path, os::native_path((char*)src)) == 0) {
|
||||
break;
|
||||
}
|
||||
classpath_index ++;
|
||||
}
|
||||
}
|
||||
if (e == NULL) {
|
||||
assert(ik->shared_classpath_index() < 0,
|
||||
"must be a class from a custom jar which isn't in the class path or boot class path");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (classpath_index < _num_boot_entries) {
|
||||
// ik is either:
|
||||
// 1) a boot class loaded from the runtime image during vm initialization (classpath_index = 0); or
|
||||
// 2) a user's class from -Xbootclasspath/a (classpath_index > 0)
|
||||
// In the second case, the classpath_index, classloader_type will be recorded via
|
||||
// context.record_result() in ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS).
|
||||
if (classpath_index > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ResourceMark rm;
|
||||
const char* const class_name = ik->name()->as_C_string();
|
||||
const char* const file_name = file_name_for_class_name(class_name,
|
||||
ik->name()->utf8_length());
|
||||
assert(file_name != NULL, "invariant");
|
||||
Thread* THREAD = Thread::current();
|
||||
ClassLoaderExt::Context context(class_name, file_name, CATCH);
|
||||
context.record_result(ik->name(), e, classpath_index, ik, THREAD);
|
||||
}
|
||||
#endif // INCLUDE_CDS
|
||||
|
||||
// Initialize the class loader's access to methods in libzip. Parse and
|
||||
// process the boot classpath into a list ClassPathEntry objects. Once
|
||||
// this list has been created, it must not change order (see class PackageInfo)
|
||||
|
@ -1632,6 +1733,7 @@ void ClassLoader::initialize() {
|
|||
#if INCLUDE_CDS
|
||||
void ClassLoader::initialize_shared_path() {
|
||||
if (DumpSharedSpaces) {
|
||||
_num_boot_entries = _num_entries;
|
||||
ClassLoaderExt::setup_search_paths();
|
||||
_shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue