possible CMS problem with C2
Tom Rodriguez
tom.rodriguez at oracle.com
Thu Mar 31 17:57:41 PDT 2011
To close the loop on this, here's at least one case of this I found with a little awkery and inspection:
00c B1: # B151 B2 <- BLOCK HEAD IS JUNK Freq: 1
00c ! stack bang
SAVE R_SP,-112,R_SP
018 SET 0xf92d4000,R_L1 !ptr
01c + STW R_I3,[R_I0 + #20] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.documentation
020 SRL R_I0,#9,R_L0 ! Cast ptr R_I0 to int and shift
024 + STB #0,[R_L1 + R_L0] ! CMS card-mark byte 0
028 LDUW [R_SP + #188],R_L0 ! spill
02c + STW R_L0,[R_I0 + #28] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.value
030 LDUW [R_SP + #184],R_L1 ! spill
034 + STW R_L1,[R_I0 + #24] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.exp
038 LDUW [R_SP + #176],R_L7 ! spill
03c + STW R_L7,[R_I0 + #36] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.name
040 + STW R_I5,[R_I0 + #16] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.type
044 + STW R_I4,[R_I0 + #12] ! Field spec/benchmarks/_213_javac/FieldDefinition.modifiers
048 STW R_I2,[R_SP + #96] ! spill
04c + STW R_I2,[R_I0 + #32] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.clazz
050 STW R_I1,[R_SP + #92] ! spill
054 + STW R_I1,[R_I0 + #8] ! Field spec/benchmarks/_213_javac/FieldDefinition.where
058 LDUW [R_I5 + #8],R_L1 ! int ! Field spec/benchmarks/_213_javac/Type.typeCode
05c NullCheck R_I5
If we don't eliminate any of the StoreCMs this code looks like this:
00c B1: # B152 B2 <- BLOCK HEAD IS JUNK Freq: 1
00c ! stack bang
SAVE R_SP,-112,R_SP
018 SET 0xb53d2000,R_L2 !ptr
01c + SRL R_I0,#9,R_L1 ! Cast ptr R_I0 to int and shift
020 STW R_I2,[R_I0 + #32] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.clazz
024 + ADD R_L2,R_L1,R_L0
028 STW R_I5,[R_I0 + #16] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.type
02c + STB #0,[R_L0] ! CMS card-mark byte 0
030 LDUW [R_SP + #176],R_L3 ! spill
034 + STW R_L3,[R_I0 + #36] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.name
038 + STB #0,[R_L0] ! CMS card-mark byte 0
03c LDUW [R_SP + #184],R_L2 ! spill
040 + STW R_L2,[R_I0 + #24] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.exp
044 + STB #0,[R_L0] ! CMS card-mark byte 0
048 LDUW [R_SP + #188],R_L1 ! spill
04c + STW R_L1,[R_I0 + #28] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.value
050 + STB #0,[R_L0] ! CMS card-mark byte 0
054 + STW R_I3,[R_I0 + #20] ! ptr ! Field spec/benchmarks/_213_javac/FieldDefinition.documentation
058 + STB #0,[R_L0] ! CMS card-mark byte 0
05c + STB #0,[R_L0] ! CMS card-mark byte 0
060 STW R_I1,[R_SP + #92] ! spill
064 + STW R_I1,[R_I0 + #8] ! Field spec/benchmarks/_213_javac/FieldDefinition.where
068 STW R_I2,[R_SP + #96] ! spill
06c + STW R_I4,[R_I0 + #12] ! Field spec/benchmarks/_213_javac/FieldDefinition.modifiers
070 LDUW [R_I5 + #8],R_L1 ! int ! Field spec/benchmarks/_213_javac/Type.typeCode
074 NullCheck R_I5
So it definitely occurs in the wild. I think we're going to need to optimize away the redundant ones since they appear to be fairly common. II see how to do it during final_graph_reshape so that we can accumulate the dependences and place the single one where it should go.
tom
On Mar 31, 2011, at 2:17 PM, Tom Rodriguez wrote:
> I filed 7032963 for this.
>
> tom
>
> On Mar 31, 2011, at 1:52 PM, Y. S. Ramakrishna wrote:
>
>> Hi Tom --
>>
>> On 03/31/11 12:41, Tom Rodriguez wrote:
>>> While looking at the code we generate for a simple program I noticed that we were eliminating card marks with CMS in a illegal fashion. For this simple program:
>>> public class test {
>>> static Object a1;
>>> static Object a2;
>>> static Object a3;
>>> public static void main(String[] args) {
>>> a1 = args;
>>> a2 = args;
>>> a3 = args;
>>> }
>>> }
>>> we generate this:
>>> 000 B1: # N1 <- BLOCK HEAD IS JUNK Freq: 1
>>> 000 SAVE R_SP,-72,R_SP
>>> 004 SET precise klass test: 0x00843a50:Constant:exact *,R_L0 !ptr
>>> 00c + SET 0xf92d4000,R_L2 !ptr
>>> 010 + STW R_I0,[R_L0 + #352] ! ptr ! Field test.a3
>>> 014 + STW R_I0,[R_L0 + #348] ! ptr ! Field test.a2
>>> 018 + SRL R_L0,#9,R_L1 ! Cast ptr R_L0 to int and shift
>>> 01c STW R_I0,[R_L0 + #344] ! ptr ! Field test.a1
>>> 020 + STB #0,[R_L2 + R_L1] ! CMS card-mark byte 0
>>> 024 SETHI #PollAddr,L0 ! Load Polling address
>>> LDUW [L0],G0 !Poll for Safepointing
>>> RET
>>> RESTORE
>>> 034 + ! return
>>> 034
>>> which happens to be ok because the STB happens last but we don't actually have enough dependences to ensure that we get this schedule. We emit 3 separate StoreCMs for each field references and each one has a dependence on the store that it covers. What's going wrong is that we're allowing StoreCM to participate in the the store elimination in StoreNode::Ideal so we end up with this:
>>> 45 StoreP === 5 7 44 10 [[ 16 50 ]] @precise klass test: 0x00843a50:Constant:exact+352 *, name=a3, idx=6; Memory: @precise klass test: 0
>>> x00843a50:Constant:exact+352 *, name=a3, idx=6; !jvms: test::main @ bci:9
>>> 36 StoreP === 5 7 35 10 [[ 16 ]] @precise klass test: 0x00843a50:Constant:exact+348 *, name=a2, idx=5; Memory: @precise klass test: 0x008
>>> 43a50:Constant:exact+348 *, name=a2, idx=5; !jvms: test::main @ bci:5
>>> 25 StoreP === 5 7 24 10 [[ 16 ]] @precise klass test: 0x00843a50:Constant:exact+344 *, name=a1, idx=4; Memory: @precise klass test: 0x008
>>> 43a50:Constant:exact+344 *, name=a1, idx=4; !jvms: test::main @ bci:1
>>> 50 StoreCM === 5 7 31 23 45 [[ 16 ]] @rawptr:BotPTR, idx=Raw; Memory: @rawptr:BotPTR, idx=Raw; !jvms: test::main @ bci:9
>>> The store to a3 has a StoreCM and it has killed the StoreCMs for a1 and a2 but it doesn't have a dependence on it. Since the slices are independent the a3 operations could be scheduled before the store to a1 and a2. It may be that this is rare in practice and/or the local schedule tends to put the StoreCM last but it's clearly wrong. G1 is safe from this because the StoreCMs are never close enough to be eliminated.
>>> It's easy to fix but it might hurt CMS performance a bit. It could also be done safely if the StoreCM could have dependences on multiple stores but since it's not using normal precedence edges I'm not sure how this would be implemented.
>>> Does this sound like any issues that have been seen in the past?
>>
>> If it's been seen in the past, it has never been identified
>> as stemming from this kind of optimization / missing dependencies.
>> I have heard people (Vladimir, Igor, John Cuthbertson) express the lack of
>> confidence in the existence of sufficient dependencies in some of the
>> card-mark eliminations before.
>>
>> There was a time way back when Mike Paleczny and Ross Knippel
>> had fixed issues stemming from illegal (for CMS) elision of card-marks
>> in the case of CMS, and we had also taken care to add some
>> missing ones in the runtime for perm objects, but this
>> one is new to me.
>>
>> Yes, please fix this; even though i imagine this will be rare
>> because (1) such scheduling may be rare (2) it's only when this
>> intersects with precleaning that this would manifest, and if
>> CMS collections are infrequent, the error will be rare (3) the
>> lack of a card-mark for the elided/rescheduled stores may be
>> masked by a different store to an adjacent object, making an
>> actual crash rarer still. But still, thanks for finding the
>> issue and fixing it! It would be interesting to see how much
>> of a difference in performance the new previously missing
>> dependencies will make to real codes/workloads.
>>
>> -- ramki
>>
>>> tom
>
More information about the hotspot-compiler-dev
mailing list