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