RFR (S) 8078438: Interpreter should support conditional card marks (UseCondCardMark)

Thomas Schatzl thomas.schatzl at oracle.com
Tue Apr 28 15:54:48 UTC 2015


Hi,

On Tue, 2015-04-28 at 16:03 +0100, Andrew Haley wrote:
> On 04/28/2015 02:28 PM, Mikael Gerdin wrote:
> > 
> > On 2015-04-28 15:13, Andrew Haley wrote:
> >> On 04/28/2015 02:06 PM, Mikael Gerdin wrote:
> >>>
> >>> On 2015-04-28 14:45, Andrew Haley wrote:
> >>>> On 04/28/2015 11:56 AM, Thomas Schatzl wrote:
> >>>>> Somewhat related, note that C2 adds a MemBarRelease before the actual
> >>>>> card table store (see StoreCMNode) I think to ensure store ordering (the
> >>>>> card mark must be visible after the reference write). So the given
> >>>>> aarch64 code seems to be missing something already.
> >>>>
> >>>> I don't think it's missing anything.  It has the barrier in the correct
> >>>> place when G1 is in use, and CMS isn't supposed to need one.
> >>>
> >>> I think it does depend on StoreStore ordering, the field write must be
> >>> visible if the dirty card byte is visible.
> >>
> >> Hmm.  We were told otherwise here before.  Does the code which scans
> >> the card table use a load barrier after each read of the card?  If not
> >> the StoreStore won't have any effect anyway.
> > 
> > Consider the following sequence of events:
> > Mutator:		CMS-preclean:
> > # o.x == NULL
> > o.x = a			
> > card[o >> 9] = 0x0	finds card[o >> 9] == 0x0
> > 			reads o.x, finds NULL
> > 			writes card[o >> 9] = 0x1
> > #			o.x == a becomes visible
> > 
> > CMS-remark occurs, o.x is not scanned because card[o >> 9] == 0x1 which 
> > is not dirty.
> 
> I see.
> 
> > There's no load barrier in the card scanning code that I'm aware of.
> 
> In which case the store barrier won't have any effect.  I see your
> point, but there really is no point fixing only one end of this bug.
> If this ordering matters there really has to be a barrier after
> reading the card.

I dug a little through the CMS code, and I think the preclean code
mentioned is actually something like this:

{
MutexLocker x(some-lock); // In the CMSTockenSync constructor
}

MemRegion range = find next range of dirty cards by scanning the card
table

write 0x1 to range

{
MutexLocker x(some-lock); // In the CMSTockenSync destructor
}

inspect all object references in range x

See CMSCollector::preclean_card_table().

I.e. the implicit barriers (the CAS'es) executed by acquiring the
mutexes in the preclean thread provide the necessary synchronization
(actually between reading the card and inspecting the memory there are a
few of them).

I am not sure if this was the intention of using these MutexLockers (I
doubt that) but it seems sufficient.

Please have a look at the mentioned method.

Thanks,
  Thomas




More information about the hotspot-gc-dev mailing list