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