RFR: 8080106: Refactor setup of parallel GC threads
Stefan Karlsson
stefan.karlsson at oracle.com
Mon May 18 11:17:12 UTC 2015
Hi Kim,
On 2015-05-14 05:01, Kim Barrett wrote:
> On May 13, 2015, at 9:17 AM, Stefan Karlsson <stefan.karlsson at oracle.com> wrote:
>> Hi all,
>>
>> Please review these patches to unify the ways we specify the number of used worker threads. The main goal for these patches is to get rid of CollectedHeap::set_par_threads() and CollectedHeap::n_par_threads().
>>
>> The RFE has been split into multiple sub-tasks:
>> 8080109: Use single-threaded code in Threads::possibly_parallel_oops_do when running with only one worker thread
>> 8080110: Remove usage of CollectedHeap::n_par_threads() from root processing
>> 8080111: Remove SubTaskDone::_n_threads
>> 8080112: Replace and remove the last usages of CollectedHeap::n_par_threads()
>> 8080113: Remove CollectedHeap::set_par_threads()
>>
>> See the description below for each individual patch:
> Thanks for breaking this up into multiple webrevs.
>
> I'm only part way through; I haven't looked at the webrev for 8080113
> yet. Here's what I've got so far.
>
> ==============================================================================
> http://cr.openjdk.java.net/~stefank/8080109/webrev.00
> 8080109: Use single-threaded code in Threads::possibly_parallel_oops_do when running with only one worker thread
>
> Looks good.
>
> ==============================================================================
> http://cr.openjdk.java.net/~stefank/8080110/webrev.00
> 8080110: Remove usage of CollectedHeap::n_par_threads() from root processing
>
> I would have found this easier to review if the description contained
> some discussion of the elimination of MarkScope::_active.
Yes. I actually intended to move the setup of StrongRootScope and the
removal of MarkScope::_active as a separate patch, but that patch was
hard to motivate without the rest of 8080110.
MarkScope::_active was used to allow the single-threaded code to call
gen_process_roots without having to create explicitly create s
StrongRootsScope before calling gen_process_roots. With this patch all
callers of gen_process_roots have to pass a pointer to a
StrongRootsScope as an argument to gen_process_roots, so there's no need
to keep the MarkSweep::_active variable anymore.
>
> ------------------------------------------------------------------------------
> src/share/vm/memory/genCollectedHeap.hpp
> 401 void gen_process_roots(StrongRootsScope* scpe,
>
> scpe => scope
Fixed.
>
> ------------------------------------------------------------------------------
> src/share/vm/memory/strongRootsScope.hpp
>
> Pre-existing defect: For the MarkScope class, at least the destructor
> should be protected, to ensure no accidental slicing. The constructor
> can also be protected.
I changed it to protected.
>
> ==============================================================================
> http://cr.openjdk.java.net/~stefank/8080111/webrev.00
> 8080111: Remove SubTaskDone::_n_threads
>
> Looks good.
Thanks.
>
> ==============================================================================
> http://cr.openjdk.java.net/~stefank/8080112/webrev.00
> 8080112: Replace and remove the last usages of CollectedHeap::n_par_threads()
>
> ------------------------------------------------------------------------------
> src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
> 1899 if (rem_sz < SmallForDictionary) {
> 1900 // The freeList lock is held, but multiple GC task threads might be executing in parallel.
> 1901 bool is_par = Thread::current()->is_GC_task_thread();
> 1902 if (is_par) _indexedFreeListParLocks[rem_sz]->lock();
> 1903 returnChunkToFreeList(ffc);
> 1904 split(size, rem_sz);
> 1905 if (is_par) _indexedFreeListParLocks[rem_sz]->unlock();
> 1906 } else {
> 1907 returnChunkToDictionary(ffc);
> 1908 split(size, rem_sz);
> 1909 }
>
> Conditional locking could be eliminated by changing the test on line
> 1899 to also test the is_par expression. OTOH, see next comment.
One branch calls returnChunkToFreeList while the other calls
returnChunkToDictionary, so I'm not sure I understand what you suggest.
>
> ------------------------------------------------------------------------------
> src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
> 1900 bool is_par = (GenCollectedHeap::heap()->n_par_threads() > 0);
> =>
> 1901 bool is_par = Thread::current()->is_GC_task_thread();
>
> This new mechanism for computing is_par seems like it might be
> substantially more expensive than the old mechanism. I'm not sure
> whether it's likely to be noticably so.
Do you mean the call to Thead::current()? Do you have any suggestion on
how to rewrite this?
>
> ------------------------------------------------------------------------------
> src/share/vm/gc_implementation/g1/concurrentMark.cpp
> 1998 uint n_workers;
> ...
> 2004 n_workers = g1h->n_par_threads();
> 2005 assert(g1h->n_par_threads() == n_workers,
> 2006 "Should not have been reset");
> =>
> 2002 uint n_workers = _g1h->workers()->active_workers();
>
> Nice!
Thanks.
>
> ------------------------------------------------------------------------------
> src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp
> 44 assert(n_threads <= (uint)ParallelGCThreads, "# worker threads != # requested!");
>
> Pre-existing defect: The error message says "!=" but the test is "<=".
Changed to:
assert(n_threads <= (uint)ParallelGCThreads, "# worker threads < #
requested!");
>
> ------------------------------------------------------------------------------
> src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp
> 61 bool parallel = n_threads > 0;
>
> There's an assertion on line 43 that n_threads > 0.
You're right! I removed the 'parallel' parameter from process_stride.
>
> ------------------------------------------------------------------------------
> src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp
> 65 process_stride(sp, mr, stride, n_strides,
> 66 parallel,
> 67 cl, ct,
>
> Strange indentation of arguments.
I've removed the 'parallel' parameter.
>
> ------------------------------------------------------------------------------
> src/share/vm/gc_interface/collectedHeap.hpp
> 294 virtual void set_par_threads(uint t) { (void)t; };
>
> The "standard" way to ignore a parameter is to not name it, e.g.
>
> virtual void set_par_threads(uint /* t */) { }
OK. This code is removed in the next patch.
>
> Pre-existing defect: The trailing semi-colon isn't needed.
OK.
Thanks for reviewing!
StefanK
>
> ==============================================================================
>
More information about the hotspot-gc-dev
mailing list