G1 question: concurrent cleaning of dirty cards

John Cuthbertson john.cuthbertson at oracle.com
Thu May 23 00:29:13 UTC 2013

Hi Martin,

An enqueued card let's the refinment threads know that the oops spanned 
by that card need to be walked but we're only interested in the latest 
contents of the fields in those oops. IOW the oop in (3') doesn't need 
to be the oop stored in (1). If there's a subsequent store (3) to the 
same location then we want the load at (3') to see the lastest contents. 
For example suppose we have:

x.f = a;
x.f = b;

If the application thread sees the card spanning x.f is dirty at the 
second store then we won't enqueue the card after the second store. As 
long as the refinement thread sees 'b' when the card is 'refined' then 
we're OK since we no longer need to add an entry into the RSet for the 
region containing a - we do need an entry in the RSet for the region 
containing b.

If the application thread sees the card as clean at the second store 
before the refinement thread loads x.f we have just needlessly enqueued 
the card again.

It is only if the application thread sees the card as dirty but the 
refinement thread reads 'a' then there could be a problem. We have a 
missing RSet entry for 'b'.


On 5/17/2013 1:29 AM, Doerr, Martin wrote:
> Hi all,
> we have a question about the interaction between G1 post barriers and 
> the refinement thread's concurrent dirty card cleaning.
> The case in which the G1 post barrier sees a clean card is obviously 
> not problematic, because it will add an entry in a dirty card queue.
> However, in case in which the Java thread (mutator thread) sees the 
> card already dirtied, it won't enqueue the card again. Which is safe 
> as long as its stored oop (1) is seen and processed (3') by the 
> parallel refinement after having cleaned the card (1'):
> Java Thread (mutator)              Refinement Thread 
> (G1RemSet::concurrentRefineOneCard_impl calls 
> oops_on_card_seq_iterate_careful)
> (1) store(oop)
> ( StoreLoad required here ?)
> (2) load(card==dirty)
>               (1') store(card==clean)
>   (2') StoreLoad barrier
>          (3') load(oop)
> So the refinement thread seems to rely on getting the oop which was 
> written BEFORE the (2) load(card==dirty) was observed.
> We wonder how this ordering is guaranteed? There are no StoreLoad 
> barriers in the Java Thread's path. (StoreLoad ordering needs explicit 
> barriers even on TSO platforms.)
> Kind regards,
> Martin

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/hotspot-gc-dev/attachments/20130522/16d315ea/attachment.htm>

More information about the hotspot-gc-dev mailing list