Skip to content

Commit dc323a9

Browse files
author
Harold Seigel
committedApr 27, 2021
8263421: Module image file is opened twice during VM startup
Reviewed-by: iklam, dholmes
1 parent fbfd4ea commit dc323a9

File tree

2 files changed

+43
-52
lines changed

2 files changed

+43
-52
lines changed
 

‎src/hotspot/share/classfile/classLoader.cpp

+40-48
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,11 @@ int ClassLoader::_libzip_loaded = 0;
105105

106106
static JImageOpen_t JImageOpen = NULL;
107107
static JImageClose_t JImageClose = NULL;
108-
static JImagePackageToModule_t JImagePackageToModule = NULL;
109108
static JImageFindResource_t JImageFindResource = NULL;
110109
static JImageGetResource_t JImageGetResource = NULL;
111-
static JImageResourceIterator_t JImageResourceIterator = NULL;
110+
111+
// JimageFile pointer, or null if exploded JDK build.
112+
static JImageFile* JImage_file = NULL;
112113

113114
// Globals
114115

@@ -343,16 +344,26 @@ void ClassPathZipEntry::contents_do(void f(const char* name, void* context), voi
343344

344345
DEBUG_ONLY(ClassPathImageEntry* ClassPathImageEntry::_singleton = NULL;)
345346

347+
JImageFile* ClassPathImageEntry::jimage() const {
348+
return JImage_file;
349+
}
350+
351+
JImageFile* ClassPathImageEntry::jimage_non_null() const {
352+
assert(ClassLoader::has_jrt_entry(), "must be");
353+
assert(jimage() != NULL, "should have been opened by ClassLoader::lookup_vm_options "
354+
"and remained throughout normal JVM lifetime");
355+
return jimage();
356+
}
357+
346358
void ClassPathImageEntry::close_jimage() {
347-
if (_jimage != NULL) {
348-
(*JImageClose)(_jimage);
349-
_jimage = NULL;
359+
if (jimage() != NULL) {
360+
(*JImageClose)(jimage());
361+
JImage_file = NULL;
350362
}
351363
}
352364

353365
ClassPathImageEntry::ClassPathImageEntry(JImageFile* jimage, const char* name) :
354-
ClassPathEntry(),
355-
_jimage(jimage) {
366+
ClassPathEntry() {
356367
guarantee(jimage != NULL, "jimage file is null");
357368
guarantee(name != NULL, "jimage file name is null");
358369
assert(_singleton == NULL, "VM supports only one jimage");
@@ -361,18 +372,6 @@ ClassPathImageEntry::ClassPathImageEntry(JImageFile* jimage, const char* name) :
361372
_name = copy_path(name);
362373
}
363374

364-
ClassPathImageEntry::~ClassPathImageEntry() {
365-
assert(_singleton == this, "must be");
366-
DEBUG_ONLY(_singleton = NULL);
367-
368-
FREE_C_HEAP_ARRAY(const char, _name);
369-
370-
if (_jimage != NULL) {
371-
(*JImageClose)(_jimage);
372-
_jimage = NULL;
373-
}
374-
}
375-
376375
ClassFileStream* ClassPathImageEntry::open_stream(Thread* current, const char* name) {
377376
return open_stream_for_loader(current, name, ClassLoaderData::the_null_class_loader_data());
378377
}
@@ -386,15 +385,15 @@ ClassFileStream* ClassPathImageEntry::open_stream(Thread* current, const char* n
386385
//
387386
ClassFileStream* ClassPathImageEntry::open_stream_for_loader(Thread* current, const char* name, ClassLoaderData* loader_data) {
388387
jlong size;
389-
JImageLocationRef location = (*JImageFindResource)(_jimage, "", get_jimage_version_string(), name, &size);
388+
JImageLocationRef location = (*JImageFindResource)(jimage_non_null(), "", get_jimage_version_string(), name, &size);
390389

391390
if (location == 0) {
392391
TempNewSymbol class_name = SymbolTable::new_symbol(name);
393392
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
394393

395394
if (pkg_name != NULL) {
396395
if (!Universe::is_module_initialized()) {
397-
location = (*JImageFindResource)(_jimage, JAVA_BASE_NAME, get_jimage_version_string(), name, &size);
396+
location = (*JImageFindResource)(jimage_non_null(), JAVA_BASE_NAME, get_jimage_version_string(), name, &size);
398397
} else {
399398
PackageEntry* package_entry = ClassLoader::get_package_entry(pkg_name, loader_data);
400399
if (package_entry != NULL) {
@@ -405,7 +404,7 @@ ClassFileStream* ClassPathImageEntry::open_stream_for_loader(Thread* current, co
405404
assert(module->is_named(), "Boot classLoader package is in unnamed module");
406405
const char* module_name = module->name()->as_C_string();
407406
if (module_name != NULL) {
408-
location = (*JImageFindResource)(_jimage, module_name, get_jimage_version_string(), name, &size);
407+
location = (*JImageFindResource)(jimage_non_null(), module_name, get_jimage_version_string(), name, &size);
409408
}
410409
}
411410
}
@@ -416,7 +415,7 @@ ClassFileStream* ClassPathImageEntry::open_stream_for_loader(Thread* current, co
416415
ClassLoader::perf_sys_classfile_bytes_read()->inc(size);
417416
}
418417
char* data = NEW_RESOURCE_ARRAY(char, size);
419-
(*JImageGetResource)(_jimage, location, data, size);
418+
(*JImageGetResource)(jimage_non_null(), location, data, size);
420419
// Resource allocated
421420
assert(this == (ClassPathImageEntry*)ClassLoader::get_jrt_entry(), "must be");
422421
return new ClassFileStream((u1*)data,
@@ -649,14 +648,17 @@ void ClassLoader::setup_bootstrap_search_path_impl(Thread* current, const char *
649648
struct stat st;
650649
if (os::stat(path, &st) == 0) {
651650
// Directory found
652-
ClassPathEntry* new_entry = create_class_path_entry(current, path, &st, false, false);
651+
if (JImage_file != NULL) {
652+
assert(Arguments::has_jimage(), "sanity check");
653+
const char* canonical_path = get_canonical_path(path, current);
654+
assert(canonical_path != NULL, "canonical_path issue");
653655

654-
// Check for a jimage
655-
if (Arguments::has_jimage()) {
656-
assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice");
657-
_jrt_entry = new_entry;
658-
assert(new_entry != NULL && new_entry->is_modules_image(), "No java runtime image present");
656+
_jrt_entry = new ClassPathImageEntry(JImage_file, canonical_path);
657+
assert(_jrt_entry != NULL && _jrt_entry->is_modules_image(), "No java runtime image present");
659658
assert(_jrt_entry->jimage() != NULL, "No java runtime image");
659+
} else {
660+
// It's an exploded build.
661+
ClassPathEntry* new_entry = create_class_path_entry(current, path, &st, false, false);
660662
}
661663
} else {
662664
// If path does not exist, exit
@@ -724,24 +726,18 @@ ClassPathEntry* ClassLoader::create_class_path_entry(Thread* current,
724726
ClassPathEntry* new_entry = NULL;
725727
if ((st->st_mode & S_IFMT) == S_IFREG) {
726728
ResourceMark rm(thread);
727-
// Regular file, should be a zip or jimage file
729+
// Regular file, should be a zip file
728730
// Canonicalized filename
729731
const char* canonical_path = get_canonical_path(path, thread);
730732
if (canonical_path == NULL) {
731733
return NULL;
732734
}
733-
jint error;
734-
JImageFile* jimage =(*JImageOpen)(canonical_path, &error);
735-
if (jimage != NULL) {
736-
new_entry = new ClassPathImageEntry(jimage, canonical_path);
735+
char* error_msg = NULL;
736+
jzfile* zip = open_zip_file(canonical_path, &error_msg, thread);
737+
if (zip != NULL && error_msg == NULL) {
738+
new_entry = new ClassPathZipEntry(zip, path, is_boot_append, from_class_path_attr);
737739
} else {
738-
char* error_msg = NULL;
739-
jzfile* zip = open_zip_file(canonical_path, &error_msg, thread);
740-
if (zip != NULL && error_msg == NULL) {
741-
new_entry = new ClassPathZipEntry(zip, path, is_boot_append, from_class_path_attr);
742-
} else {
743-
return NULL;
744-
}
740+
return NULL;
745741
}
746742
log_info(class, path)("opened: %s", path);
747743
log_info(class, load)("opened: %s", path);
@@ -968,10 +964,8 @@ void ClassLoader::load_jimage_library() {
968964

969965
JImageOpen = CAST_TO_FN_PTR(JImageOpen_t, dll_lookup(handle, "JIMAGE_Open", path));
970966
JImageClose = CAST_TO_FN_PTR(JImageClose_t, dll_lookup(handle, "JIMAGE_Close", path));
971-
JImagePackageToModule = CAST_TO_FN_PTR(JImagePackageToModule_t, dll_lookup(handle, "JIMAGE_PackageToModule", path));
972967
JImageFindResource = CAST_TO_FN_PTR(JImageFindResource_t, dll_lookup(handle, "JIMAGE_FindResource", path));
973968
JImageGetResource = CAST_TO_FN_PTR(JImageGetResource_t, dll_lookup(handle, "JIMAGE_GetResource", path));
974-
JImageResourceIterator = CAST_TO_FN_PTR(JImageResourceIterator_t, dll_lookup(handle, "JIMAGE_ResourceIterator", path));
975969
}
976970

977971
int ClassLoader::crc32(int crc, const char* buf, int len) {
@@ -1429,15 +1423,13 @@ char* ClassLoader::lookup_vm_options() {
14291423
load_jimage_library();
14301424

14311425
jio_snprintf(modules_path, JVM_MAXPATHLEN, "%s%slib%smodules", Arguments::get_java_home(), fileSep, fileSep);
1432-
JImageFile* jimage =(*JImageOpen)(modules_path, &error);
1433-
if (jimage == NULL) {
1426+
JImage_file =(*JImageOpen)(modules_path, &error);
1427+
if (JImage_file == NULL) {
14341428
return NULL;
14351429
}
14361430

14371431
const char *jimage_version = get_jimage_version_string();
1438-
char *options = lookup_vm_resource(jimage, jimage_version, "jdk/internal/vm/options");
1439-
1440-
(*JImageClose)(jimage);
1432+
char *options = lookup_vm_resource(JImage_file, jimage_version, "jdk/internal/vm/options");
14411433
return options;
14421434
}
14431435

‎src/hotspot/share/classfile/classLoader.hpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,16 @@ class ClassPathZipEntry: public ClassPathEntry {
117117
// For java image files
118118
class ClassPathImageEntry: public ClassPathEntry {
119119
private:
120-
JImageFile* _jimage;
121120
const char* _name;
122121
DEBUG_ONLY(static ClassPathImageEntry* _singleton;)
123122
public:
124123
bool is_modules_image() const;
125-
bool is_open() const { return _jimage != NULL; }
126124
const char* name() const { return _name == NULL ? "" : _name; }
127-
JImageFile* jimage() const { return _jimage; }
125+
JImageFile* jimage() const;
126+
JImageFile* jimage_non_null() const;
128127
void close_jimage();
129128
ClassPathImageEntry(JImageFile* jimage, const char* name);
130-
virtual ~ClassPathImageEntry();
129+
virtual ~ClassPathImageEntry() { ShouldNotReachHere(); }
131130
ClassFileStream* open_stream(Thread* current, const char* name);
132131
ClassFileStream* open_stream_for_loader(Thread* current, const char* name, ClassLoaderData* loader_data);
133132
};

0 commit comments

Comments
 (0)
Please sign in to comment.