Skip to content

Commit 855895f

Browse files
committed
8224660: Parallel GC: Use WorkGang (2: MarksFromRootsTask)
Reviewed-by: stefank, kbarrett, tschatzl
1 parent 3a38bec commit 855895f

File tree

5 files changed

+159
-203
lines changed

5 files changed

+159
-203
lines changed

src/hotspot/share/gc/parallel/pcTasks.cpp

Lines changed: 0 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -47,116 +47,6 @@
4747
#include "services/management.hpp"
4848
#include "utilities/stack.inline.hpp"
4949

50-
//
51-
// ThreadRootsMarkingTask
52-
//
53-
54-
void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) {
55-
assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
56-
57-
ResourceMark rm;
58-
59-
ParCompactionManager* cm =
60-
ParCompactionManager::gc_thread_compaction_manager(which);
61-
62-
PCMarkAndPushClosure mark_and_push_closure(cm);
63-
MarkingCodeBlobClosure mark_and_push_in_blobs(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);
64-
65-
_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
66-
67-
// Do the real work
68-
cm->follow_marking_stacks();
69-
}
70-
71-
72-
void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
73-
assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
74-
75-
ParCompactionManager* cm =
76-
ParCompactionManager::gc_thread_compaction_manager(which);
77-
PCMarkAndPushClosure mark_and_push_closure(cm);
78-
79-
switch (_root_type) {
80-
case universe:
81-
Universe::oops_do(&mark_and_push_closure);
82-
break;
83-
84-
case jni_handles:
85-
JNIHandles::oops_do(&mark_and_push_closure);
86-
break;
87-
88-
case threads:
89-
{
90-
ResourceMark rm;
91-
MarkingCodeBlobClosure each_active_code_blob(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);
92-
Threads::oops_do(&mark_and_push_closure, &each_active_code_blob);
93-
}
94-
break;
95-
96-
case object_synchronizer:
97-
ObjectSynchronizer::oops_do(&mark_and_push_closure);
98-
break;
99-
100-
case management:
101-
Management::oops_do(&mark_and_push_closure);
102-
break;
103-
104-
case jvmti:
105-
JvmtiExport::oops_do(&mark_and_push_closure);
106-
break;
107-
108-
case system_dictionary:
109-
SystemDictionary::oops_do(&mark_and_push_closure);
110-
break;
111-
112-
case class_loader_data: {
113-
CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong);
114-
ClassLoaderDataGraph::always_strong_cld_do(&cld_closure);
115-
}
116-
break;
117-
118-
case code_cache:
119-
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
120-
//ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure));
121-
AOTLoader::oops_do(&mark_and_push_closure);
122-
break;
123-
124-
default:
125-
fatal("Unknown root type");
126-
}
127-
128-
// Do the real work
129-
cm->follow_marking_stacks();
130-
}
131-
132-
133-
//
134-
// StealMarkingTask
135-
//
136-
137-
StealMarkingTask::StealMarkingTask(ParallelTaskTerminator* t) :
138-
_terminator(t) {}
139-
140-
void StealMarkingTask::do_it(GCTaskManager* manager, uint which) {
141-
assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
142-
143-
ParCompactionManager* cm =
144-
ParCompactionManager::gc_thread_compaction_manager(which);
145-
146-
oop obj = NULL;
147-
ObjArrayTask task;
148-
do {
149-
while (ParCompactionManager::steal_objarray(which, task)) {
150-
cm->follow_array((objArrayOop)task.obj(), task.index());
151-
cm->follow_marking_stacks();
152-
}
153-
while (ParCompactionManager::steal(which, obj)) {
154-
cm->follow_contents(obj);
155-
cm->follow_marking_stacks();
156-
}
157-
} while (!terminator()->offer_termination());
158-
}
159-
16050
//
16151
// CompactionWithStealingTask
16252
//

src/hotspot/share/gc/parallel/pcTasks.hpp

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -66,72 +66,6 @@
6666

6767
class ParallelTaskTerminator;
6868

