RFR: 8166811: Missing memory fences between memory allocation and refinement

Kim Barrett kim.barrett at oracle.com
Tue Oct 25 23:13:08 UTC 2016


Please review this change to address missing memory barriers needed to
ensure ordering between allocation and refinement in G1.

Rather than simply adding the "obvious" barriers, this change modifies
refinement to not need any additional memory barriers.

First, the heap region type predicate used to decide whether the card
should be processed has been changed.  Previously, !is_young was used,
but that isn't really the state of interest. Rather, processing should
only occur if the region is old or humongous, not if young or *free*.
The free case (and so other cases that should be filtered out) can
happen if the card is stale, and there are several ways to get stale
cards here.  So added is_old_or_humongous type predicate and use it
for filtering based on the region's type.

Second, moved to refine_card the card region trimming to the heap
region's allocated space, and the associated filtering, to be
co-located with the type-based filtering.  An empty trimmed card
region is another indication of a stale card.

We should filter out cards that are !is_old_or_humongous or when the
card's region is beyond the allocated space for the heap region.  Only
if the card is old/humongous and covers allocated space should we
proceed with processing, and then only for the subset of the card
covering allocated space.

Moved the card cleaning to refine_card.  Having the cleaning in the
iterator seemed misplaced.  Placing it in refine_card, after the card
trimming and type-based filtering also allows the fence needed for the
cleaning to serve double duty; in addition to ensuring processing
occurs after card cleaning (the original purpose), it now also ensures
processing follows the filtering.  And this ensures the necessary
synchronization with allocation; we can't safely examine some parts of
the heap region object or the memory designated by the card until
after the card has been trimmed and filtered.  Part of this involved
changing the storeload to a full fence, though for supported platforms
that makes no difference in the underlying implementation.

(This change to card cleaning would benefit from a store_fence
operation on some platforms, but that operation was phased out, and a
release_store_fence is stronger (and more expensive) than needed on
some platforms.)

There is still a situation where processing can fail, namely an
in-progress humongous allocation that hasn't set the klass yet.  We
continue to handle that as before.

CR:
https://bugs.openjdk.java.net/browse/JDK-8166811

Webrev:
http://cr.openjdk.java.net/~kbarrett/8166811/webrev.00/
[Based on http://cr.openjdk.java.net/~kbarrett/8166607/webrev.02/]

Testing:
Local jtreg hotspot_all.
Local specjbb2015 preset.ir for several hours.
Local kitchensink for several hours.
Nightly test equiv. via rbt. (in progress)



More information about the hotspot-dev mailing list