423 } else {
424 ShenandoahTraversalMetadataClosure cl(q, rp);
425 main_loop_work<ShenandoahTraversalMetadataClosure, DO_SATB>(&cl, ld, w, t);
426 }
427 } else {
428 if (ShenandoahStringDedup::is_enabled()) {
429 ShenandoahStrDedupQueue* dq = ShenandoahStringDedup::queue(w);
430 ShenandoahTraversalDedupClosure cl(q, rp, dq);
431 main_loop_work<ShenandoahTraversalDedupClosure, DO_SATB>(&cl, ld, w, t);
432 } else {
433 ShenandoahTraversalClosure cl(q, rp);
434 main_loop_work<ShenandoahTraversalClosure, DO_SATB>(&cl, ld, w, t);
435 }
436 }
437 }
438
439 template <class T, bool DO_SATB>
440 void ShenandoahTraversalGC::main_loop_work(T* cl, jushort* live_data, uint worker_id, ParallelTaskTerminator* terminator) {
441 ShenandoahObjToScanQueueSet* queues = task_queues();
442 ShenandoahObjToScanQueue* q = queues->queue(worker_id);
443
444 uintx stride = ShenandoahMarkLoopStride;
445
446 ShenandoahMarkTask task;
447
448 // Process outstanding queues, if any.
449 q = queues->claim_next();
450 while (q != NULL) {
451 if (_heap->check_cancelled_concgc_and_yield()) {
452 ShenandoahCancelledTerminatorTerminator tt;
453 while (!terminator->offer_termination(&tt));
454 return;
455 }
456
457 for (uint i = 0; i < stride; i++) {
458 if (q->pop_buffer(task) ||
459 q->pop_local(task) ||
460 q->pop_overflow(task)) {
461 do_task(q, cl, live_data, &task);
462 } else {
463 assert(q->is_empty(), "Must be empty");
464 q = queues->claim_next();
465 break;
466 }
467 }
468 }
469 // Normal loop.
470 q = queues->queue(worker_id);
471 ShenandoahTraversalSATBBufferClosure satb_cl(q);
472 SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
473
474 int seed = 17;
475
476 while (true) {
477 if (check_and_handle_cancelled_gc(terminator)) return;
478
479 for (uint i = 0; i < stride; i++) {
480 if ((q->pop_buffer(task) ||
481 q->pop_local(task) ||
482 q->pop_overflow(task) ||
483 (DO_SATB && satb_mq_set.apply_closure_to_completed_buffer(&satb_cl) && q->pop_buffer(task)) ||
484 queues->steal(worker_id, &seed, task))) {
485 do_task(q, cl, live_data, &task);
486 } else {
487 if (terminator->offer_termination()) return;
488 }
489 }
490 }
491 }
492
493 bool ShenandoahTraversalGC::check_and_handle_cancelled_gc(ParallelTaskTerminator* terminator) {
494 if (_heap->cancelled_concgc()) {
495 ShenandoahCancelledTerminatorTerminator tt;
496 while (! terminator->offer_termination(&tt));
497 return true;
498 }
499 return false;
500 }
501
502 void ShenandoahTraversalGC::concurrent_traversal_collection() {
503 ClassLoaderDataGraph::clear_claimed_marks();
504
505 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::conc_traversal);
|
423 } else {
424 ShenandoahTraversalMetadataClosure cl(q, rp);
425 main_loop_work<ShenandoahTraversalMetadataClosure, DO_SATB>(&cl, ld, w, t);
426 }
427 } else {
428 if (ShenandoahStringDedup::is_enabled()) {
429 ShenandoahStrDedupQueue* dq = ShenandoahStringDedup::queue(w);
430 ShenandoahTraversalDedupClosure cl(q, rp, dq);
431 main_loop_work<ShenandoahTraversalDedupClosure, DO_SATB>(&cl, ld, w, t);
432 } else {
433 ShenandoahTraversalClosure cl(q, rp);
434 main_loop_work<ShenandoahTraversalClosure, DO_SATB>(&cl, ld, w, t);
435 }
436 }
437 }
438
439 template <class T, bool DO_SATB>
440 void ShenandoahTraversalGC::main_loop_work(T* cl, jushort* live_data, uint worker_id, ParallelTaskTerminator* terminator) {
441 ShenandoahObjToScanQueueSet* queues = task_queues();
442 ShenandoahObjToScanQueue* q = queues->queue(worker_id);
443 ShenandoahConcurrentMark* conc_mark = _heap->concurrentMark();
444
445 uintx stride = ShenandoahMarkLoopStride;
446
447 ShenandoahMarkTask task;
448
449 // Process outstanding queues, if any.
450 q = queues->claim_next();
451 while (q != NULL) {
452 if (_heap->check_cancelled_concgc_and_yield()) {
453 ShenandoahCancelledTerminatorTerminator tt;
454 while (!terminator->offer_termination(&tt));
455 return;
456 }
457
458 for (uint i = 0; i < stride; i++) {
459 if (q->pop_buffer(task) ||
460 q->pop_local(task) ||
461 q->pop_overflow(task)) {
462 conc_mark->do_task<T, true>(q, cl, live_data, &task);
463 } else {
464 assert(q->is_empty(), "Must be empty");
465 q = queues->claim_next();
466 break;
467 }
468 }
469 }
470 // Normal loop.
471 q = queues->queue(worker_id);
472 ShenandoahTraversalSATBBufferClosure satb_cl(q);
473 SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
474
475 int seed = 17;
476
477 while (true) {
478 if (check_and_handle_cancelled_gc(terminator)) return;
479
480 for (uint i = 0; i < stride; i++) {
481 if ((q->pop_buffer(task) ||
482 q->pop_local(task) ||
483 q->pop_overflow(task) ||
484 (DO_SATB && satb_mq_set.apply_closure_to_completed_buffer(&satb_cl) && q->pop_buffer(task)) ||
485 queues->steal(worker_id, &seed, task))) {
486 conc_mark->do_task<T, true>(q, cl, live_data, &task);
487 } else {
488 if (terminator->offer_termination()) return;
489 }
490 }
491 }
492 }
493
494 bool ShenandoahTraversalGC::check_and_handle_cancelled_gc(ParallelTaskTerminator* terminator) {
495 if (_heap->cancelled_concgc()) {
496 ShenandoahCancelledTerminatorTerminator tt;
497 while (! terminator->offer_termination(&tt));
498 return true;
499 }
500 return false;
501 }
502
503 void ShenandoahTraversalGC::concurrent_traversal_collection() {
504 ClassLoaderDataGraph::clear_claimed_marks();
505
506 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::conc_traversal);
|