69-
class ThreadRootsMarkingTask : public GCTask {
70-
private:
71-
Thread* _thread;
72-
73-
public:
74-
ThreadRootsMarkingTask(Thread* root) : _thread(root) {}
75-
76-
char* name() { return (char *)"thread-roots-marking-task"; }
77-
78-
virtual void do_it(GCTaskManager* manager, uint which);
79-
};
80-
81-
82-
//
83-
// MarkFromRootsTask
84-
//
85-
// This task marks from all the roots to all live
86-
// objects.
87-
//
88-
//
89-
90-
class MarkFromRootsTask : public GCTask {
91-
public:
92-
enum RootType {
93-
universe = 1,
94-
jni_handles = 2,
95-
threads = 3,
96-
object_synchronizer = 4,
97-
management = 5,
98-
jvmti = 6,
99-
system_dictionary = 7,
100-
class_loader_data = 8,
101-
code_cache = 9
102-
};
103-
private:
104-
RootType _root_type;
105-
public:
106-
MarkFromRootsTask(RootType value) : _root_type(value) {}
107-
108-
char* name() { return (char *)"mark-from-roots-task"; }
109-
110-
virtual void do_it(GCTaskManager* manager, uint which);
111-
};
112-
113-
114-
//
115-
// StealMarkingTask
116-
//
117-
// This task is used to distribute work to idle threads.
118-
//
119-
120-
class StealMarkingTask : public GCTask {
121-
private:
122-
ParallelTaskTerminator* const _terminator;
123-
private:
124-
125-
public:
126-
char* name() { return (char *)"steal-marking-task"; }
127-
128-
StealMarkingTask(ParallelTaskTerminator* t);
129-
130-
ParallelTaskTerminator* terminator() { return _terminator; }
131-
132-
virtual void do_it(GCTaskManager* manager, uint which);
133-
};
134-
13569
//
13670
// CompactionWithStealingTask
13771
//

