RFR: Traveral GC heuristics
Aleksey Shipilev
shade at redhat.com
Tue Jan 23 16:06:20 UTC 2018
On 01/22/2018 11:17 PM, Roman Kennke wrote:
> - when growing the heap, we must make sure that the TAMS points to end for the new regions,
> otherwise we'd treat them implicitely marked.
Is this the source of this spooky change?
inline ShenandoahHeapRegion* get(size_t i) const {
- assert (i < _active_end, "sanity");
+ assert (i < _reserved_end, "sanity");
return _regions[i];
}
get() is supposed to only return added regions. I think if you return something farther the
_active_end, you read garbage.
> - folded 'SATB' queue processing into thread stack scanning. The problem here is that iterating
> the threads 2x is cumbersome because of the claiming protocol: we need to fire the task/workers
> 2x: once for the SATB queues, once for the thread scanning. I folded it into one pass. This
> required a (trivial) extension in the upstream parallel thread scanning/iteration protocol.
So this is the source for extension of RootProcessor and Thread methods? I am a bit uneasy about
this (mostly because it raises backporting questions). I'd rather include this into RootProcessor
right away, and assert nothing passes non-NULL ThreadClosure there. Then, sh/jdk8u, sh/jdk9 and
sh/jdk10 versions would agree on the shape of RootProcessor methods and the calls to it, while
sh/jdk10 would call RootProcessor with non-NULL ThreadClosure, and it would *also* implement the
relevant parts in Thread.
> - I tripped an assert in SHR::increase_live_data(). I think the reason is that we have a race
> here: a GC thread might not yet see the updated SHR::_top but already accounts for the updated
> live data. I excluded conc-traversal from that check. This could probably be fixed by doing the
> proper concurrency membars, but do we care? For assertion code?
But wait, this change means "s" is greater than max_jint on some paths during Traversal?!
inline void ShenandoahHeapRegion::increase_live_data_words(size_t s) {
- assert (s <= (size_t)max_jint, "sanity");
+ assert (s <= (size_t)max_jint || _heap->is_concurrent_traversal_in_progress(), "sanity");
increase_live_data_words((int)s);
}
Also, I am confused where Traversal calls increase_live_data_words(size_t), because both call sites
are already protected:
if (!sh->is_concurrent_traversal_in_progress()) {
r->increase_live_data_words(used_words);
}
...
if (!ShenandoahHeap::heap()->is_concurrent_traversal_in_progress()) {
r->increase_live_data_words(word_size);
}
> Full:
> http://cr.openjdk.java.net/~rkennke/traversal/webrev.04/
Since we have "adaptive" failures with C2 and/or -ShWBMemBar, I propose we chicken out, and drop all
C2 changes (apart from the actual enqueue_barrier) from this change, then follow up on optimization
story in subsequent changesets. This way we could integrated Traversal GC, and not risk immediate
regression in non-Traversal code.
This is done, along with other minor touchups here (apply over webrev.04):
http://cr.openjdk.java.net/~shade/shenandoah/traversal-shade-updates-1.patch
Thanks,
-Aleksey
More information about the shenandoah-dev
mailing list