RFR (S) 8078438: Interpreter should support conditional card marks (UseCondCardMark)
mikael.gerdin at oracle.com
Thu Apr 30 13:52:47 UTC 2015
On 2015-04-30 12:33, Thomas Schatzl wrote:
> On Wed, 2015-04-29 at 18:32 +0100, Andrew Haley wrote:
>> On 04/29/2015 05:20 PM, Andrew Dinn wrote:
>>> But then neither is there anything to guarantee that the conditional
>>> test at T3_a sees the write of 0x1 at T3_b. We know T3_b > T1_a but that
>>> is all. The mutator and GC thread would have to employ some sort of
>>> ordering relationship between the write at T3_b and the read at T3_a to
>>> guarantee that. TSO won't do it. Nor will an stlr at T1_a.
>>> Of course, if the mutator writes the card unconditionally at T3_a then
>>> there is no problem -- the GC will see the dirty card at the next dirty
>>> scan. The problem is that the condition test may be based on out of date
>>> information causing a necessary card mark to be omitted.
>> I wondered if a halfway house would work. Something like
>> o.x = a
>> if card[o >> 9] != 0x0
>> card[o >> 9] = 0x0
>> There is a release in write_ref_field() but I think it's only used by
>> mutator threads. I think there is something vital we don't
>> understand. I think the actual collection (and the write of the card
>> table entry by the collector) happens only at a safepoint. GC people,
>> can you help?
> From my understanding, the GC thread does something like this concurrent
> to the mutator:
> find card[o >> 9] == 0x0 ("dirty")
> set card[o >> 9] == 0x1 ("precleaned")
> storeload+CAS+loadstore+loadload // via at least one Atomic::cmpxchg()
> in the code path for the mutex locking.
> read o.x
> Still I believe the code is broken as the load for the card could float
> above the store. A StoreLoad barrier (in case of enabled conditional
> card marking) would help I guess.
> However, that one is expensive, and I am not sure if it would outweigh
> the gains from the conditional card marking.
> An alternative would be to disable conditional card marking when
> precleaning is enabled (basically always) in CMS.
Yep, I think you and the Andrews are correct.
For UseCondCardMark to be correct with CMS with precleaning it would
require a StoreLoad between the field write and the card table load.
Another approach to solve this partially would be to change the
condition for the conditional card mark from an equality test aginst 0x0
to a negated equality test of 0xff (clean_card_val)
In that case we would slightly reduce the number of false-sharing
inducing card writes and still survive the precleaning phase since
precleaning sets the card to 0x1 (precleaned_card_val).
More information about the hotspot-gc-dev