[aarch64-port-dev ] RFR(s): 8171449" [aarch64] store_klass needs to use store release
Thomas Schatzl
thomas.schatzl at oracle.com
Wed Dec 21 12:22:11 UTC 2016
Hi Andrew,
On Tue, 2016-12-20 at 16:42 +0000, Andrew Haley wrote:
> Hi,
>
> On 20/12/16 14:40, White, Derek wrote:
>
> >
> > Some background. There are two synchronization issues around object
> > initialization:
> > 1) The allocating thread needs to ensure that the object is fully
> > initialized (to default zeros or specified values) before another
> > Java thread can see the object. This case is well handled with
> > memory barriers etc.
> >
> > 2) A concurrent GC might find an object during heap scanning that
> > has been allocated but not yet initialized. At the least it needs
> > to know the size of the object if it's to reason about it. To
> > enable this, the contract between the runtime and the concurrent
> > collectors is that the length of an array (and 'forgotten case B'),
> > is written before the klass word is installed in the header. If CMS
> > finds an object with a null klass word, it either retries,
> > terminates what it's doing, or uses a back-up method for finding
> > the object size.
>
> I've had a look at what was confusing me so much, and I think I have
> found something. In
> G1CollectedHeap::humongous_obj_allocate_initialize_regions I see
> this:
>
> // First, we need to zero the header of the space that we will be
> // allocating. When we update top further down, some refinement
> // threads might try to scan the region. By zeroing the header we
> // ensure that any thread that will try to scan the region will
> // come across the zero klass word and bail out.
> //
> Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
>
> ...
>
> OrderAccess::storestore();
>
> >
> > This was fixed, but discussion led to the point that a compiler or
> > weak memory-model CPU might also write the fields out-of-order, so
> > a series of fixes changed the concurrent GC code to use load-
> > acquires when necessary. This is JDK-8160369 and sub-tasks. See in
> > particular oopDesc:: klass_or_null_acquire().
> Sure.
>
> >
> > As far as which GCs need to worry about this goes, CMS is clearly
> > in
> > danger with this issue on weak memory model systems. I don't have a
> > definitive answer for G1. Thomas makes a good argument that in G1,
> > concurrent GC would only scan a newly allocated object if it were
> > humongous, and there are enough memory barriers around allocating a
> > humungous region that we should be safe. But there were changes
> > made
> > to G1 to use oopDesc:: klass_or_null_acquire(). See
> > http://hg.openjdk.java.net/jdk9/hs/hotspot/rev/1a33f585a889
> > . Perhaps these are overly conservative?
> After an object is allocated and before it is zeroed, the object is
> garbage. This includes the klass field, which probably is non-null.
> There is a window in time between the memory being allocated and the
> klass field being written. So, I suppose until the klass field is
> written, some memory which is about to become an array must not be
> visible to CMS. It must not be visible because it must not be
> possible for CMS to see a garbage klass field.
s/CMS/G1?
At that point "top" of the region must be the same as "bottom" in this
case. To be allocated, a region must have been "Free" before that; we
set to "Free" and reset a regions' "top" to "bottom" only during STW
pause, so this must be visible.
So this card will be filtered out by the gc thread and that area not
scanned, the check is at g1RemSet.cpp:668. Also see the comment at line
659.
I hope this is the answer to your question.
Hth,
Thomas
More information about the aarch64-port-dev
mailing list