157 TaskTerminator* _terminator;
158
159 public:
160 ShenandoahConcurrentMarkingTask(ShenandoahConcurrentMark* cm, TaskTerminator* terminator) :
161 AbstractGangTask("Root Region Scan"), _cm(cm), _terminator(terminator) {
162 }
163
164 void work(uint worker_id) {
165 ShenandoahHeap* heap = ShenandoahHeap::heap();
166 ShenandoahConcurrentWorkerSession worker_session(worker_id);
167 ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
168 ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id);
169 ReferenceProcessor* rp;
170 if (heap->process_references()) {
171 rp = heap->ref_processor();
172 shenandoah_assert_rp_isalive_installed();
173 } else {
174 rp = NULL;
175 }
176
177 _cm->concurrent_scan_code_roots(worker_id, rp);
178 _cm->mark_loop(worker_id, _terminator, rp,
179 true, // cancellable
180 ShenandoahStringDedup::is_enabled()); // perform string dedup
181 }
182 };
183
184 class ShenandoahSATBAndRemarkCodeRootsThreadsClosure : public ThreadClosure {
185 private:
186 ShenandoahSATBBufferClosure* _satb_cl;
187 OopClosure* const _cl;
188 MarkingCodeBlobClosure* _code_cl;
189 uintx _claim_token;
190
191 public:
192 ShenandoahSATBAndRemarkCodeRootsThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, OopClosure* cl, MarkingCodeBlobClosure* code_cl) :
193 _satb_cl(satb_cl), _cl(cl), _code_cl(code_cl),
194 _claim_token(Threads::thread_claim_token()) {}
195
196 void do_thread(Thread* thread) {
197 if (thread->claim_threads_do(true, _claim_token)) {
250 SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
251 while (satb_mq_set.apply_closure_to_completed_buffer(&cl));
252 bool do_nmethods = heap->unload_classes() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading();
253 if (heap->has_forwarded_objects()) {
254 ShenandoahMarkResolveRefsClosure resolve_mark_cl(q, rp);
255 MarkingCodeBlobClosure blobsCl(&resolve_mark_cl, !CodeBlobToOopClosure::FixRelocations);
256 ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl,
257 ShenandoahStoreValEnqueueBarrier ? &resolve_mark_cl : NULL,
258 do_nmethods ? &blobsCl : NULL);
259 Threads::threads_do(&tc);
260 } else {
261 ShenandoahMarkRefsClosure mark_cl(q, rp);
262 MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations);
263 ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl,
264 ShenandoahStoreValEnqueueBarrier ? &mark_cl : NULL,
265 do_nmethods ? &blobsCl : NULL);
266 Threads::threads_do(&tc);
267 }
268 }
269
270 if (heap->is_degenerated_gc_in_progress()) {
271 // Degenerated cycle may bypass concurrent cycle, so code roots might not be scanned,
272 // let's check here.
273 _cm->concurrent_scan_code_roots(worker_id, rp);
274 }
275
276 _cm->mark_loop(worker_id, _terminator, rp,
277 false, // not cancellable
278 _dedup_string);
279
280 assert(_cm->task_queues()->is_empty(), "Should be empty");
281 }
282 };
283
284 void ShenandoahConcurrentMark::mark_roots(ShenandoahPhaseTimings::Phase root_phase) {
285 assert(Thread::current()->is_VM_thread(), "can only do this in VMThread");
286 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
287
288 ShenandoahHeap* heap = ShenandoahHeap::heap();
289
290 ShenandoahGCPhase phase(root_phase);
|
157 TaskTerminator* _terminator;
158
159 public:
160 ShenandoahConcurrentMarkingTask(ShenandoahConcurrentMark* cm, TaskTerminator* terminator) :
161 AbstractGangTask("Root Region Scan"), _cm(cm), _terminator(terminator) {
162 }
163
164 void work(uint worker_id) {
165 ShenandoahHeap* heap = ShenandoahHeap::heap();
166 ShenandoahConcurrentWorkerSession worker_session(worker_id);
167 ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
168 ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id);
169 ReferenceProcessor* rp;
170 if (heap->process_references()) {
171 rp = heap->ref_processor();
172 shenandoah_assert_rp_isalive_installed();
173 } else {
174 rp = NULL;
175 }
176
177 if (!heap->unload_classes()) {
178 _cm->concurrent_scan_code_roots(worker_id, rp);
179 }
180
181 _cm->mark_loop(worker_id, _terminator, rp,
182 true, // cancellable
183 ShenandoahStringDedup::is_enabled()); // perform string dedup
184 }
185 };
186
187 class ShenandoahSATBAndRemarkCodeRootsThreadsClosure : public ThreadClosure {
188 private:
189 ShenandoahSATBBufferClosure* _satb_cl;
190 OopClosure* const _cl;
191 MarkingCodeBlobClosure* _code_cl;
192 uintx _claim_token;
193
194 public:
195 ShenandoahSATBAndRemarkCodeRootsThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, OopClosure* cl, MarkingCodeBlobClosure* code_cl) :
196 _satb_cl(satb_cl), _cl(cl), _code_cl(code_cl),
197 _claim_token(Threads::thread_claim_token()) {}
198
199 void do_thread(Thread* thread) {
200 if (thread->claim_threads_do(true, _claim_token)) {
253 SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
254 while (satb_mq_set.apply_closure_to_completed_buffer(&cl));
255 bool do_nmethods = heap->unload_classes() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading();
256 if (heap->has_forwarded_objects()) {
257 ShenandoahMarkResolveRefsClosure resolve_mark_cl(q, rp);
258 MarkingCodeBlobClosure blobsCl(&resolve_mark_cl, !CodeBlobToOopClosure::FixRelocations);
259 ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl,
260 ShenandoahStoreValEnqueueBarrier ? &resolve_mark_cl : NULL,
261 do_nmethods ? &blobsCl : NULL);
262 Threads::threads_do(&tc);
263 } else {
264 ShenandoahMarkRefsClosure mark_cl(q, rp);
265 MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations);
266 ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl,
267 ShenandoahStoreValEnqueueBarrier ? &mark_cl : NULL,
268 do_nmethods ? &blobsCl : NULL);
269 Threads::threads_do(&tc);
270 }
271 }
272
273 if (heap->is_degenerated_gc_in_progress() &&
274 !heap->unload_classes()) {
275 // Degenerated cycle may bypass concurrent cycle, so code roots might not be scanned,
276 // let's check here.
277 _cm->concurrent_scan_code_roots(worker_id, rp);
278 }
279
280 _cm->mark_loop(worker_id, _terminator, rp,
281 false, // not cancellable
282 _dedup_string);
283
284 assert(_cm->task_queues()->is_empty(), "Should be empty");
285 }
286 };
287
288 void ShenandoahConcurrentMark::mark_roots(ShenandoahPhaseTimings::Phase root_phase) {
289 assert(Thread::current()->is_VM_thread(), "can only do this in VMThread");
290 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
291
292 ShenandoahHeap* heap = ShenandoahHeap::heap();
293
294 ShenandoahGCPhase phase(root_phase);
|