RFR(S) 8231125 Improve testing of parallel loading of shared classes by the boot class loader
Calvin Cheung
calvin.cheung at oracle.com
Wed Sep 18 18:42:07 UTC 2019
Hi Ioi,
Just one comment on the v02 webrev:
http://cr.openjdk.java.net/~iklam/jdk14/8231125-shared-boot-class-parallel-test.v02/test/hotspot/jtreg/runtime/cds/appcds/test-classes/ParallelLoad.java.sdiff.html
191 log("thread[%d] t = %s, c = %s, l = %s", i, this, clazz,
clazz.getClassLoader());
I thought i is the index into the ParallelLoad.MAX_CLASSES.
Should the above i be thread_id?
thanks,
Calvin
On 9/17/19 11:23 PM, Ioi Lam wrote:
>
>
> On 9/17/19 6:27 PM, David Holmes wrote:
>> Hi Ioi,
>>
>> On 18/09/2019 7:24 am, coleen.phillimore at oracle.com wrote:
>>> http://cr.openjdk.java.net/~iklam/jdk14/8231125-shared-boot-class-parallel-test.v01/src/hotspot/share/classfile/systemDictionary.cpp.udiff.html
>>>
>>>
>>> Can you add a line something like.
>>>
>>> + if (class_loader() == NULL) {
>>> + // See case 3 in SystemDictionary::resolve_instance_class_or_null
>>> + // multiple threads wait on the SystemDictionary_lock if the
>>> boot loader class is in the placeholder table, so only
>>> + // one thread loads the class.
>>> + assert(ik->class_loader_data() == NULL, "boot loader classes are
>>> not loaded in parallel");
>>> + }
>>> +
>>
>> Even with Coleen's suggested comment I still don't see what this code
>> has to do with loading in parallel? AFAICS all you are asserting is
>> that if the class is to be loaded by the boot-loader then the class
>> should have been dumped by the boot-loader - no?
>>
> Hi David,
>
> When we were analyzing a recent random crash that might be caused by
> race condition during class loading, we looked at this call to
> restore_unshareable_info() in SystemDictionary::load_shared_class()
>
> ClassLoaderData* loader_data =
> ClassLoaderData::class_loader_data(class_loader());
> {
> HandleMark hm(THREAD);
> Handle lockObject = compute_loader_lock_object(class_loader,
> THREAD);
> check_loader_lock_contention(lockObject, THREAD);
> ObjectLocker ol(lockObject, THREAD, true);
> // prohibited package check assumes all classes loaded from
> archive call
> // restore_unshareable_info which calls ik->set_package()
> ik->restore_unshareable_info(loader_data, protection_domain,
> CHECK_NULL);
> }
>
> Because all the crash seemed to be with shared classes loaded by the
> boot loader, we suspect that two threads competing to load the same
> class may arrive here simultaneously, and we will end up calling
> ik->restore_unshareable_info() twice, with harmful side effects.
>
> Upon further investigation, we found that this is not the case. But it
> will be good to have an assert to check for this -- that we won't call
> ik->restore_unshareable_info() more than once.
>
> I realized that I put the assert at the wrong place, and asserted on
> the wrong field (non-boot classes will enter load_shared_class() with
> ik->class_loader_data() != NULL). So I changed the assert to be on the
> java_mirror. That way, the assert works for shared classes for all
> loaders.
>
> assert(!ik->is_java_mirror_restored(), "don't load the same
> shared class twice");
> ik->restore_unshareable_info(loader_data, protection_domain,
> CHECK_NULL);
> assert(ik->is_java_mirror_restored() ||
> !SystemDictionary::Class_klass_loaded(), "must be");
>
> Here's an updated webrev, which also contains fixes you suggested below.
>
> Thanks
> - Ioi
>
>> The test seems okay - the proof is in the running :)
>>
>> One style nit:
>>
>> ! for (int i=0; i<APP_LOOPS; i++) {
>>
>> spaces around binary operators please. This seems to impact all for
>> loops.
>>
>> Also:
>>
>> 175 { // Avoid logging in this block so the threads can
>> proceeds without
>>
>> s/proceeds/proceed/
>>
>> Thanks,
>> David
>> -----
>>
>>> I wonder if the ObjectLocker is really needed for non-bootclass
>>> loaders below this code, since it appears to not be needed for boot
>>> class loaders.
>>>
>>> The test changes look good. I think you're supposed to have @bug
>>> tags in them.
>>>
>>> Thanks for going through this code looking for races!
>>> Coleen
>>>
>>>
>>> On 9/17/19 1:10 PM, Ioi Lam wrote:
>>>> https://bugs.openjdk.java.net/browse/JDK-8231125
>>>> http://cr.openjdk.java.net/~iklam/jdk14/8231125-shared-boot-class-parallel-test.v01/
>>>>
>>>>
>>>>
>>>> [1] Modified ParallelLoadTest.java to also test the loading of
>>>> shared classes
>>>> into the boot loader.
>>>> [2] Modified ParallelLoad.java to minimize the initial time lag
>>>> when the 4 parallel
>>>> threads compete to load the same class.
>>>> [3] Added an assert in the JVM to verify that for a shared classes
>>>> loaded
>>>> the boot class loader, SystemDictionary::load_shared_class is
>>>> not called
>>>> multiple times.
>>>>
>>>
>
More information about the hotspot-runtime-dev
mailing list