40
40
#include " gc/parallel/psOldGen.hpp"
41
41
#include " gc/parallel/psParallelCompact.inline.hpp"
42
42
#include " gc/parallel/psPromotionManager.inline.hpp"
43
+ #include " gc/parallel/psRootType.hpp"
43
44
#include " gc/parallel/psScavenge.hpp"
44
45
#include " gc/parallel/psYoungGen.hpp"
45
46
#include " gc/shared/gcCause.hpp"
56
57
#include " gc/shared/spaceDecorator.hpp"
57
58
#include " gc/shared/weakProcessor.hpp"
58
59
#include " gc/shared/workerPolicy.hpp"
60
+ #include " gc/shared/workgroup.hpp"
59
61
#include " logging/log.hpp"
60
62
#include " memory/iterator.inline.hpp"
61
63
#include " memory/resourceArea.hpp"
@@ -2087,15 +2089,82 @@ GCTaskManager* const PSParallelCompact::gc_task_manager() {
2087
2089
2088
2090
class PCAddThreadRootsMarkingTaskClosure : public ThreadClosure {
2089
2091
private:
2090
- GCTaskQueue* _q ;
2092
+ uint _worker_id ;
2091
2093
2092
2094
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 ();
2096
2110
}
2097
2111
};
2098
2112
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
+
2099
2168
static void steal_marking_work (ParallelTaskTerminator& terminator, uint worker_id) {
2100
2169
assert (ParallelScavengeHeap::heap ()->is_gc_active (), " called outside gc" );
2101
2170
@@ -2116,6 +2185,39 @@ static void steal_marking_work(ParallelTaskTerminator& terminator, uint worker_i
2116
2185
} while (!terminator.offer_termination ());
2117
2186
}
2118
2187
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
+
2119
2221
class PCRefProcTask : public AbstractGangTask {
2120
2222
typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
2121
2223
ProcessTask& _task;
@@ -2177,29 +2279,8 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
2177
2279
{
2178
2280
GCTraceTime (Debug, gc, phases) tm (" Par Mark" , &_gc_timer);
2179
2281
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);
2203
2284
}
2204
2285
2205
2286
// Process reference objects found during marking
0 commit comments