src/hotspot/share/gc/parallel/psCompactionManager.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class ParCompactionManager : public CHeapObj<mtGC> {
4545
friend class RefProcTaskExecutor;
4646
friend class IdleGCTask;
4747
friend class PCRefProcTask;
48+
friend class MarkFromRootsTask;
4849

4950
public:
5051

src/hotspot/share/gc/parallel/psParallelCompact.cpp

Lines changed: 108 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "gc/parallel/psOldGen.hpp"
4141
#include "gc/parallel/psParallelCompact.inline.hpp"
4242
#include "gc/parallel/psPromotionManager.inline.hpp"
43+
#include "gc/parallel/psRootType.hpp"
4344
#include "gc/parallel/psScavenge.hpp"
4445
#include "gc/parallel/psYoungGen.hpp"
4546
#include "gc/shared/gcCause.hpp"
@@ -56,6 +57,7 @@
5657
#include "gc/shared/spaceDecorator.hpp"
5758
#include "gc/shared/weakProcessor.hpp"
5859
#include "gc/shared/workerPolicy.hpp"
60+
#include "gc/shared/workgroup.hpp"
5961
#include "logging/log.hpp"
6062
#include "memory/iterator.inline.hpp"
6163
#include "memory/resourceArea.hpp"
@@ -2087,15 +2089,82 @@ GCTaskManager* const PSParallelCompact::gc_task_manager() {
20872089

20882090
class PCAddThreadRootsMarkingTaskClosure : public ThreadClosure {
20892091
private:
2090-
GCTaskQueue* _q;
2092+
uint _worker_id;
20912093

20922094
public:
2093-
PCAddThreadRootsMarkingTaskClosure(GCTaskQueue* q) : _q(q) { }
2094-
void do_thread(Thread* t) {
2095-
_q->enqueue(new ThreadRootsMarkingTask(t));
2095+
PCAddThreadRootsMarkingTaskClosure(uint worker_id) : _worker_id(worker_id) { }
2096+
void do_thread(Thread* thread) {
2097+
assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
2098+
2099+
ResourceMark rm;
2100+
2101+
ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(_worker_id);
2102+
2103+
PCMarkAndPushClosure mark_and_push_closure(cm);
2104+
MarkingCodeBlobClosure mark_and_push_in_blobs(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);
2105+
2106+
thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
2107+
2108+
// Do the real work
2109+
cm->follow_marking_stacks();
20962110
}
20972111
};
20982112

2113+
static void mark_from_roots_work(ParallelRootType::Value root_type, uint worker_id) {
2114+
assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
2115+
2116+
ParCompactionManager* cm =
2117+
ParCompactionManager::gc_thread_compaction_manager(worker_id);
2118+
PCMarkAndPushClosure mark_and_push_closure(cm);
2119+
2120+
switch (root_type) {
2121+
case ParallelRootType::universe:
2122+
Universe::oops_do(&mark_and_push_closure);
2123+
break;
2124+
2125+
case ParallelRootType::jni_handles:
2126+
JNIHandles::oops_do(&mark_and_push_closure);
2127+
break;
2128+
2129+
case ParallelRootType::object_synchronizer:
2130+
ObjectSynchronizer::oops_do(&mark_and_push_closure);
2131+
break;
2132+
2133+
case ParallelRootType::management:
2134+
Management::oops_do(&mark_and_push_closure);
2135+
break;
2136+
2137+
case ParallelRootType::jvmti:
2138+
JvmtiExport::oops_do(&mark_and_push_closure);
2139+
break;
2140+
2141+
case ParallelRootType::system_dictionary:
2142+
SystemDictionary::oops_do(&mark_and_push_closure);
2143+
break;
2144+
2145+
case ParallelRootType::class_loader_data:
2146+
{
2147+
CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong);
2148+
ClassLoaderDataGraph::always_strong_cld_do(&cld_closure);
2149+
}
2150+
break;
2151+
2152+
case ParallelRootType::code_cache:
2153+
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
2154+
//ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure));
2155+
AOTLoader::oops_do(&mark_and_push_closure);
2156+
break;
2157+
2158+
case ParallelRootType::sentinel:
2159+
DEBUG_ONLY(default:) // DEBUG_ONLY hack will create compile error on release builds (-Wswitch) and runtime check on debug builds
2160+
fatal("Bad enumeration value: %u", root_type);
2161+
break;
2162+
}
2163+
2164+
// Do the real work
2165+
cm->follow_marking_stacks();
2166+
}
2167+
20992168
static void steal_marking_work(ParallelTaskTerminator& terminator, uint worker_id) {
21002169
assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
21012170

@@ -2116,6 +2185,39 @@ static void steal_marking_work(ParallelTaskTerminator& terminator, uint worker_i
21162185
} while (!terminator.offer_termination());
21172186
}
21182187

2188+
class MarkFromRootsTask : public AbstractGangTask {
2189+
typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
2190+
StrongRootsScope _strong_roots_scope; // needed for Threads::possibly_parallel_threads_do
2191+
SequentialSubTasksDone _subtasks;
2192+
TaskTerminator _terminator;
2193+
uint _active_workers;
2194+
2195+
public:
2196+
MarkFromRootsTask(uint active_workers) :
2197+
AbstractGangTask("MarkFromRootsTask"),
2198+
_strong_roots_scope(active_workers),
2199+
_subtasks(),
2200+
_terminator(active_workers, ParCompactionManager::stack_array()),
2201+
_active_workers(active_workers) {
2202+
_subtasks.set_n_threads(active_workers);
2203+
_subtasks.set_n_tasks(ParallelRootType::sentinel);
2204+
}
2205+
2206+
virtual void work(uint worker_id) {
2207+
for (uint task = 0; _subtasks.try_claim_task(task); /*empty*/ ) {
2208+
mark_from_roots_work(static_cast<ParallelRootType::Value>(task), worker_id);
2209+
}
2210+
_subtasks.all_tasks_completed();
2211+
2212+
PCAddThreadRootsMarkingTaskClosure closure(worker_id);
2213+
Threads::possibly_parallel_threads_do(true /*parallel */, &closure);
2214+
2215+
if (_active_workers > 1) {
2216+
steal_marking_work(*_terminator.terminator(), worker_id);
2217+
}
2218+
}
2219+
};
2220+
21192221
class PCRefProcTask : public AbstractGangTask {
21202222
typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
21212223
ProcessTask& _task;
@@ -2177,29 +2279,8 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
21772279
{
21782280
GCTraceTime(Debug, gc, phases) tm("Par Mark", &_gc_timer);
21792281

2180-
ParallelScavengeHeap::ParStrongRootsScope psrs;
2181-
2182-
GCTaskQueue* q = GCTaskQueue::create();
2183-
2184-
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::universe));
2185-
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jni_handles));
2186-
// We scan the thread roots in parallel
2187-
PCAddThreadRootsMarkingTaskClosure cl(q);
2188-
Threads::java_threads_and_vm_thread_do(&cl);
2189-
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::object_synchronizer));
2190-
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
2191-
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
2192-
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::class_loader_data));
2193-
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
2194-
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
2195-
2196-
if (active_gc_threads > 1) {
2197-
for (uint j = 0; j < active_gc_threads; j++) {
2198-
q->enqueue(new StealMarkingTask(terminator.terminator()));
2199-
}
2200-
}
2201-
2202-
gc_task_manager()->execute_and_wait(q);
2282+
MarkFromRootsTask task(active_gc_threads);
2283+
ParallelScavengeHeap::heap()->workers().run_task(&task);
22032284
}
22042285

22052286
// Process reference objects found during marking

0 commit comments

Comments
 (0)