(S) 8237750: Load libzip.so only if necessary
Dean Long
dean.long at oracle.com
Mon May 4 20:49:35 UTC 2020
Hi Ioi. I think you're right. Good catch.
dl
On 5/3/20 10:01 PM, Ioi Lam wrote:
> Hi Dean,
>
> The code uses double-checked locking so we can be thread-safe when
> loading the zip library, while avoiding using the MutexLock every time:
>
> https://en.wikipedia.org/wiki/Double-checked_locking
>
> To work correctly on modern memory architectures, we need the memory
> barriers:
>
> 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 }
>
> (Atomic::load_acquire is much cheaper than MutexLocker).
>
> If we read Crc32 without memory barriers, as in the original code, in
> two concurrent threads, I think there may be a chance for one of the
> threads to read an invalid value of Crc32.
>
> int ClassLoader::crc32(int crc, const char* buf, int len) {
> return (*Crc32)(crc, (const jbyte*)buf, len);
> }
>
> 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
>>>>>
>>>>
>>>
>>
>
More information about the serviceability-dev
mailing list