8237750: Load libzip.so only if necessary

Libzip.so is unconditionally loaded even without usage. Fix by on demand loading.

Reviewed-by: dlong, iklam, ccheung
This commit is contained in:
Yumin Qi 2020-05-05 15:40:18 -07:00
parent bc8065facd
commit 0c0d485c37
6 changed files with 28 additions and 4 deletions
src/hotspot/share
test/hotspot/jtreg/serviceability/sa

@ -95,6 +95,7 @@ static FindEntry_t FindEntry = NULL;
static ReadEntry_t ReadEntry = NULL;
static GetNextEntry_t GetNextEntry = NULL;
static Crc32_t Crc32 = NULL;
int ClassLoader::_libzip_loaded = 0;
// Entry points for jimage.dll for loading jimage file entries
@ -747,6 +748,7 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str
// enable call to C land
ThreadToNativeFromVM ttn(thread);
HandleMark hm(thread);
load_zip_library_if_needed();
zip = (*ZipOpen)(canonical_path, &error_msg);
}
if (zip != NULL && error_msg == NULL) {
@ -796,6 +798,7 @@ ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path, bo
JavaThread* thread = JavaThread::current();
ThreadToNativeFromVM ttn(thread);
HandleMark hm(thread);
load_zip_library_if_needed();
zip = (*ZipOpen)(canonical_path, &error_msg);
}
if (zip != NULL && error_msg == NULL) {
@ -967,6 +970,14 @@ void ClassLoader::load_java_library() {
CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, dll_lookup(javalib_handle, "JDK_Canonicalize", NULL));
}
void ClassLoader::release_load_zip_library() {
MutexLocker locker(Zip_lock, Monitor::_no_safepoint_check_flag);
if (_libzip_loaded == 0) {
load_zip_library();
Atomic::release_store(&_libzip_loaded, 1);
}
}
void ClassLoader::load_zip_library() {
assert(ZipOpen == NULL, "should not load zip library twice");
char path[JVM_MAXPATHLEN];
@ -1008,6 +1019,7 @@ void ClassLoader::load_jimage_library() {
}
int ClassLoader::crc32(int crc, const char* buf, int len) {
load_zip_library_if_needed();
return (*Crc32)(crc, (const jbyte*)buf, len);
}
@ -1466,8 +1478,6 @@ void ClassLoader::initialize() {
// lookup java library entry points
load_java_library();
// lookup zip library entry points
load_zip_library();
// jimage library entry points are loaded below, in lookup_vm_options
setup_bootstrap_search_path();
}

@ -252,6 +252,11 @@ class ClassLoader: AllStatic {
static void load_zip_library();
static void load_jimage_library();
private:
static int _libzip_loaded; // used to sync loading zip.
static void release_load_zip_library();
static inline void load_zip_library_if_needed();
public:
static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
bool throw_exception,

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -56,6 +56,12 @@ inline ClassPathEntry* ClassLoader::classpath_entry(int n) {
}
}
inline void ClassLoader::load_zip_library_if_needed() {
if (Atomic::load_acquire(&_libzip_loaded) == 0) {
release_load_zip_library();
}
}
#if INCLUDE_CDS
// Helper function used by CDS code to get the number of boot classpath

@ -120,6 +120,7 @@ Monitor* Notification_lock = NULL;
Monitor* PeriodicTask_lock = NULL;
Monitor* RedefineClasses_lock = NULL;
Mutex* Verify_lock = NULL;
Monitor* Zip_lock = NULL;
#if INCLUDE_JFR
Mutex* JfrStacktrace_lock = NULL;
@ -309,6 +310,7 @@ void mutex_init() {
def(PeriodicTask_lock , PaddedMonitor, nonleaf+5, true, _safepoint_check_always);
def(RedefineClasses_lock , PaddedMonitor, nonleaf+5, true, _safepoint_check_always);
def(Verify_lock , PaddedMutex, nonleaf+5, true, _safepoint_check_always);
def(Zip_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
if (WhiteBoxAPI) {
def(Compilation_lock , PaddedMonitor, leaf, false, _safepoint_check_never);

@ -115,6 +115,7 @@ extern Monitor* Notification_lock; // a lock used for notification
extern Monitor* PeriodicTask_lock; // protects the periodic task structure
extern Monitor* RedefineClasses_lock; // locks classes from parallel redefinition
extern Mutex* Verify_lock; // synchronize initialization of verify library
extern Monitor* Zip_lock; // synchronize initialization of zip library
extern Monitor* ThreadsSMRDelete_lock; // Used by ThreadsSMRSupport to take pressure off the Threads_lock
extern Mutex* ThreadIdTableCreate_lock; // Used by ThreadIdTable to lazily create the thread id table
extern Mutex* SharedDecoder_lock; // serializes access to the decoder during normal (not error reporting) use

@ -57,7 +57,7 @@ public class ClhsdbPmap {
List.of("Not available on Mac OS X"));
} else {
expStrMap.put("pmap",
List.of("jvm", "java", "net", "nio", "jimage", "zip"));
List.of("jvm", "java", "net", "nio", "jimage"));
}
test.run(theApp.getPid(), cmds, expStrMap, null);