Hi Yumin,
Looks good.
Just small nits. No need for new webrev.
[1] I think this should be named _libzip_loaded to be consistent with
other fields
static int libzip_loaded; // used to sync loading zip.
[2] This introduces dependency on atomic.hpp to classLoader.hpp
static void load_zip_library_if_needed() {
if (Atomic::load_acquire(&libzip_loaded) == 0) {
release_load_zip_library();
}
}
Since this function is used only privately in the cpp file, I think it's
better to change the hpp to this (to reduce unnecessary header file
dependencies)
inline static void load_zip_library_if_needed();
and then move the implementation to the classLoader.cpp file. You also
need to add include "runtime/atomic.hpp" to classLoader.cpp.
Thanks
- Ioi
On 5/4/20 4:40 PM, Yumin Qi wrote:
Hi, Ioi
Thanks. Updated webrev at:
http://cr.openjdk.java.net/~minqi/8237750/webrev-02/
libzip_loaded now is a class member of ClassLoader, no longer a file
private integer since it is used in both .hpp and .cpp files.
Thanks
Yumin
On 5/4/20 8:31 AM, Ioi Lam wrote:
Hi Yumin,
977 void ClassLoader::load_zip_library() {
978 if (Atomic::load_acquire(&libzip_loaded) == 0) {
979 MutexLocker locker(Zip_lock,
Monitor::_no_safepoint_check_flag);
980 if (libzip_loaded == 0) {
981 load_zip_library0();
982 Atomic::release_store(&libzip_loaded, 1);
983 }
984 }
985 }
1026 int ClassLoader::crc32(int crc, const char* buf, int len) {
1027 if (libzip_loaded == 0) {
1028 load_zip_library();
1029 }
1030 return (*Crc32)(crc, (const jbyte*)buf, len);
1031 }
ClassLoader::crc32 access libzip_loaded without a memory barrier, so
it may read libzip_loaded out-of-order from Crc32. This means, thread
1 may be writing the memory in this order:
Crc32 = <addr>;
libzip_loaded = 1;
but the order observed in thread 2 may be
libzip_loaded = 1;
>> ClassLoader::crc32 called here in thread 2
Crc32 = <addr>;
as a result, thread 2 may read libzip_loaded = 1, but still reads a
NULL from Crc32.
To ensure the memory barrier is used, I think we should do this:
// private
inline void ClassLoader::load_zip_library_if_needed() {
if (Atomic::load_acquire(&libzip_loaded) == 0) {
release_load_zip_library();
}
}
// private
void ClassLoader::release_load_zip_library() {
MutexLocker locker(Zip_lock, Monitor::_no_safepoint_check_flag);
if (libzip_loaded == 0) {
load_zip_library0();
Atomic::release_store(&libzip_loaded, 1);
}
}
int ClassLoader::crc32(int crc, const char* buf, int len) {
load_zip_library_if_needed();
return (*Crc32)(crc, (const jbyte*)buf, len);
}
HotSpot code uses the "release_" prefix to indicate that the function
must be used as a part of an acquire/release memory barrier. (E.g.,
InstanceKlass::release_set_array_klasses()).
Some backgrounds:
https://preshing.com/20130922/acquire-and-release-fences/
Thanks
- Ioi
On 5/1/20 8:00 PM, Yumin Qi wrote:
Dean,
I have updated to use MutexLocker instead at same link:
http://cr.openjdk.java.net/~minqi/8237750/webrev-01/
Tested locally, passed jtreg/runtime.
Thanks
Yumin
On 5/1/20 4:24 PM, Dean Long wrote:
OK, I didn't realize compute_fingerprint is using ZIP_CRC32.
dl
On 5/1/20 2:42 PM, Yumin Qi wrote:
Hi, Dean
Thanks for the review. I will try MutextLocker, for AOT, I think
currently the tests are not using CDS then it will load classes
from stream, that will use libzip's Crc32.
I will check for AOT to see if it really loads libzip with the
patch. For test compiler/aot/DeoptimizationTest.java:
#0 ClassLoader::load_zip_library () at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/classLoader.cpp:978
#1 0x00007ffff57d4693 in ClassLoader::crc32 (crc=0,
buf=0x7ffff0244ee0 "\312\376\272\276", len=1888) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/classLoader.cpp:1028
#2 0x00007ffff57cef5d in ClassFileStream::compute_fingerprint
(this=0x7ffff0245640) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/classFileStream.cpp:80
#3 0x00007ffff57c40ed in ClassFileParser::create_instance_klass
(this=0x7ffff7fc6fc0, changed_by_loadhook=false, cl_inst_info=...,
__the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/classFileParser.cpp:5630
#4 0x00007ffff5dea647 in KlassFactory::create_from_stream
(stream=0x7ffff0245640, name=0x7ffff40550f0,
loader_data=0x7ffff022dbc0, cl_info=...,
__the_thread__=0x7ffff0033000)
at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/klassFactory.cpp:207
#5 0x00007ffff57d53e4 in ClassLoader::load_class
(name=0x7ffff40550f0, search_append_only=false,
__the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/classLoader.cpp:1285
#6 0x00007ffff6234fcf in SystemDictionary::load_instance_class
(class_name=0x7ffff40550f0, class_loader=...,
__the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:1550
#7 0x00007ffff6232d0a in
SystemDictionary::resolve_instance_class_or_null
(name=0x7ffff40550f0, class_loader=..., protection_domain=...,
__the_thread__=0x7ffff0033000)
at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:882
#8 0x00007ffff623137e in
SystemDictionary::resolve_instance_class_or_null_helper
(class_name=0x7ffff40550f0, class_loader=...,
protection_domain=..., __the_thread__=0x7ffff0033000)
at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:302
#9 0x00007ffff623124c in SystemDictionary::resolve_or_null
(class_name=0x7ffff40550f0, class_loader=...,
protection_domain=..., __the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:285
#10 0x00007ffff6230f57 in SystemDictionary::resolve_or_fail
(class_name=0x7ffff40550f0, class_loader=...,
protection_domain=..., throw_error=true,
__the_thread__=0x7ffff0033000)
at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:233
#11 0x00007ffff62311eb in SystemDictionary::resolve_or_fail
(class_name=0x7ffff40550f0, throw_error=true,
__the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:275
#12 0x00007ffff6236722 in SystemDictionary::resolve_wk_klass
(id=SystemDictionary::Object_klass_knum,
__the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:2029
#13 0x00007ffff623681e in
SystemDictionary::resolve_wk_klasses_until
(limit_id=SystemDictionary::Cloneable_klass_knum,
start_id=@0x7ffff7fc79d4: SystemDictionary::Object_klass_knum,
__the_thread__=0x7ffff0033000)
at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:2039
#14 0x00007ffff623ac01 in
SystemDictionary::resolve_wk_klasses_through
(end_id=SystemDictionary::Class_klass_knum,
start_id=@0x7ffff7fc79d4: SystemDictionary::Object_klass_knum,
__the_thread__=0x7ffff0033000)
at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.hpp:418
#15 0x00007ffff62369b0 in
SystemDictionary::resolve_well_known_classes
(__the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:2082
#16 0x00007ffff6236517 in SystemDictionary::initialize
(__the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/classfile/systemDictionary.cpp:1985
#17 0x00007ffff62afe15 in Universe::genesis
(__the_thread__=0x7ffff0033000) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/memory/universe.cpp:326
#18 0x00007ffff62b1e51 in universe2_init () at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/memory/universe.cpp:847
#19 0x00007ffff5af21ed in init_globals () at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/runtime/init.cpp:128
#20 0x00007ffff627feff in Threads::create_vm (args=0x7ffff7fc7e50,
canTryAgain=0x7ffff7fc7d5b) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/runtime/thread.cpp:3879
#21 0x00007ffff5bf537d in JNI_CreateJavaVM_inner
(vm=0x7ffff7fc7ea8, penv=0x7ffff7fc7eb0, args=0x7ffff7fc7e50) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/prims/jni.cpp:3789
#22 0x00007ffff5bf5677 in JNI_CreateJavaVM (vm=0x7ffff7fc7ea8,
penv=0x7ffff7fc7eb0, args=0x7ffff7fc7e50) at
/home/minqi/ws/jdk15/jdk/src/hotspot/share/prims/jni.cpp:3872
#23 0x00007ffff7bca4c9 in InitializeJVM (pvm=0x7ffff7fc7ea8,
penv=0x7ffff7fc7eb0, ifn=0x7ffff7fc7f00) at
/home/minqi/ws/jdk15/jdk/src/java.base/share/native/libjli/java.c:1538
#24 0x00007ffff7bc70b5 in JavaMain (_args=0x7fffffffab10) at
/home/minqi/ws/jdk15/jdk/src/java.base/share/native/libjli/java.c:417
#25 0x00007ffff7bceb5f in ThreadJavaMain (args=0x7fffffffab10) at
/home/minqi/ws/jdk15/jdk/src/java.base/unix/native/libjli/java_md_solinux.c:734
#26 0x00007ffff71c56ba in start_thread (arg=0x7ffff7fc8700) at
pthread_create.c:333
#27 0x00007ffff790041d in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:109
This is not with CDS.
Thanks
Yumin
On 5/1/20 2:11 PM, Dean Long wrote:
It looks like Zip_lock could be a MutexLocker instead of a
MonitorLocker.
dl
On 5/1/20 10:24 AM, Yumin Qi wrote:
Hi, please review:
bug 8237750: https://bugs.openjdk.java.net/browse/JDK-8237750
webrev: http://cr.openjdk.java.net/~minqi/8237750/webrev-01/
Summary:
zip library is loaded unconditionally at start up but it is
only needed when
1) bootclasspath contains zip or
2) UseAOT enabled or
3) VerifySharedArchive turned on or
4) CDS archives custom loaded classes
If none of above in java application, it is not necessary to
have zip library loaded.
Solution by loading zip library on demand when needed.
Performance for java -Xint version:
Results of " perf stat -r 50 bin/java -Xshare:on
-XX:SharedArchiveFile=jdk2.jsa -Xint -version "
1: 59611556 59450206 (-161350) ----- 39.799
40.274 ( 0.475) ++
2: 59602708 59425234 (-177474) ----- 40.591
41.183 ( 0.592) ++
3: 59579718 59441272 (-138446) ---- 40.777 40.471
( -0.306) -
4: 59584882 59410155 (-174727) ----- 40.824
40.233 ( -0.591) --
5: 59590998 59447252 (-143746) ---- 40.400 40.493
( 0.093)
6: 59589523 59441934 (-147589) ---- 40.475 40.064
( -0.411) --
7: 59581820 59413612 (-168208) ----- 39.763
40.077 ( 0.314) +
8: 59593678 59418738 (-174940) ----- 40.912
39.724 ( -1.188) -----
9: 59573058 59412554 (-160504) ----- 40.126
40.033 ( -0.093)
10: 59591469 59419291 (-172178) ----- 40.731
40.689 ( -0.042)
============================================================
59589940 59428022 (-161917) ----- 40.438
40.322 ( -0.116)
instr delta = -161917 -0.2717%
time delta = -0.116 ms -0.2859%
Tests: hs-tier1-4.
Due to zip library not loaded at default, I removed 'zip' from
pmap list in test case:
*test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java
**
* Thanks
Yumin