RFR: missing UseShenandoahGC checks in 9

Roland Westrelin rwestrel at redhat.com
Wed Oct 11 12:39:48 UTC 2017


> FYI, I see failures with gc/shenandoah/compiler/TestReferenceCAS.java
> when ran with -Xcomp (reproducible with and without this patch):
>
> Error occurred during initialization of boot layer
> java.lang.InternalError: BMH.reinvoke=Lambda(a0:L/SpeciesData<LLL>,a1:L,a2:L,a3:L,a4:L,a5:L,a6:L)=>{
>     t7:L=BoundMethodHandle$Species_L3.argL2(a0:L);
>     t8:L=MethodHandle.invokeBasic(t7:L,a5:L);
>     t9:L=BoundMethodHandle$Species_L3.argL1(a0:L);
>     t10:L=MethodHandle.invokeBasic(t9:L,a4:L);
>     t11:L=BoundMethodHandle$Species_L3.argL0(a0:L);
>     t12:L=MethodHandle.invokeBasic(t11:L,a1:L,a2:L,a3:L,t10:L,t8:L,a6:L);t12:L}
> Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
>
> And also NPEs sometimes. 

I get the NPE with stack trace:

Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
j  sun.security.jca.ProviderList$3.size()I+4 java.base at 9-internal
J 3610 c2 java.util.AbstractList$Itr.hasNext()Z java.base at 9-internal (20 bytes) @ 0x00007f56b3d4a450 [0x00007f56b3d4a260+0x00000000000001f0]
j  java.security.SecureRandom.getPrngAlgorithm()Ljava/lang/String;+13 java.base at 9-internal                                                                                                                                                                                        
J 3735 c2 java.security.SecureRandom.getDefaultPRNG(Z[B)V java.base at 9-internal (110 bytes) @ 0x00007f56b3f4b040 [0x00007f56b3f4b000+0x0000000000000040]
J 3732 c2 java.security.SecureRandom.<init>()V java.base at 9-internal (35 bytes) @ 0x00007f56b3f263b4 [0x00007f56b3f26320+0x0000000000000094]
j  java.util.UUID$Holder.<clinit>()V+4 java.base at 9-internal
v  ~StubRoutines::call_stub

The NPE is triggered by a null reference in the interpreter when loading
an array length (ProviderList.configs I suppose). I managed to keep
track of the this pointer that the compiled code sees on entry to
java.util.AbstractList$Itr.hasNext(). In the debugger from the signal
handler for the null check if I dereference this$0 fields all the way to
the ProviderList.configs, I end up on a array that is not null:

"Executing find"
0x00000005ca800078 is an oop
java.util.AbstractList$Itr
{0x00000005ca800078} - klass: 'java/util/AbstractList$Itr'
 - ---- fields (total size 4 words):
 - 'cursor' 'I' @12  0
 - 'lastRet' 'I' @16  -1 (ffffffff)
 - 'expectedModCount' 'I' @20  0
 - final synthetic 'this$0' 'Ljava/util/AbstractList;' @24  a 'sun/security/jca/ProviderList$3'{0x00000007bffbe7e0} (f7ff7cfc 0)

"Executing find"
0x00000007bffbe7e0 is an oop
sun.security.jca.ProviderList$3
{0x00000007bffbe7e0} - klass: 'sun/security/jca/ProviderList$3'
 - ---- fields (total size 3 words):
 - protected transient 'modCount' 'I' @12  0
 - final synthetic 'this$0' 'Lsun/security/jca/ProviderList;' @16  a 'sun/security/jca/ProviderList'{0x00000007bfe00548} (f7fc00a9 0)

"Executing find"
0x00000007bfe00548 is an oop
sun.security.jca.ProviderList
{0x00000007bfe00548} - klass: 'sun/security/jca/ProviderList'
 - ---- fields (total size 3 words):
 - private volatile 'allLoaded' 'Z' @12  false
 - private final 'configs' '[Lsun/security/jca/ProviderConfig;' @16  a 'sun/security/jca/ProviderConfig'[12] {0x00000005ca800008} (b9500001 f7ff7cfc)
 - private final strict 'userList' 'Ljava/util/List;' @20  a 'sun/security/jca/ProviderList$3'{0x00000007bffbe7e0} (f7ff7cfc bfe00568)

"Executing find"
0x00000005ca800008 is an oop
[Lsun.security.jca.ProviderConfig;
{0x00000005ca800008} - klass: 'sun/security/jca/ProviderConfig'[]
 - length: 12
 -   0 : a 'sun/security/jca/ProviderConfig'{0x00000007bff80398}
 -   1 : a 'sun/security/jca/ProviderConfig'{0x00000007bff80188}
 -   2 : a 'sun/security/jca/ProviderConfig'{0x00000007bff801b0}
 -   3 : a 'sun/security/jca/ProviderConfig'{0x00000007bff801d8}
 -   4 : a 'sun/security/jca/ProviderConfig'{0x00000007bff80200}
 -   5 : a 'sun/security/jca/ProviderConfig'{0x00000007bff80228}
 -   6 : a 'sun/security/jca/ProviderConfig'{0x00000007bff80250}
 -   7 : a 'sun/security/jca/ProviderConfig'{0x00000007bff80278}
 -   8 : a 'sun/security/jca/ProviderConfig'{0x00000007bff802a0}
 -   9 : a 'sun/security/jca/ProviderConfig'{0x00000007bff802c8}
 -  10 : a 'sun/security/jca/ProviderConfig'{0x00000007bff802f0}
 -  11 : a 'sun/security/jca/ProviderConfig'{0x00000007bff80370}

The java.util.AbstractList$Itr.hasNext() compiled code is correct as far
as I can tell: its loads this$0 without a read barrier because the field
is final and passes it to the call to size().

In short what I'm seeing seems impossible: when I follow references in
the debugger after the null check has fired I end up on a non null
reference and so no null check should have fired.

Is there anyway the thead could see a partially copied
'sun/security/jca/ProviderList at some point?

Roland.


More information about the shenandoah-dev mailing list