PING^3: RFD: C2 bug: 8157306 random infrequent null pointer exceptions in javac

Vladimir Kozlov vladimir.kozlov at oracle.com
Thu Aug 4 03:35:49 UTC 2016


It looks like it caused by PhaseCFG::implicit_null_check() based on nodes you showed (NullCheck node for storeL node).

implicit_null_check() may move memory node into previous blocks. In this case it moved StoreL to the block which have dependent load. implicit_null_check() checks for anti_dependent loads but only for 
blocks below the block with NULL check (b !- block):

       // mach use (faulting) trying to hoist
       // n might be blocker to hoisting
       while( b != block ) {
         uint k;
         for( k = 1; k < b->number_of_nodes(); k++ ) {
           Node *n = b->get_node(k);
           if( n->needs_anti_dependence_check() &&
               n->in(LoadNode::Memory) == mach->in(StoreNode::Memory) )
             break;              // Found anti-dependent load
         }

What saves us is StoreL node is placed the last in the block.
I think we need to call insert_anti_dependences() at the end of  implicit_null_check():

   latency_from_uses(nul_chk);
   latency_from_uses(best);

   // insert anti-dependences to defs in this block
   for (uint k = 1; k < block->number_of_nodes(); k++) {
     Node *n = block->get_node(k);
     if (n->needs_anti_dependence_check() &&
         n->in(LoadNode::Memory) == best->in(StoreNode::Memory)) {
       // Found anti-dependent load
       insert_anti_dependences(block, n);
     }
   }
}

I can't reproduce the problem any more with latest hs-comp sources. Andrew, can you verify this fix? I will also will try to find build which fails.

Thanks,
Vladimir


On 7/30/16 10:03 AM, Andrew Haley wrote:
> On 28/07/16 05:02, Vladimir Kozlov wrote:
>> I reproduced it running jtreg in hotspot/test:
>>
>> jtreg -testjdk:$JAVA_HOME -v -vmoptions:'-Xcomp' compiler/calls/fromCompiled/CompiledInvokeDynamic2CompiledTest.java
>>
>> and other compiler/calls tests.
>>
>> It crashed not in test execution but during test compilation:
>>
>> ACTION: compile -- Error. unexpected exit code from javac: 6
>
> This failure happens because first a load and then a store are
> scheduled into a block.  But as far as I can see there is no attempt
> to insert a precedence edge when the store is scheduled.
>
> In GCM we start with this:
>
> B20: #	B22 B21 <- N159 N161 N163  Freq: 0.0999936
>   89	Region	===  89  158  157  156  [[ 89  87  114 ]]  !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:99
>   87	jmpCon	===  89  88  [[ 86  123 ]] P=0.999999, C=-1.000000 !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:100
>   86	IfFalse	===  87  [[ 155 ]] #0 !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:100
>   123	IfTrue	===  87  [[ 164  125 ]] #1 !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:100
>
> And end up with this:
>
> B20: #	B22 B21 <- B19 B24 B25  Freq: 0.0999936
>   89	Region	===  89  158  157  156  [[ 89  172  114  125 ]]  !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:99
>   114	Phi	===  89  115  116  118  [[ 103 ]]  #long:0..8796093022208:w !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:93
>   102	orL_rReg	=== _  103  112  [[ 113  83  125 ]]  !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:99
>   113	MachProj	===  102  [[]] #1
>   103	orL_rReg	=== _  104  114  [[ 111  102 ]]
>   111	MachProj	===  103  [[]] #1
>   112	loadConL	===  1  [[ 102 ]] #562949953425410/0x0002000000001002
>   104	orL_rReg	=== _  105  108  [[ 110  103 ]]
>   110	MachProj	===  104  [[]] #1
>   108	andL_rReg_mem_0	===  160  68  79  106  [[ 109  104 ]] #16/0x0000000000000010
>   109	MachProj	===  108  [[]] #1
>   105	andL_rReg_mem_0	===  154  68  67  106  [[ 107  104 ]] #16/0x0000000000000010
>   107	MachProj	===  105  [[]] #1
>   100	loadN	=== _  68  16  [[ 125 ]] narrowoop: com/sun/tools/javac/code/Symbol$MethodSymbol * !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:41
>   106	loadConUL32	===  14  [[ 105  108 ]] #2048/0x0000000000000800
>   125	storeL	===  89  68  100  102  [[ 124  172 ]] memory  Memory: @com/sun/tools/javac/code/Symbol$MethodSymbol+16 *, name=flags_field, idx=8; !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:100
>   172	NullCheck	===  89  125  [[ 123  86 ]]
>   123	IfTrue	===  172  [[ 155 ]] #1 !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:100
>   86	IfFalse	===  172  [[ 164 ]] #0 !jvms: LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext::complete @ bci:100
>
> The load at 105 does have a true anti dependence on the store at 125.
>
> This is before LCM.  I would have thought that LCM needed precedence
> edges to be correct, and I'm sure they are not.  But the really
> baffing thing for me is that when store nodes are scheduled into a
> block there is no attempt to add precedence edges.
>
> Andrew.
>


More information about the hotspot-compiler-dev mailing list