RFR: 8262377: Parallel class resolution loses constant pool error

Coleen Phillimore coleenp at openjdk.java.net
Thu Mar 4 15:47:40 UTC 2021


On Thu, 4 Mar 2021 15:21:07 GMT, Harold Seigel <hseigel at openjdk.org> wrote:

>> This PR was to originally add some tests for parallel class loading situations that aren't covered in our internal parallel class loading tests.  The tests found that class loading resolution errors weren't saving the error in the constant pool to implement JVMS 5.4.3.  The compiler was also doing re-resolution rather than using the error saved at that constant pool index.
>> 
>> One of the existing CDS tests verified that the Throwable.cause so this change also adds the cause and cause message to the resolution_errors() saved exceptions.
>> 
>> I didn't squash the commits so it would be easier to see the different changes, but they all go together.
>> 
>> The test description:
>> 
>> Two Threads T1, T2
>> 
>> Three definitions of class A, defined by user defined class loader
>> Class A extends B extends A (CCE)
>> Class A extends B
>> Class A extends C
>> 
>> Five modes:
>> Sequential
>> Concurrent loading with user defined class loader
>> Concurrent loading parallelCapable class loader
>> Wait when loading the superclass with parallelCapable class loader
>> Wait when loading the superclass with user defined class loader
>> 
>> In all cases, after A is parsed and calls resolve_super_or_fail to load B
>> and loading B waits.  Classes ClassInLoader, CP1 and CP2 provide
>> constant pool references to A.
>> 
>> In all cases, when B waits, A is replaced with bytes so A extends C.
>> 
>> Two tests x 3 modes (both threads do the same):
>> (CCE) First test A extends B, which throws CCE.
>>    -- All three modes: first constant pool reference throws CCE, second reference A extends C
>> (B) Second test A extends B which doesn't throw CCE.
>>    -- All three modes: both references A extends B.
>> 
>> The code in SystemDictionary::handle_parallel_super_load treats the parallel case for thread T2 as if T1
>> is not stalled and wins the race to load the class, by attempting to load the same superclass as T1 is
>> currently loading.  
>> 
>> Resolution for a constant pool reference should always fail with the same error even if there are concurrent threads doing that resolution.  Forcing the second thread to resolve the super class of the first, even if the thread has a different set of bytes for the class A, is a way to do that, but this actually exposed that the second successful thread should check the result of the constant pool resolution for the first. So this exposed this bug.
>> 
>> Tested with tier1, on all Oracle supported platforms and tier2-8 on linux-x64-debug and windows-x64-debug.
>
> src/hotspot/share/oops/constantPool.cpp line 565:
> 
>> 563:                                   (jbyte)JVM_CONSTANT_Class);
>> 564: 
>> 565:   if (old_tag != JVM_CONSTANT_UnresolvedClass) {
> 
> I think this check at line 565 can be removed.

Yes, it can.  I was checking if the race failed but the following if statement does that too.  Thanks!

-------------

PR: https://git.openjdk.java.net/jdk/pull/2718


More information about the hotspot-dev mailing list