mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8154239: -Xbootclasspath/a breaks exploded build
Correct exploded modules build system class path search for the boot loader Reviewed-by: acorn, ccheung, hseigel, jiangli
This commit is contained in:
parent
2313844e20
commit
64f4953141
11 changed files with 338 additions and 312 deletions
|
@ -141,11 +141,11 @@ PerfCounter* ClassLoader::_isUnsyncloadClass = NULL;
|
|||
PerfCounter* ClassLoader::_load_instance_class_failCounter = NULL;
|
||||
|
||||
GrowableArray<ModuleClassPathList*>* ClassLoader::_xpatch_entries = NULL;
|
||||
ClassPathEntry* ClassLoader::_first_entry = NULL;
|
||||
ClassPathEntry* ClassLoader::_last_entry = NULL;
|
||||
int ClassLoader::_num_entries = 0;
|
||||
GrowableArray<ModuleClassPathList*>* ClassLoader::_exploded_entries = NULL;
|
||||
ClassPathEntry* ClassLoader::_jrt_entry = NULL;
|
||||
ClassPathEntry* ClassLoader::_first_append_entry = NULL;
|
||||
bool ClassLoader::_has_jimage = false;
|
||||
ClassPathEntry* ClassLoader::_last_append_entry = NULL;
|
||||
int ClassLoader::_num_entries = 0;
|
||||
#if INCLUDE_CDS
|
||||
GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL;
|
||||
GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL;
|
||||
|
@ -508,7 +508,7 @@ ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
|
|||
#endif
|
||||
|
||||
} else {
|
||||
PackageEntry* package_entry = get_package_entry(name, ClassLoaderData::the_null_class_loader_data(), THREAD);
|
||||
PackageEntry* package_entry = get_package_entry(name, ClassLoaderData::the_null_class_loader_data(), CHECK_NULL);
|
||||
if (package_entry != NULL) {
|
||||
ResourceMark rm;
|
||||
// Get the module name
|
||||
|
@ -651,7 +651,6 @@ void ClassLoader::check_shared_classpath(const char *path) {
|
|||
#endif
|
||||
|
||||
void ClassLoader::setup_bootstrap_search_path() {
|
||||
assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
|
||||
const char* sys_class_path = Arguments::get_sysclasspath();
|
||||
const char* java_class_path = Arguments::get_appclasspath();
|
||||
if (PrintSharedArchiveAndExit) {
|
||||
|
@ -694,7 +693,10 @@ void ClassLoader::setup_xpatch_entries() {
|
|||
GrowableArray<ModuleXPatchPath*>* xpatch_args = Arguments::get_xpatchprefix();
|
||||
int num_of_entries = xpatch_args->length();
|
||||
|
||||
// Set up the boot loader's xpatch_entries list
|
||||
assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with -Xpatch");
|
||||
assert(!UseSharedSpaces, "UseSharedSpaces not supported with -Xpatch");
|
||||
|
||||
// Set up the boot loader's _xpatch_entries list
|
||||
_xpatch_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
|
||||
|
||||
for (int i = 0; i < num_of_entries; i++) {
|
||||
|
@ -742,10 +744,9 @@ void ClassLoader::setup_xpatch_entries() {
|
|||
}
|
||||
|
||||
void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_search) {
|
||||
int offset = 0;
|
||||
int len = (int)strlen(class_path);
|
||||
int end = 0;
|
||||
bool mark_append_entry = false;
|
||||
bool set_base_piece = bootstrap_search;
|
||||
|
||||
// Iterate over class path entries
|
||||
for (int start = 0; start < len; start = end) {
|
||||
|
@ -754,21 +755,45 @@ void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_searc
|
|||
}
|
||||
EXCEPTION_MARK;
|
||||
ResourceMark rm(THREAD);
|
||||
mark_append_entry = (mark_append_entry ||
|
||||
(bootstrap_search && (start == Arguments::bootclassloader_append_index())));
|
||||
char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
|
||||
strncpy(path, &class_path[start], end - start);
|
||||
path[end - start] = '\0';
|
||||
update_class_path_entry_list(path, false, mark_append_entry, false, bootstrap_search);
|
||||
|
||||
// Check on the state of the boot loader's append path
|
||||
if (mark_append_entry && (_first_append_entry == NULL)) {
|
||||
// Failure to mark the first append entry, most likely
|
||||
// due to a non-existent path. Record the next entry
|
||||
// as the first boot loader append entry.
|
||||
mark_append_entry = true;
|
||||
// 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) {
|
||||
assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, "java.base"),
|
||||
"Incorrect boot loader search path, no java runtime image or java.base exploded build");
|
||||
struct stat st;
|
||||
if (os::stat(path, &st) == 0) {
|
||||
// Directory found
|
||||
Thread* THREAD = Thread::current();
|
||||
ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
|
||||
|
||||
// Check for a jimage
|
||||
if (Arguments::has_jimage()) {
|
||||
assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice");
|
||||
assert(new_entry != NULL && new_entry->is_jrt(), "No java runtime image present");
|
||||
_jrt_entry = new_entry;
|
||||
++_num_entries;
|
||||
#if INCLUDE_CDS
|
||||
if (DumpSharedSpaces) {
|
||||
JImageFile *jimage = _jrt_entry->jimage();
|
||||
assert(jimage != NULL, "No java runtime image file present");
|
||||
ClassLoader::initialize_module_loader_map(jimage);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// If path does not exist, exit
|
||||
vm_exit_during_initialization("Unable to establish the boot loader search path", path);
|
||||
}
|
||||
set_base_piece = false;
|
||||
} else {
|
||||
mark_append_entry = false;
|
||||
// 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.
|
||||
update_class_path_entry_list(path, false, bootstrap_search);
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
|
@ -782,6 +807,45 @@ void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_searc
|
|||
}
|
||||
}
|
||||
|
||||
// During an exploded modules build, each module defined to the boot loader
|
||||
// will be added to the ClassLoader::_exploded_entries array.
|
||||
void ClassLoader::add_to_exploded_build_list(Symbol* module_sym, TRAPS) {
|
||||
assert(!ClassLoader::has_jrt_entry(), "Exploded build not applicable");
|
||||
|
||||
// Set up the boot loader's _exploded_entries list
|
||||
if (_exploded_entries == NULL) {
|
||||
_exploded_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(EXPLODED_ENTRY_SIZE, true);
|
||||
}
|
||||
|
||||
// Find the module's symbol
|
||||
ResourceMark rm(THREAD);
|
||||
const char *module_name = module_sym->as_C_string();
|
||||
const char *home = Arguments::get_java_home();
|
||||
const char file_sep = os::file_separator()[0];
|
||||
// 10 represents the length of "modules" + 2 file separators + \0
|
||||
size_t len = strlen(home) + strlen(module_name) + 10;
|
||||
char *path = NEW_C_HEAP_ARRAY(char, len, mtModule);
|
||||
jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
|
||||
|
||||
struct stat st;
|
||||
if (os::stat(path, &st) == 0) {
|
||||
// Directory found
|
||||
ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
|
||||
|
||||
// If the path specification is valid, enter it into this module's list.
|
||||
// There is no need to check for duplicate modules in the exploded entry list,
|
||||
// since no two modules with the same name can be defined to the boot loader.
|
||||
// This is checked at module definition time in Modules::define_module.
|
||||
if (new_entry != NULL) {
|
||||
ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
|
||||
module_cpl->add_to_list(new_entry);
|
||||
_exploded_entries->push(module_cpl);
|
||||
log_info(class, load)("path: %s", path);
|
||||
}
|
||||
}
|
||||
FREE_C_HEAP_ARRAY(char, path);
|
||||
}
|
||||
|
||||
ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
|
||||
bool throw_exception,
|
||||
bool is_boot_append, TRAPS) {
|
||||
|
@ -872,21 +936,9 @@ ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path, bo
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// The boot class loader must adhere to specfic visibility rules.
|
||||
// Prior to loading a class in a named package, the package is checked
|
||||
// to see if it is in a module defined to the boot loader. If the
|
||||
// package is not in a module defined to the boot loader, the class
|
||||
// must be loaded only in the boot loader's append path, which
|
||||
// consists of [-Xbootclasspath/a]; [jvmti appended entries]
|
||||
void ClassLoader::set_first_append_entry(ClassPathEntry *new_entry) {
|
||||
if (_first_append_entry == NULL) {
|
||||
_first_append_entry = new_entry;
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if entry already on class path
|
||||
bool ClassLoader::contains_entry(ClassPathEntry *entry) {
|
||||
ClassPathEntry* e = _first_entry;
|
||||
ClassPathEntry* e = _first_append_entry;
|
||||
while (e != NULL) {
|
||||
// assume zip entries have been canonicalized
|
||||
if (strcmp(entry->name(), e->name()) == 0) {
|
||||
|
@ -899,41 +951,24 @@ bool ClassLoader::contains_entry(ClassPathEntry *entry) {
|
|||
|
||||
void ClassLoader::add_to_list(ClassPathEntry *new_entry) {
|
||||
if (new_entry != NULL) {
|
||||
if (_last_entry == NULL) {
|
||||
_first_entry = _last_entry = new_entry;
|
||||
if (_last_append_entry == NULL) {
|
||||
assert(_first_append_entry == NULL, "boot loader's append class path entry list not empty");
|
||||
_first_append_entry = _last_append_entry = new_entry;
|
||||
} else {
|
||||
_last_entry->set_next(new_entry);
|
||||
_last_entry = new_entry;
|
||||
_last_append_entry->set_next(new_entry);
|
||||
_last_append_entry = new_entry;
|
||||
}
|
||||
}
|
||||
_num_entries ++;
|
||||
}
|
||||
|
||||
void ClassLoader::prepend_to_list(ClassPathEntry *new_entry) {
|
||||
if (new_entry != NULL) {
|
||||
if (_last_entry == NULL) {
|
||||
_first_entry = _last_entry = new_entry;
|
||||
} else {
|
||||
new_entry->set_next(_first_entry);
|
||||
_first_entry = new_entry;
|
||||
}
|
||||
}
|
||||
_num_entries ++;
|
||||
_num_entries++;
|
||||
}
|
||||
|
||||
void ClassLoader::add_to_list(const char *apath) {
|
||||
update_class_path_entry_list((char*)apath, false, false, false, false);
|
||||
}
|
||||
|
||||
void ClassLoader::prepend_to_list(const char *apath) {
|
||||
update_class_path_entry_list((char*)apath, false, false, true, false);
|
||||
update_class_path_entry_list((char*)apath, false, false);
|
||||
}
|
||||
|
||||
// Returns true IFF the file/dir exists and the entry was successfully created.
|
||||
bool ClassLoader::update_class_path_entry_list(const char *path,
|
||||
bool check_for_duplicates,
|
||||
bool mark_append_entry,
|
||||
bool prepend_entry,
|
||||
bool is_boot_append,
|
||||
bool throw_exception) {
|
||||
struct stat st;
|
||||
|
@ -946,19 +981,10 @@ bool ClassLoader::update_class_path_entry_list(const char *path,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Ensure that the first boot loader append entry will always be set correctly.
|
||||
assert((!mark_append_entry ||
|
||||
(mark_append_entry && (!check_for_duplicates || !contains_entry(new_entry)))),
|
||||
"failed to mark boot loader's first append boundary");
|
||||
|
||||
// Do not reorder the bootclasspath which would break get_system_package().
|
||||
// Add new entry to linked list
|
||||
|
||||
if (!check_for_duplicates || !contains_entry(new_entry)) {
|
||||
ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry, prepend_entry);
|
||||
if (mark_append_entry) {
|
||||
set_first_append_entry(new_entry);
|
||||
}
|
||||
ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
|
@ -971,30 +997,47 @@ bool ClassLoader::update_class_path_entry_list(const char *path,
|
|||
}
|
||||
}
|
||||
|
||||
static void print_module_entry_table(const GrowableArray<ModuleClassPathList*>* const module_list) {
|
||||
ResourceMark rm;
|
||||
int num_of_entries = module_list->length();
|
||||
for (int i = 0; i < num_of_entries; i++) {
|
||||
ClassPathEntry* e;
|
||||
ModuleClassPathList* mpl = module_list->at(i);
|
||||
tty->print("%s=", mpl->module_name()->as_C_string());
|
||||
e = mpl->module_first_entry();
|
||||
while (e != NULL) {
|
||||
tty->print("%s", e->name());
|
||||
e = e->next();
|
||||
if (e != NULL) {
|
||||
tty->print("%s", os::path_separator());
|
||||
}
|
||||
}
|
||||
tty->print(" ;");
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoader::print_bootclasspath() {
|
||||
ClassPathEntry* e;
|
||||
tty->print("[bootclasspath= ");
|
||||
|
||||
// Print -Xpatch module/path specifications first
|
||||
if (_xpatch_entries != NULL) {
|
||||
ResourceMark rm;
|
||||
int num_of_entries = _xpatch_entries->length();
|
||||
for (int i = 0; i < num_of_entries; i++) {
|
||||
ModuleClassPathList* mpl = _xpatch_entries->at(i);
|
||||
tty->print("%s=", mpl->module_name()->as_C_string());
|
||||
e = mpl->module_first_entry();
|
||||
while (e != NULL) {
|
||||
tty->print("%s", e->name());
|
||||
e = e->next();
|
||||
if (e != NULL) {
|
||||
tty->print("%s", os::path_separator());
|
||||
}
|
||||
}
|
||||
tty->print(" ;");
|
||||
print_module_entry_table(_xpatch_entries);
|
||||
}
|
||||
|
||||
// [jimage | exploded modules build]
|
||||
if (has_jrt_entry()) {
|
||||
// Print the location of the java runtime image
|
||||
tty->print("%s ;", _jrt_entry->name());
|
||||
} else {
|
||||
// Print exploded module build path specifications
|
||||
if (_exploded_entries != NULL) {
|
||||
print_module_entry_table(_exploded_entries);
|
||||
}
|
||||
}
|
||||
|
||||
e = _first_entry;
|
||||
// appended entries
|
||||
e = _first_append_entry;
|
||||
while (e != NULL) {
|
||||
tty->print("%s ;", e->name());
|
||||
e = e->next();
|
||||
|
@ -1298,6 +1341,60 @@ const char* ClassLoader::file_name_for_class_name(const char* class_name,
|
|||
return file_name;
|
||||
}
|
||||
|
||||
// Search either the xpatch or exploded build entries for class
|
||||
ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleClassPathList*>* const module_list,
|
||||
const char* const class_name, const char* const file_name, TRAPS) {
|
||||
ClassFileStream* stream = NULL;
|
||||
|
||||
// Find the class' defining module in the boot loader's module entry table
|
||||
PackageEntry* pkg_entry = get_package_entry(class_name, ClassLoaderData::the_null_class_loader_data(), CHECK_NULL);
|
||||
ModuleEntry* mod_entry = (pkg_entry != NULL) ? pkg_entry->module() : NULL;
|
||||
|
||||
// If the module system has not defined java.base yet, then
|
||||
// classes loaded are assumed to be defined to java.base.
|
||||
// When java.base is eventually defined by the module system,
|
||||
// all packages of classes that have been previously loaded
|
||||
// are verified in ModuleEntryTable::verify_javabase_packages().
|
||||
if (!Universe::is_module_initialized() &&
|
||||
!ModuleEntryTable::javabase_defined() &&
|
||||
mod_entry == NULL) {
|
||||
mod_entry = ModuleEntryTable::javabase_module();
|
||||
}
|
||||
|
||||
// The module must be a named module
|
||||
if (mod_entry != NULL && mod_entry->is_named()) {
|
||||
int num_of_entries = module_list->length();
|
||||
const Symbol* class_module_name = mod_entry->name();
|
||||
|
||||
// Loop through all the modules in either the xpatch or exploded entries looking for module
|
||||
for (int i = 0; i < num_of_entries; i++) {
|
||||
ModuleClassPathList* module_cpl = module_list->at(i);
|
||||
Symbol* module_cpl_name = module_cpl->module_name();
|
||||
|
||||
if (module_cpl_name->fast_compare(class_module_name) == 0) {
|
||||
// Class' module has been located, attempt to load
|
||||
// the class from the module's ClassPathEntry list.
|
||||
ClassPathEntry* e = module_cpl->module_first_entry();
|
||||
while (e != NULL) {
|
||||
stream = e->open_stream(file_name, CHECK_NULL);
|
||||
// No context.check is required since CDS is not supported
|
||||
// for an exploded modules build or if -Xpatch is specified.
|
||||
if (NULL != stream) {
|
||||
return stream;
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
// If the module was located, break out even if the class was not
|
||||
// located successfully from that module's ClassPathEntry list.
|
||||
// There will not be another valid entry for that module.
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) {
|
||||
assert(name != NULL, "invariant");
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
|
@ -1321,18 +1418,19 @@ instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_onl
|
|||
s2 classpath_index = 0;
|
||||
ClassPathEntry* e = NULL;
|
||||
|
||||
// If DumpSharedSpaces is true, boot loader visibility boundaries are set
|
||||
// to be _first_entry to the end (all path entries). No -Xpatch entries are
|
||||
// included since CDS and AppCDS are not supported if -Xpatch is specified.
|
||||
// If DumpSharedSpaces is true boot loader visibility boundaries are set to:
|
||||
// - [jimage] + [_first_append_entry to _last_append_entry] (all path entries).
|
||||
// No -Xpatch entries or exploded module builds are included since CDS
|
||||
// is not supported if -Xpatch or exploded module builds are used.
|
||||
//
|
||||
// If search_append_only is true, boot loader visibility boundaries are
|
||||
// set to be _first_append_entry to the end. This includes:
|
||||
// [-Xbootclasspath/a]; [jvmti appended entries]
|
||||
//
|
||||
// If both DumpSharedSpaces and search_append_only are false, boot loader
|
||||
// visibility boundaries are set to be _first_entry to the entry before
|
||||
// the _first_append_entry. This would include:
|
||||
// [-Xpatch:<module>=<file>(<pathsep><file>)*]; [exploded build | jimage]
|
||||
// visibility boundaries are set to be the -Xpatch entries plus the base piece.
|
||||
// This would include:
|
||||
// [-Xpatch:<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build]
|
||||
//
|
||||
// DumpSharedSpaces and search_append_only are mutually exclusive and cannot
|
||||
// be true at the same time.
|
||||
|
@ -1341,85 +1439,37 @@ instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_onl
|
|||
// Load Attempt #1: -Xpatch
|
||||
// Determine the class' defining module. If it appears in the _xpatch_entries,
|
||||
// attempt to load the class from those locations specific to the module.
|
||||
// Specifications to -Xpatch can contain a partial number of classes
|
||||
// that are part of the overall module definition. So if a particular class is not
|
||||
// found within its module specification, the search should continue to Load Attempt #2.
|
||||
// Note: The -Xpatch entries are never searched if the boot loader's
|
||||
// visibility boundary is limited to only searching the append entries.
|
||||
if (_xpatch_entries != NULL && !search_append_only && !DumpSharedSpaces) {
|
||||
// Find the module in the boot loader's module entry table
|
||||
PackageEntry* pkg_entry = get_package_entry(class_name, ClassLoaderData::the_null_class_loader_data(), THREAD);
|
||||
ModuleEntry* mod_entry = (pkg_entry != NULL) ? pkg_entry->module() : NULL;
|
||||
|
||||
// If the module system has not defined java.base yet, then
|
||||
// classes loaded are assumed to be defined to java.base.
|
||||
// When java.base is eventually defined by the module system,
|
||||
// all packages of classes that have been previously loaded
|
||||
// are verified in ModuleEntryTable::verify_javabase_packages().
|
||||
if (!Universe::is_module_initialized() &&
|
||||
!ModuleEntryTable::javabase_defined() &&
|
||||
mod_entry == NULL) {
|
||||
mod_entry = ModuleEntryTable::javabase_module();
|
||||
}
|
||||
|
||||
// The module must be a named module
|
||||
if (mod_entry != NULL && mod_entry->is_named()) {
|
||||
int num_of_entries = _xpatch_entries->length();
|
||||
const Symbol* class_module_name = mod_entry->name();
|
||||
|
||||
// Loop through all the xpatch entries looking for module
|
||||
for (int i = 0; i < num_of_entries; i++) {
|
||||
ModuleClassPathList* module_cpl = _xpatch_entries->at(i);
|
||||
Symbol* module_cpl_name = module_cpl->module_name();
|
||||
|
||||
if (module_cpl_name->fast_compare(class_module_name) == 0) {
|
||||
// Class' module has been located, attempt to load
|
||||
// the class from the module's ClassPathEntry list.
|
||||
e = module_cpl->module_first_entry();
|
||||
while (e != NULL) {
|
||||
stream = e->open_stream(file_name, CHECK_NULL);
|
||||
// No context.check is required since both CDS
|
||||
// and AppCDS are turned off if -Xpatch is specified.
|
||||
if (NULL != stream) {
|
||||
break;
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
// If the module was located in the xpatch entries, break out
|
||||
// even if the class was not located successfully from that module's
|
||||
// ClassPathEntry list. There will not be another valid entry for
|
||||
// that module in the _xpatch_entries array.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
stream = search_module_entries(_xpatch_entries, class_name, file_name, CHECK_NULL);
|
||||
}
|
||||
|
||||
// Load Attempt #2: [exploded build | jimage]
|
||||
// Load Attempt #2: [jimage | exploded build]
|
||||
if (!search_append_only && (NULL == stream)) {
|
||||
e = _first_entry;
|
||||
while ((e != NULL) && (e != _first_append_entry)) {
|
||||
stream = e->open_stream(file_name, CHECK_NULL);
|
||||
if (has_jrt_entry()) {
|
||||
e = _jrt_entry;
|
||||
stream = _jrt_entry->open_stream(file_name, CHECK_NULL);
|
||||
if (!context.check(stream, classpath_index)) {
|
||||
return NULL;
|
||||
}
|
||||
if (NULL != stream) {
|
||||
break;
|
||||
}
|
||||
e = e->next();
|
||||
++classpath_index;
|
||||
} else {
|
||||
// Exploded build - attempt to locate class in its defining module's location.
|
||||
assert(_exploded_entries != NULL, "No exploded build entries present");
|
||||
stream = search_module_entries(_exploded_entries, class_name, file_name, CHECK_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Load Attempt #3: [-Xbootclasspath/a]; [jvmti appended entries]
|
||||
if ((search_append_only || DumpSharedSpaces) && (NULL == stream)) {
|
||||
// For the boot loader append path search, must calculate
|
||||
// the starting classpath_index prior to attempting to
|
||||
// load the classfile.
|
||||
if (search_append_only) {
|
||||
ClassPathEntry *tmp_e = _first_entry;
|
||||
while ((tmp_e != NULL) && (tmp_e != _first_append_entry)) {
|
||||
tmp_e = tmp_e->next();
|
||||
++classpath_index;
|
||||
}
|
||||
}
|
||||
// For the boot loader append path search, the starting classpath_index
|
||||
// for the appended piece is always 1 to account for either the
|
||||
// _jrt_entry or the _exploded_entries.
|
||||
assert(classpath_index == 0, "The classpath_index has been incremented incorrectly");
|
||||
classpath_index = 1;
|
||||
|
||||
e = _first_append_entry;
|
||||
while (e != NULL) {
|
||||
|
@ -1597,16 +1647,25 @@ void classLoader_init1() {
|
|||
}
|
||||
|
||||
// Complete the ClassPathEntry setup for the boot loader
|
||||
void classLoader_init2() {
|
||||
void ClassLoader::classLoader_init2(TRAPS) {
|
||||
// Create the moduleEntry for java.base
|
||||
create_javabase();
|
||||
|
||||
// Setup the list of module/path pairs for -Xpatch processing
|
||||
// This must be done after the SymbolTable is created in order
|
||||
// to use fast_compare on module names instead of a string compare.
|
||||
if (Arguments::get_xpatchprefix() != NULL) {
|
||||
ClassLoader::setup_xpatch_entries();
|
||||
setup_xpatch_entries();
|
||||
}
|
||||
|
||||
// Determine if this is an exploded build
|
||||
ClassLoader::set_has_jimage();
|
||||
// Setup the initial java.base/path pair for the exploded build entries.
|
||||
// As more modules are defined during module system initialization, more
|
||||
// entries will be added to the exploded build array.
|
||||
if (!has_jrt_entry()) {
|
||||
assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with exploded module builds");
|
||||
assert(!UseSharedSpaces, "UsedSharedSpaces not supported with exploded module builds");
|
||||
add_to_exploded_build_list(vmSymbols::java_base(), CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1654,26 +1713,6 @@ void ClassLoader::create_javabase() {
|
|||
}
|
||||
}
|
||||
|
||||
void ClassLoader::set_has_jimage() {
|
||||
// Determine if this is an exploded build. When looking for
|
||||
// the jimage file, only search the piece of the boot
|
||||
// loader's boot class path which contains [exploded build | jimage].
|
||||
// Do not search the boot loader's xpatch entries or append path.
|
||||
ClassPathEntry* e = _first_entry;
|
||||
ClassPathEntry* last_e = _first_append_entry;
|
||||
while ((e != NULL) && (e != last_e)) {
|
||||
JImageFile *jimage = e->jimage();
|
||||
if (jimage != NULL && e->is_jrt()) {
|
||||
_has_jimage = true;
|
||||
#if INCLUDE_CDS
|
||||
ClassLoader::initialize_module_loader_map(jimage);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
// CompileTheWorld
|
||||
|
@ -1762,14 +1801,19 @@ void ClassLoader::compile_the_world() {
|
|||
HandleMark hm(THREAD);
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
assert(has_jrt_entry(), "Compile The World not supported with exploded module build");
|
||||
|
||||
// Find bootstrap loader
|
||||
Handle system_class_loader (THREAD, SystemDictionary::java_system_loader());
|
||||
// Iterate over all bootstrap class path entries
|
||||
ClassPathEntry* e = _first_entry;
|
||||
jlong start = os::javaTimeMillis();
|
||||
|
||||
// Compile the world for the modular java runtime image
|
||||
_jrt_entry->compile_the_world(system_class_loader, CATCH);
|
||||
|
||||
// Iterate over all bootstrap class path appended entries
|
||||
ClassPathEntry* e = _first_append_entry;
|
||||
while (e != NULL) {
|
||||
// We stop at "modules" jimage, unless it is the first bootstrap path entry
|
||||
if (e->is_jrt() && e != _first_entry) break;
|
||||
assert(!e->is_jrt(), "A modular java runtime image is present on the list of appended entries");
|
||||
e->compile_the_world(system_class_loader, CATCH);
|
||||
e = e->next();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue