mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8187118: Remove appending -cp path to the boot class path at AppCDS dump time
8187119: Consolidate record_shared_class_loader_type() and record_result() Remove -cp path from the boot append list at dump time and other AppCDS cleanups. Reviewed-by: lfoltan, iklam
This commit is contained in:
parent
768e1121de
commit
7409630577
6 changed files with 240 additions and 153 deletions
|
@ -145,9 +145,9 @@ GrowableArray<ModuleClassPathList*>* ClassLoader::_exploded_entries = NULL;
|
||||||
ClassPathEntry* ClassLoader::_jrt_entry = NULL;
|
ClassPathEntry* ClassLoader::_jrt_entry = NULL;
|
||||||
ClassPathEntry* ClassLoader::_first_append_entry = NULL;
|
ClassPathEntry* ClassLoader::_first_append_entry = NULL;
|
||||||
ClassPathEntry* ClassLoader::_last_append_entry = NULL;
|
ClassPathEntry* ClassLoader::_last_append_entry = NULL;
|
||||||
int ClassLoader::_num_entries = 0;
|
|
||||||
int ClassLoader::_num_boot_entries = -1;
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
|
ClassPathEntry* ClassLoader::_app_classpath_entries = NULL;
|
||||||
|
ClassPathEntry* ClassLoader::_last_app_classpath_entry = NULL;
|
||||||
GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL;
|
GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL;
|
||||||
GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL;
|
GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL;
|
||||||
SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
|
SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
|
||||||
|
@ -660,20 +660,18 @@ void ClassLoader::check_shared_classpath(const char *path) {
|
||||||
|
|
||||||
void ClassLoader::setup_bootstrap_search_path() {
|
void ClassLoader::setup_bootstrap_search_path() {
|
||||||
const char* sys_class_path = Arguments::get_sysclasspath();
|
const char* sys_class_path = Arguments::get_sysclasspath();
|
||||||
const char* java_class_path = Arguments::get_appclasspath();
|
|
||||||
if (PrintSharedArchiveAndExit) {
|
if (PrintSharedArchiveAndExit) {
|
||||||
// Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
|
// Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
|
||||||
// the same as the bootcp of the shared archive.
|
// the same as the bootcp of the shared archive.
|
||||||
} else {
|
} else {
|
||||||
trace_class_path("bootstrap loader class path=", sys_class_path);
|
trace_class_path("bootstrap loader class path=", sys_class_path);
|
||||||
trace_class_path("classpath: ", java_class_path);
|
|
||||||
}
|
}
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
if (DumpSharedSpaces) {
|
if (DumpSharedSpaces) {
|
||||||
_shared_paths_misc_info->add_boot_classpath(sys_class_path);
|
_shared_paths_misc_info->add_boot_classpath(sys_class_path);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
setup_search_path(sys_class_path, true);
|
setup_boot_search_path(sys_class_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
|
@ -691,6 +689,36 @@ bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
|
||||||
delete checker;
|
delete checker;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClassLoader::setup_app_search_path(const char *class_path) {
|
||||||
|
|
||||||
|
assert(DumpSharedSpaces, "Sanity");
|
||||||
|
|
||||||
|
Thread* THREAD = Thread::current();
|
||||||
|
int len = (int)strlen(class_path);
|
||||||
|
int end = 0;
|
||||||
|
|
||||||
|
// Iterate over class path entries
|
||||||
|
for (int start = 0; start < len; start = end) {
|
||||||
|
while (class_path[end] && class_path[end] != os::path_separator()[0]) {
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
EXCEPTION_MARK;
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
|
||||||
|
strncpy(path, &class_path[start], end - start);
|
||||||
|
path[end - start] = '\0';
|
||||||
|
|
||||||
|
check_shared_classpath(path);
|
||||||
|
|
||||||
|
update_class_path_entry_list(path, false, false);
|
||||||
|
|
||||||
|
while (class_path[end] == os::path_separator()[0]) {
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Construct the array of module/path pairs as specified to --patch-module
|
// Construct the array of module/path pairs as specified to --patch-module
|
||||||
|
@ -764,10 +792,11 @@ bool ClassLoader::is_in_patch_mod_entries(Symbol* module_name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_search) {
|
// Set up the _jrt_entry if present and boot append path
|
||||||
|
void ClassLoader::setup_boot_search_path(const char *class_path) {
|
||||||
int len = (int)strlen(class_path);
|
int len = (int)strlen(class_path);
|
||||||
int end = 0;
|
int end = 0;
|
||||||
bool set_base_piece = bootstrap_search;
|
bool set_base_piece = true;
|
||||||
|
|
||||||
// Iterate over class path entries
|
// Iterate over class path entries
|
||||||
for (int start = 0; start < len; start = end) {
|
for (int start = 0; start < len; start = end) {
|
||||||
|
@ -780,10 +809,10 @@ void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_searc
|
||||||
strncpy(path, &class_path[start], end - start);
|
strncpy(path, &class_path[start], end - start);
|
||||||
path[end - start] = '\0';
|
path[end - start] = '\0';
|
||||||
|
|
||||||
// The first time through the bootstrap_search setup, it must be determined
|
|
||||||
// what the base or core piece of the boot loader search is. Either a java runtime
|
|
||||||
// image is present or this is an exploded module build situation.
|
|
||||||
if (set_base_piece) {
|
if (set_base_piece) {
|
||||||
|
// The first time through the bootstrap_search setup, it must be determined
|
||||||
|
// what the base or core piece of the boot loader search is. Either a java runtime
|
||||||
|
// image is present or this is an exploded module build situation.
|
||||||
assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, JAVA_BASE_NAME),
|
assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, JAVA_BASE_NAME),
|
||||||
"Incorrect boot loader search path, no java runtime image or " JAVA_BASE_NAME " exploded build");
|
"Incorrect boot loader search path, no java runtime image or " JAVA_BASE_NAME " exploded build");
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -797,13 +826,7 @@ void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_searc
|
||||||
assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice");
|
assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice");
|
||||||
assert(new_entry != NULL && new_entry->is_modules_image(), "No java runtime image present");
|
assert(new_entry != NULL && new_entry->is_modules_image(), "No java runtime image present");
|
||||||
_jrt_entry = new_entry;
|
_jrt_entry = new_entry;
|
||||||
++_num_entries;
|
assert(_jrt_entry->jimage() != NULL, "No java runtime image");
|
||||||
#if INCLUDE_CDS
|
|
||||||
if (DumpSharedSpaces) {
|
|
||||||
JImageFile *jimage = _jrt_entry->jimage();
|
|
||||||
assert(jimage != NULL, "No java runtime image file present");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If path does not exist, exit
|
// If path does not exist, exit
|
||||||
|
@ -813,7 +836,7 @@ void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_searc
|
||||||
} else {
|
} else {
|
||||||
// Every entry on the system boot class path after the initial base piece,
|
// Every entry on the system boot class path after the initial base piece,
|
||||||
// which is set by os::set_boot_path(), is considered an appended entry.
|
// which is set by os::set_boot_path(), is considered an appended entry.
|
||||||
update_class_path_entry_list(path, false, bootstrap_search);
|
update_class_path_entry_list(path, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
|
@ -968,7 +991,7 @@ bool ClassLoader::contains_append_entry(const char* name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassLoader::add_to_list(ClassPathEntry *new_entry) {
|
void ClassLoader::add_to_boot_append_entries(ClassPathEntry *new_entry) {
|
||||||
if (new_entry != NULL) {
|
if (new_entry != NULL) {
|
||||||
if (_last_append_entry == NULL) {
|
if (_last_append_entry == NULL) {
|
||||||
assert(_first_append_entry == NULL, "boot loader's append class path entry list not empty");
|
assert(_first_append_entry == NULL, "boot loader's append class path entry list not empty");
|
||||||
|
@ -978,11 +1001,48 @@ void ClassLoader::add_to_list(ClassPathEntry *new_entry) {
|
||||||
_last_append_entry = new_entry;
|
_last_append_entry = new_entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_num_entries++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassLoader::add_to_list(const char *apath) {
|
// Record the path entries specified in -cp during dump time. The recorded
|
||||||
update_class_path_entry_list((char*)apath, false, false);
|
// information will be used at runtime for loading the archived app classes.
|
||||||
|
//
|
||||||
|
// Note that at dump time, ClassLoader::_app_classpath_entries are NOT used for
|
||||||
|
// loading app classes. Instead, the app class are loaded by the
|
||||||
|
// jdk/internal/loader/ClassLoaders$AppClassLoader instance.
|
||||||
|
void ClassLoader::add_to_app_classpath_entries(const char* path,
|
||||||
|
ClassPathEntry* entry,
|
||||||
|
bool check_for_duplicates) {
|
||||||
|
#if INCLUDE_CDS
|
||||||
|
assert(entry != NULL, "ClassPathEntry should not be NULL");
|
||||||
|
ClassPathEntry* e = _app_classpath_entries;
|
||||||
|
if (check_for_duplicates) {
|
||||||
|
while (e != NULL) {
|
||||||
|
if (strcmp(e->name(), entry->name()) == 0) {
|
||||||
|
// entry already exists
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The entry does not exist, add to the list
|
||||||
|
if (_app_classpath_entries == NULL) {
|
||||||
|
assert(_last_app_classpath_entry == NULL, "Sanity");
|
||||||
|
_app_classpath_entries = _last_app_classpath_entry = entry;
|
||||||
|
} else {
|
||||||
|
_last_app_classpath_entry->set_next(entry);
|
||||||
|
_last_app_classpath_entry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->is_jar_file()) {
|
||||||
|
ClassLoaderExt::process_jar_manifest(entry, check_for_duplicates);
|
||||||
|
} else {
|
||||||
|
if (!os::dir_is_empty(path)) {
|
||||||
|
tty->print_cr("Error: non-empty directory '%s'", path);
|
||||||
|
exit_with_path_failure("Cannot have non-empty directory in app classpaths", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true IFF the file/dir exists and the entry was successfully created.
|
// Returns true IFF the file/dir exists and the entry was successfully created.
|
||||||
|
@ -1002,8 +1062,10 @@ bool ClassLoader::update_class_path_entry_list(const char *path,
|
||||||
|
|
||||||
// Do not reorder the bootclasspath which would break get_system_package().
|
// Do not reorder the bootclasspath which would break get_system_package().
|
||||||
// Add new entry to linked list
|
// Add new entry to linked list
|
||||||
if (!check_for_duplicates || !contains_append_entry(new_entry->name())) {
|
if (is_boot_append) {
|
||||||
ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry);
|
add_to_boot_append_entries(new_entry);
|
||||||
|
} else {
|
||||||
|
add_to_app_classpath_entries(path, new_entry, check_for_duplicates);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1323,6 +1385,7 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleCl
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by the boot classloader to load classes
|
||||||
InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) {
|
InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) {
|
||||||
assert(name != NULL, "invariant");
|
assert(name != NULL, "invariant");
|
||||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||||
|
@ -1402,11 +1465,6 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
|
||||||
|
|
||||||
e = _first_append_entry;
|
e = _first_append_entry;
|
||||||
while (e != NULL) {
|
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);
|
stream = e->open_stream(file_name, CHECK_NULL);
|
||||||
if (!context.check(stream, classpath_index)) {
|
if (!context.check(stream, classpath_index)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1442,7 +1500,11 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.record_result(name, e, classpath_index, result, THREAD);
|
if (!add_package(file_name, classpath_index, THREAD)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
|
@ -1465,7 +1527,9 @@ static char* skip_uri_protocol(char* source) {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassLoader::record_shared_class_loader_type(InstanceKlass* ik, const ClassFileStream* stream) {
|
// Record the shared classpath index and loader type for classes loaded
|
||||||
|
// by the builtin loaders at dump time.
|
||||||
|
void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream) {
|
||||||
assert(DumpSharedSpaces, "sanity");
|
assert(DumpSharedSpaces, "sanity");
|
||||||
assert(stream != NULL, "sanity");
|
assert(stream != NULL, "sanity");
|
||||||
|
|
||||||
|
@ -1474,7 +1538,8 @@ void ClassLoader::record_shared_class_loader_type(InstanceKlass* ik, const Class
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->source() == NULL) {
|
char* src = (char*)stream->source();
|
||||||
|
if (src == NULL) {
|
||||||
if (ik->class_loader() == NULL) {
|
if (ik->class_loader() == NULL) {
|
||||||
// JFR classes
|
// JFR classes
|
||||||
ik->set_shared_classpath_index(0);
|
ik->set_shared_classpath_index(0);
|
||||||
|
@ -1486,56 +1551,42 @@ void ClassLoader::record_shared_class_loader_type(InstanceKlass* ik, const Class
|
||||||
assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build");
|
assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build");
|
||||||
|
|
||||||
ModuleEntry* module = ik->module();
|
ModuleEntry* module = ik->module();
|
||||||
ClassPathEntry* e = NULL;
|
int classpath_index = -1;
|
||||||
int classpath_index = 0;
|
ResourceMark rm;
|
||||||
|
char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN);
|
||||||
|
|
||||||
// Check if the class is from the runtime image
|
// save the path from the file: protocol or the module name from the jrt: protocol
|
||||||
if (module != NULL && (module->location() != NULL) &&
|
// if no protocol prefix is found, path is the same as stream->source()
|
||||||
(module->location()->starts_with("jrt:"))) {
|
char* path = skip_uri_protocol(src);
|
||||||
e = _jrt_entry;
|
for (int i = 0; i < FileMapInfo::get_number_of_share_classpaths(); i++) {
|
||||||
classpath_index = 0;
|
SharedClassPathEntry* ent = FileMapInfo::shared_classpath(i);
|
||||||
} else {
|
if (get_canonical_path(ent->name(), canonical_path, JVM_MAXPATHLEN)) {
|
||||||
classpath_index = 1;
|
// If the path (from the class stream srouce) is the same as the shared
|
||||||
ResourceMark rm;
|
// class path, then we have a match. For classes from module image loaded by the
|
||||||
char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN);
|
// PlatformClassLoader, the stream->source() is not the name of the module image.
|
||||||
for (e = _first_append_entry; e != NULL; e = e->next()) {
|
// Need to look for 'jrt:' explicitly.
|
||||||
if (get_canonical_path(e->name(), canonical_path, JVM_MAXPATHLEN)) {
|
if (strcmp(canonical_path, os::native_path((char*)path)) == 0 ||
|
||||||
char* src = (char*)stream->source();
|
(i == 0 && string_starts_with(src, "jrt:"))) {
|
||||||
// save the path from the file: protocol or the module name from the jrt: protocol
|
classpath_index = i;
|
||||||
// if no protocol prefix is found, src is the same as stream->source() after the following call
|
break;
|
||||||
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,
|
if (classpath_index < 0) {
|
||||||
"must be a class from a custom jar which isn't in the class path or boot class path");
|
// Shared classpath entry table only contains boot class path and -cp path.
|
||||||
return;
|
// No path entry found for this class. Must be a shared class loaded by the
|
||||||
}
|
// user defined classloader.
|
||||||
|
assert(ik->shared_classpath_index() < 0, "Sanity");
|
||||||
|
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 class_name = ik->name()->as_C_string();
|
||||||
const char* const file_name = file_name_for_class_name(class_name,
|
const char* const file_name = file_name_for_class_name(class_name,
|
||||||
ik->name()->utf8_length());
|
ik->name()->utf8_length());
|
||||||
assert(file_name != NULL, "invariant");
|
assert(file_name != NULL, "invariant");
|
||||||
Thread* THREAD = Thread::current();
|
Thread* THREAD = Thread::current();
|
||||||
ClassLoaderExt::Context context(class_name, file_name, CATCH);
|
ClassLoaderExt::Context context(class_name, file_name, CATCH);
|
||||||
context.record_result(ik->name(), e, classpath_index, ik, THREAD);
|
context.record_result(ik->name(), classpath_index, ik, THREAD);
|
||||||
}
|
}
|
||||||
#endif // INCLUDE_CDS
|
#endif // INCLUDE_CDS
|
||||||
|
|
||||||
|
@ -1623,7 +1674,6 @@ void ClassLoader::initialize() {
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
void ClassLoader::initialize_shared_path() {
|
void ClassLoader::initialize_shared_path() {
|
||||||
if (DumpSharedSpaces) {
|
if (DumpSharedSpaces) {
|
||||||
_num_boot_entries = _num_entries;
|
|
||||||
ClassLoaderExt::setup_search_paths();
|
ClassLoaderExt::setup_search_paths();
|
||||||
_shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
|
_shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,14 +237,6 @@ class ClassLoader: AllStatic {
|
||||||
// Last entry in linked list of appended ClassPathEntry instances
|
// Last entry in linked list of appended ClassPathEntry instances
|
||||||
static ClassPathEntry* _last_append_entry;
|
static ClassPathEntry* _last_append_entry;
|
||||||
|
|
||||||
// Note: _num_entries includes the java runtime image and all
|
|
||||||
// the entries on the _first_append_entry linked list.
|
|
||||||
static int _num_entries;
|
|
||||||
|
|
||||||
// number of entries in the boot class path including the
|
|
||||||
// java runtime image
|
|
||||||
static int _num_boot_entries;
|
|
||||||
|
|
||||||
// Array of module names associated with the boot class loader
|
// Array of module names associated with the boot class loader
|
||||||
CDS_ONLY(static GrowableArray<char*>* _boot_modules_array;)
|
CDS_ONLY(static GrowableArray<char*>* _boot_modules_array;)
|
||||||
|
|
||||||
|
@ -254,12 +246,22 @@ class ClassLoader: AllStatic {
|
||||||
// Info used by CDS
|
// Info used by CDS
|
||||||
CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
|
CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
|
||||||
|
|
||||||
|
CDS_ONLY(static ClassPathEntry* _app_classpath_entries;)
|
||||||
|
CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;)
|
||||||
|
CDS_ONLY(static void setup_app_search_path(const char *class_path);)
|
||||||
|
static void add_to_app_classpath_entries(const char* path,
|
||||||
|
ClassPathEntry* entry,
|
||||||
|
bool check_for_duplicates);
|
||||||
|
public:
|
||||||
|
CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})
|
||||||
|
|
||||||
|
protected:
|
||||||
// Initialization:
|
// Initialization:
|
||||||
// - setup the boot loader's system class path
|
// - setup the boot loader's system class path
|
||||||
// - setup the boot loader's patch mod entries, if present
|
// - setup the boot loader's patch mod entries, if present
|
||||||
// - create the ModuleEntry for java.base
|
// - create the ModuleEntry for java.base
|
||||||
static void setup_bootstrap_search_path();
|
static void setup_bootstrap_search_path();
|
||||||
static void setup_search_path(const char *class_path, bool setting_bootstrap);
|
static void setup_boot_search_path(const char *class_path);
|
||||||
static void setup_patch_mod_entries();
|
static void setup_patch_mod_entries();
|
||||||
static void create_javabase();
|
static void create_javabase();
|
||||||
|
|
||||||
|
@ -395,7 +397,6 @@ class ClassLoader: AllStatic {
|
||||||
|
|
||||||
static ClassPathEntry* classpath_entry(int n) {
|
static ClassPathEntry* classpath_entry(int n) {
|
||||||
assert(n >= 0, "sanity");
|
assert(n >= 0, "sanity");
|
||||||
assert(!has_jrt_entry() || n < _num_entries, "sanity");
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
assert(has_jrt_entry(), "No class path entry at 0 for exploded module builds");
|
assert(has_jrt_entry(), "No class path entry at 0 for exploded module builds");
|
||||||
return ClassLoader::_jrt_entry;
|
return ClassLoader::_jrt_entry;
|
||||||
|
@ -414,15 +415,46 @@ class ClassLoader: AllStatic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int number_of_classpath_entries() {
|
|
||||||
return _num_entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_in_patch_mod_entries(Symbol* module_name);
|
static bool is_in_patch_mod_entries(Symbol* module_name);
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
// Sharing dump and restore
|
// Sharing dump and restore
|
||||||
|
|
||||||
|
// Helper function used by CDS code to get the number of boot classpath
|
||||||
|
// entries during shared classpath setup time.
|
||||||
|
static int num_boot_classpath_entries() {
|
||||||
|
assert(DumpSharedSpaces, "Should only be called at CDS dump time");
|
||||||
|
assert(has_jrt_entry(), "must have a java runtime image");
|
||||||
|
int num_entries = 1; // count the runtime image
|
||||||
|
ClassPathEntry* e = ClassLoader::_first_append_entry;
|
||||||
|
while (e != NULL) {
|
||||||
|
num_entries ++;
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
return num_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClassPathEntry* get_next_boot_classpath_entry(ClassPathEntry* e) {
|
||||||
|
if (e == ClassLoader::_jrt_entry) {
|
||||||
|
return ClassLoader::_first_append_entry;
|
||||||
|
} else {
|
||||||
|
return e->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function used by CDS code to get the number of app classpath
|
||||||
|
// entries during shared classpath setup time.
|
||||||
|
static int num_app_classpath_entries() {
|
||||||
|
assert(DumpSharedSpaces, "Should only be called at CDS dump time");
|
||||||
|
int num_entries = 0;
|
||||||
|
ClassPathEntry* e= ClassLoader::_app_classpath_entries;
|
||||||
|
while (e != NULL) {
|
||||||
|
num_entries ++;
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
return num_entries;
|
||||||
|
}
|
||||||
|
|
||||||
static void check_shared_classpath(const char *path);
|
static void check_shared_classpath(const char *path);
|
||||||
static void finalize_shared_paths_misc_info();
|
static void finalize_shared_paths_misc_info();
|
||||||
static int get_shared_paths_misc_info_size();
|
static int get_shared_paths_misc_info_size();
|
||||||
|
@ -430,7 +462,7 @@ class ClassLoader: AllStatic {
|
||||||
static bool check_shared_paths_misc_info(void* info, int size);
|
static bool check_shared_paths_misc_info(void* info, int size);
|
||||||
static void exit_with_path_failure(const char* error, const char* message);
|
static void exit_with_path_failure(const char* error, const char* message);
|
||||||
|
|
||||||
static void record_shared_class_loader_type(InstanceKlass* ik, const ClassFileStream* stream);
|
static void record_result(InstanceKlass* ik, const ClassFileStream* stream);
|
||||||
#endif
|
#endif
|
||||||
static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name,
|
static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name,
|
||||||
const char* file_name, jlong &size);
|
const char* file_name, jlong &size);
|
||||||
|
@ -446,20 +478,15 @@ class ClassLoader: AllStatic {
|
||||||
static jlong class_link_count();
|
static jlong class_link_count();
|
||||||
static jlong class_link_time_ms();
|
static jlong class_link_time_ms();
|
||||||
|
|
||||||
static void set_first_append_entry(ClassPathEntry* entry);
|
|
||||||
|
|
||||||
// indicates if class path already contains a entry (exact match by name)
|
// indicates if class path already contains a entry (exact match by name)
|
||||||
static bool contains_append_entry(const char* name);
|
static bool contains_append_entry(const char* name);
|
||||||
|
|
||||||
// adds a class path list
|
// adds a class path to the boot append entries
|
||||||
static void add_to_list(ClassPathEntry* new_entry);
|
static void add_to_boot_append_entries(ClassPathEntry* new_entry);
|
||||||
|
|
||||||
// creates a class path zip entry (returns NULL if JAR file cannot be opened)
|
// creates a class path zip entry (returns NULL if JAR file cannot be opened)
|
||||||
static ClassPathZipEntry* create_class_path_zip_entry(const char *apath, bool is_boot_append);
|
static ClassPathZipEntry* create_class_path_zip_entry(const char *apath, bool is_boot_append);
|
||||||
|
|
||||||
// add a path to class path list
|
|
||||||
static void add_to_list(const char* apath);
|
|
||||||
|
|
||||||
static bool string_ends_with(const char* str, const char* str_to_find);
|
static bool string_ends_with(const char* str, const char* str_to_find);
|
||||||
|
|
||||||
// obtain package name from a fully qualified class name
|
// obtain package name from a fully qualified class name
|
||||||
|
|
|
@ -50,40 +50,28 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceKlass* record_result(Symbol* class_name,
|
void record_result(Symbol* class_name,
|
||||||
ClassPathEntry* e,
|
const s2 classpath_index,
|
||||||
const s2 classpath_index,
|
InstanceKlass* result, TRAPS) {
|
||||||
InstanceKlass* result, TRAPS) {
|
|
||||||
if (ClassLoader::add_package(_file_name, classpath_index, THREAD)) {
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
if (DumpSharedSpaces) {
|
assert(DumpSharedSpaces, "Sanity");
|
||||||
oop loader = result->class_loader();
|
oop loader = result->class_loader();
|
||||||
s2 classloader_type = ClassLoader::BOOT_LOADER;
|
s2 classloader_type = ClassLoader::BOOT_LOADER;
|
||||||
if (SystemDictionary::is_system_class_loader(loader)) {
|
if (SystemDictionary::is_system_class_loader(loader)) {
|
||||||
classloader_type = ClassLoader::APP_LOADER;
|
classloader_type = ClassLoader::APP_LOADER;
|
||||||
ClassLoaderExt::set_has_app_classes();
|
ClassLoaderExt::set_has_app_classes();
|
||||||
} else if (SystemDictionary::is_platform_class_loader(loader)) {
|
} else if (SystemDictionary::is_platform_class_loader(loader)) {
|
||||||
classloader_type = ClassLoader::PLATFORM_LOADER;
|
classloader_type = ClassLoader::PLATFORM_LOADER;
|
||||||
ClassLoaderExt::set_has_platform_classes();
|
ClassLoaderExt::set_has_platform_classes();
|
||||||
}
|
|
||||||
result->set_shared_classpath_index(classpath_index);
|
|
||||||
result->set_class_loader_type(classloader_type);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
result->set_shared_classpath_index(classpath_index);
|
||||||
|
result->set_class_loader_type(classloader_type);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void add_class_path_entry(const char* path, bool check_for_duplicates,
|
|
||||||
ClassPathEntry* new_entry) {
|
|
||||||
ClassLoader::add_to_list(new_entry);
|
|
||||||
}
|
|
||||||
static void append_boot_classpath(ClassPathEntry* new_entry) {
|
static void append_boot_classpath(ClassPathEntry* new_entry) {
|
||||||
ClassLoader::add_to_list(new_entry);
|
ClassLoader::add_to_boot_append_entries(new_entry);
|
||||||
}
|
}
|
||||||
static void setup_search_paths() {}
|
static void setup_search_paths() {}
|
||||||
static bool is_boot_classpath(int classpath_index) {
|
static bool is_boot_classpath(int classpath_index) {
|
||||||
|
@ -96,6 +84,7 @@ public:
|
||||||
static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
|
static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates) {}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
if (DumpSharedSpaces) {
|
if (DumpSharedSpaces) {
|
||||||
ClassLoader::record_shared_class_loader_type(result, stream);
|
ClassLoader::record_result(result, stream);
|
||||||
#if INCLUDE_JVMTI
|
#if INCLUDE_JVMTI
|
||||||
assert(cached_class_file == NULL, "Sanity");
|
assert(cached_class_file == NULL, "Sanity");
|
||||||
// Archive the class stream data into the optional data section
|
// Archive the class stream data into the optional data section
|
||||||
|
|
|
@ -1465,25 +1465,23 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle
|
||||||
// java.base packages in the boot loader's PackageEntryTable.
|
// java.base packages in the boot loader's PackageEntryTable.
|
||||||
// No class outside of java.base is allowed to be loaded during
|
// No class outside of java.base is allowed to be loaded during
|
||||||
// this bootstrapping window.
|
// this bootstrapping window.
|
||||||
if (!DumpSharedSpaces) {
|
if (pkg_entry == NULL || pkg_entry->in_unnamed_module()) {
|
||||||
if (pkg_entry == NULL || pkg_entry->in_unnamed_module()) {
|
// Class is either in the unnamed package or in
|
||||||
// Class is either in the unnamed package or in
|
// a named package within the unnamed module. Either
|
||||||
// a named package within the unnamed module. Either
|
// case is outside of java.base, do not attempt to
|
||||||
// case is outside of java.base, do not attempt to
|
// load the class post java.base definition. If
|
||||||
// load the class post java.base definition. If
|
// java.base has not been defined, let the class load
|
||||||
// java.base has not been defined, let the class load
|
// and its package will be checked later by
|
||||||
// and its package will be checked later by
|
// ModuleEntryTable::verify_javabase_packages.
|
||||||
// ModuleEntryTable::verify_javabase_packages.
|
if (ModuleEntryTable::javabase_defined()) {
|
||||||
if (ModuleEntryTable::javabase_defined()) {
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
// Check that the class' package is defined within java.base.
|
||||||
// Check that the class' package is defined within java.base.
|
ModuleEntry* mod_entry = pkg_entry->module();
|
||||||
ModuleEntry* mod_entry = pkg_entry->module();
|
Symbol* mod_entry_name = mod_entry->name();
|
||||||
Symbol* mod_entry_name = mod_entry->name();
|
if (mod_entry_name->fast_compare(vmSymbols::java_base()) != 0) {
|
||||||
if (mod_entry_name->fast_compare(vmSymbols::java_base()) != 0) {
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1501,7 +1499,7 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle
|
||||||
|
|
||||||
// Prior to bootstrapping's module initialization, never load a class outside
|
// Prior to bootstrapping's module initialization, never load a class outside
|
||||||
// of the boot loader's module path
|
// of the boot loader's module path
|
||||||
assert(Universe::is_module_initialized() || DumpSharedSpaces ||
|
assert(Universe::is_module_initialized() ||
|
||||||
!search_only_bootloader_append,
|
!search_only_bootloader_append,
|
||||||
"Attempt to load a class outside of boot loader's module path");
|
"Attempt to load a class outside of boot loader's module path");
|
||||||
|
|
||||||
|
|
|
@ -266,32 +266,55 @@ void SharedClassPathEntry::metaspace_pointers_do(MetaspaceClosure* it) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileMapInfo::allocate_classpath_entry_table() {
|
void FileMapInfo::allocate_classpath_entry_table() {
|
||||||
|
assert(DumpSharedSpaces, "Sanity");
|
||||||
|
|
||||||
Thread* THREAD = Thread::current();
|
Thread* THREAD = Thread::current();
|
||||||
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
||||||
|
ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
|
||||||
|
|
||||||
|
assert(jrt != NULL,
|
||||||
|
"No modular java runtime image present when allocating the CDS classpath entry table");
|
||||||
|
|
||||||
size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
|
size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
|
||||||
int num_entries = ClassLoader::number_of_classpath_entries();
|
int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
|
||||||
|
int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
|
||||||
|
int num_entries = num_boot_classpath_entries + num_app_classpath_entries;
|
||||||
size_t bytes = entry_size * num_entries;
|
size_t bytes = entry_size * num_entries;
|
||||||
|
|
||||||
_classpath_entry_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
|
_classpath_entry_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
|
||||||
_classpath_entry_table_size = num_entries;
|
_classpath_entry_table_size = num_entries;
|
||||||
_classpath_entry_size = entry_size;
|
_classpath_entry_size = entry_size;
|
||||||
|
|
||||||
assert(ClassLoader::get_jrt_entry() != NULL,
|
// 1. boot class path
|
||||||
"No modular java runtime image present when allocating the CDS classpath entry table");
|
int i = 0;
|
||||||
|
ClassPathEntry* cpe = jrt;
|
||||||
for (int i=0; i<num_entries; i++) {
|
while (cpe != NULL) {
|
||||||
ClassPathEntry *cpe = ClassLoader::classpath_entry(i);
|
const char* type = ((cpe == jrt) ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
|
||||||
const char* type = ((i == 0) ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
|
|
||||||
|
|
||||||
log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
|
log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
|
||||||
SharedClassPathEntry* ent = shared_classpath(i);
|
SharedClassPathEntry* ent = shared_classpath(i);
|
||||||
ent->init(cpe->name(), THREAD);
|
ent->init(cpe->name(), THREAD);
|
||||||
|
if (cpe != jrt) { // No need to do jimage.
|
||||||
if (i > 0) { // No need to do jimage.
|
|
||||||
EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
|
EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
|
||||||
SharedClassUtil::update_shared_classpath(cpe, ent, THREAD);
|
SharedClassUtil::update_shared_classpath(cpe, ent, THREAD);
|
||||||
}
|
}
|
||||||
|
cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
assert(i == num_boot_classpath_entries,
|
||||||
|
"number of boot class path entry mismatch");
|
||||||
|
|
||||||
|
// 2. app class path
|
||||||
|
ClassPathEntry *acpe = ClassLoader::app_classpath_entries();
|
||||||
|
while (acpe != NULL) {
|
||||||
|
log_info(class, path)("add app shared path %s", acpe->name());
|
||||||
|
SharedClassPathEntry* ent = shared_classpath(i);
|
||||||
|
ent->init(acpe->name(), THREAD);
|
||||||
|
EXCEPTION_MARK;
|
||||||
|
SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
|
||||||
|
acpe = acpe->next();
|
||||||
|
i ++;
|
||||||
|
}
|
||||||
|
assert(i == num_entries, "number of app class path entry mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileMapInfo::validate_classpath_entry_table() {
|
bool FileMapInfo::validate_classpath_entry_table() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue