1 /*
   2  * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #include "precompiled.hpp"
  25 
  26 #include "classfile/classLoaderData.hpp"
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "gc/shared/referenceProcessor.hpp"
  29 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
  30 #include "gc/shared/workgroup.hpp"
  31 #include "gc/shared/weakProcessor.inline.hpp"
  32 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  33 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
  34 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
  35 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
  36 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  37 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  38 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  39 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  40 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
  41 #include "gc/shenandoah/shenandoahHeuristics.hpp"
  42 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  43 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
  44 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
  45 #include "gc/shenandoah/shenandoahStringDedup.hpp"
  46 #include "gc/shenandoah/shenandoahTaskqueue.inline.hpp"
  47 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
  48 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
  49 #include "gc/shenandoah/shenandoahUtils.hpp"
  50 #include "gc/shenandoah/shenandoahVerifier.hpp"
  51 
  52 #include "memory/iterator.hpp"
  53 #include "memory/metaspace.hpp"
  54 #include "memory/resourceArea.hpp"
  55 #include "memory/universe.hpp"
  56 
  57 /**
  58  * NOTE: We are using the SATB buffer in thread.hpp and satbMarkQueue.hpp, however, it is not an SATB algorithm.
  59  * We're using the buffer as generic oop buffer to enqueue new values in concurrent oop stores, IOW, the algorithm
  60  * is incremental-update-based.
  61  *
  62  * NOTE on interaction with TAMS: we want to avoid traversing new objects for
  63  * several reasons:
  64  * - We will not reclaim them in this cycle anyway, because they are not in the
  65  *   cset
  66  * - It makes up for the bulk of work during final-pause
  67  * - It also shortens the concurrent cycle because we don't need to
  68  *   pointlessly traverse through newly allocated objects.
  69  * - As a nice side-effect, it solves the I-U termination problem (mutators
  70  *   cannot outrun the GC by allocating like crazy)
  71  * - It is an easy way to achieve MWF. What MWF does is to also enqueue the
  72  *   target object of stores if it's new. Treating new objects live implicitely
  73  *   achieves the same, but without extra barriers. I think the effect of
  74  *   shortened final-pause (mentioned above) is the main advantage of MWF. In
  75  *   particular, we will not see the head of a completely new long linked list
  76  *   in final-pause and end up traversing huge chunks of the heap there.
  77  * - We don't need to see/update the fields of new objects either, because they
  78  *   are either still null, or anything that's been stored into them has been
  79  *   evacuated+enqueued before (and will thus be treated later).
  80  *
  81  * We achieve this by setting TAMS for each region, and everything allocated
  82  * beyond TAMS will be 'implicitely marked'.
  83  *
  84  * Gotchas:
  85  * - While we want new objects to be implicitely marked, we don't want to count
  86  *   them alive. Otherwise the next cycle wouldn't pick them up and consider
  87  *   them for cset. This means that we need to protect such regions from
  88  *   getting accidentally thrashed at the end of traversal cycle. This is why I
  89  *   keep track of alloc-regions and check is_alloc_region() in the trashing
  90  *   code.
  91  * - We *need* to traverse through evacuated objects. Those objects are
  92  *   pre-existing, and any references in them point to interesting objects that
  93  *   we need to see. We also want to count them as live, because we just
  94  *   determined that they are alive :-) I achieve this by upping TAMS
  95  *   concurrently for every gclab/gc-shared alloc before publishing the
  96  *   evacuated object. This way, the GC threads will not consider such objects
  97  *   implictely marked, and traverse through them as normal.
  98  */
  99 class ShenandoahTraversalSATBBufferClosure : public SATBBufferClosure {
 100 private:
 101   ShenandoahObjToScanQueue* _queue;
 102   ShenandoahTraversalGC* _traversal_gc;
 103   ShenandoahHeap* const _heap;
 104 
 105 public:
 106   ShenandoahTraversalSATBBufferClosure(ShenandoahObjToScanQueue* q) :
 107     _queue(q),
 108     _heap(ShenandoahHeap::heap())
 109  { }
 110 
 111   void do_buffer(void** buffer, size_t size) {
 112     for (size_t i = 0; i < size; ++i) {
 113       oop* p = (oop*) &buffer[i];
 114       oop obj = RawAccess<>::oop_load(p);
 115       shenandoah_assert_not_forwarded(p, obj);
 116       if (_heap->marking_context()->mark(obj)) {
 117         _queue->push(ShenandoahMarkTask(obj));
 118       }
 119     }
 120   }
 121 };
 122 
 123 class ShenandoahTraversalSATBThreadsClosure : public ThreadClosure {
 124 private:
 125   ShenandoahTraversalSATBBufferClosure* _satb_cl;
 126 
 127 public:
 128   ShenandoahTraversalSATBThreadsClosure(ShenandoahTraversalSATBBufferClosure* satb_cl) :
 129     _satb_cl(satb_cl) {}
 130 
 131   void do_thread(Thread* thread) {
 132     ShenandoahThreadLocalData::satb_mark_queue(thread).apply_closure_and_empty(_satb_cl);
 133   }
 134 };
 135 
 136 // Like CLDToOopClosure, but clears has_modified_oops, so that we can record modified CLDs during traversal
 137 // and remark them later during final-traversal.
 138 class ShenandoahMarkCLDClosure : public CLDClosure {
 139 private:
 140   OopClosure* _cl;
 141 public:
 142   ShenandoahMarkCLDClosure(OopClosure* cl) : _cl(cl) {}
 143   void do_cld(ClassLoaderData* cld) {
 144     cld->oops_do(_cl, true, true);
 145   }
 146 };
 147 
 148 // Like CLDToOopClosure, but only process modified CLDs
 149 class ShenandoahRemarkCLDClosure : public CLDClosure {
 150 private:
 151   OopClosure* _cl;
 152 public:
 153   ShenandoahRemarkCLDClosure(OopClosure* cl) : _cl(cl) {}
 154   void do_cld(ClassLoaderData* cld) {
 155     if (cld->has_modified_oops()) {
 156       cld->oops_do(_cl, true, true);
 157     }
 158   }
 159 };
 160 
 161 class ShenandoahInitTraversalCollectionTask : public AbstractGangTask {
 162 private:
 163   ShenandoahCSetRootScanner* _rp;
 164   ShenandoahHeap* _heap;
 165   ShenandoahCsetCodeRootsIterator* _cset_coderoots;
 166   ShenandoahStringDedupRoots       _dedup_roots;
 167 
 168 public:
 169   ShenandoahInitTraversalCollectionTask(ShenandoahCSetRootScanner* rp) :
 170     AbstractGangTask("Shenandoah Init Traversal Collection"),
 171     _rp(rp),
 172     _heap(ShenandoahHeap::heap()) {}
 173 
 174   void work(uint worker_id) {
 175     ShenandoahParallelWorkerSession worker_session(worker_id);
 176 
 177     ShenandoahEvacOOMScope oom_evac_scope;
 178     ShenandoahObjToScanQueueSet* queues = _heap->traversal_gc()->task_queues();
 179     ShenandoahObjToScanQueue* q = queues->queue(worker_id);
 180 
 181     bool process_refs = _heap->process_references();
 182     bool unload_classes = _heap->unload_classes();
 183     ReferenceProcessor* rp = NULL;
 184     if (process_refs) {
 185       rp = _heap->ref_processor();
 186     }
 187 
 188     // Step 1: Process ordinary GC roots.
 189     {
 190       ShenandoahTraversalClosure roots_cl(q, rp);
 191       ShenandoahMarkCLDClosure cld_cl(&roots_cl);
 192       MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations);
 193       if (unload_classes) {
 194         _rp->roots_do(worker_id, &roots_cl, NULL, &code_cl);
 195       } else {
 196         _rp->roots_do(worker_id, &roots_cl, &cld_cl, &code_cl);
 197       }
 198 
 199       AlwaysTrueClosure is_alive;
 200       _dedup_roots.oops_do(&is_alive, &roots_cl, worker_id);
 201     }
 202   }
 203 };
 204 
 205 class ShenandoahConcurrentTraversalCollectionTask : public AbstractGangTask {
 206 private:
 207   ShenandoahTaskTerminator* _terminator;
 208   ShenandoahHeap* _heap;
 209 public:
 210   ShenandoahConcurrentTraversalCollectionTask(ShenandoahTaskTerminator* terminator) :
 211     AbstractGangTask("Shenandoah Concurrent Traversal Collection"),
 212     _terminator(terminator),
 213     _heap(ShenandoahHeap::heap()) {}
 214 
 215   void work(uint worker_id) {
 216     ShenandoahConcurrentWorkerSession worker_session(worker_id);
 217     ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
 218     ShenandoahEvacOOMScope oom_evac_scope;
 219     ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc();
 220 
 221     // Drain all outstanding work in queues.
 222     traversal_gc->main_loop(worker_id, _terminator, true);
 223   }
 224 };
 225 
 226 class ShenandoahFinalTraversalCollectionTask : public AbstractGangTask {
 227 private:
 228   ShenandoahAllRootScanner* _rp;
 229   ShenandoahTaskTerminator* _terminator;
 230   ShenandoahHeap* _heap;
 231 public:
 232   ShenandoahFinalTraversalCollectionTask(ShenandoahAllRootScanner* rp, ShenandoahTaskTerminator* terminator) :
 233     AbstractGangTask("Shenandoah Final Traversal Collection"),
 234     _rp(rp),
 235     _terminator(terminator),
 236     _heap(ShenandoahHeap::heap()) {}
 237 
 238   void work(uint worker_id) {
 239     ShenandoahParallelWorkerSession worker_session(worker_id);
 240 
 241     ShenandoahEvacOOMScope oom_evac_scope;
 242     ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc();
 243 
 244     ShenandoahObjToScanQueueSet* queues = traversal_gc->task_queues();
 245     ShenandoahObjToScanQueue* q = queues->queue(worker_id);
 246 
 247     bool process_refs = _heap->process_references();
 248     bool unload_classes = _heap->unload_classes();
 249     ReferenceProcessor* rp = NULL;
 250     if (process_refs) {
 251       rp = _heap->ref_processor();
 252     }
 253 
 254     // Step 0: Drain outstanding SATB queues.
 255     // NOTE: we piggy-back draining of remaining thread SATB buffers on the final root scan below.
 256     ShenandoahTraversalSATBBufferClosure satb_cl(q);
 257     {
 258       // Process remaining finished SATB buffers.
 259       SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
 260       while (satb_mq_set.apply_closure_to_completed_buffer(&satb_cl));
 261       // Process remaining threads SATB buffers below.
 262     }
 263 
 264     // Step 1: Process GC roots.
 265     // For oops in code roots, they are marked, evacuated, enqueued for further traversal,
 266     // and the references to the oops are updated during init pause. New nmethods are handled
 267     // in similar way during nmethod-register process. Therefore, we don't need to rescan code
 268     // roots here.
 269     if (!_heap->is_degenerated_gc_in_progress()) {
 270       ShenandoahTraversalClosure roots_cl(q, rp);
 271       ShenandoahTraversalSATBThreadsClosure tc(&satb_cl);
 272       if (unload_classes) {
 273         ShenandoahRemarkCLDClosure remark_cld_cl(&roots_cl);
 274         _rp->strong_roots_do(worker_id, &roots_cl, &remark_cld_cl, NULL, &tc);
 275       } else {
 276         CLDToOopClosure cld_cl(&roots_cl, ClassLoaderData::_claim_strong);
 277         _rp->roots_do(worker_id, &roots_cl, &cld_cl, NULL, &tc);
 278       }
 279     } else {
 280       ShenandoahTraversalDegenClosure roots_cl(q, rp);
 281       ShenandoahTraversalSATBThreadsClosure tc(&satb_cl);
 282       if (unload_classes) {
 283         ShenandoahRemarkCLDClosure remark_cld_cl(&roots_cl);
 284         _rp->strong_roots_do(worker_id, &roots_cl, &remark_cld_cl, NULL, &tc);
 285       } else {
 286         CLDToOopClosure cld_cl(&roots_cl, ClassLoaderData::_claim_strong);
 287         _rp->roots_do(worker_id, &roots_cl, &cld_cl, NULL, &tc);
 288       }
 289     }
 290 
 291     {
 292       ShenandoahWorkerTimings *worker_times = _heap->phase_timings()->worker_times();
 293       ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::FinishQueues, worker_id);
 294 
 295       // Step 3: Finally drain all outstanding work in queues.
 296       traversal_gc->main_loop(worker_id, _terminator, false);
 297     }
 298 
 299   }
 300 };
 301 
 302 ShenandoahTraversalGC::ShenandoahTraversalGC(ShenandoahHeap* heap, size_t num_regions) :
 303   _heap(heap),
 304   _task_queues(new ShenandoahObjToScanQueueSet(heap->max_workers())),
 305   _traversal_set(ShenandoahHeapRegionSet()) {
 306 
 307   // Traversal does not support concurrent code root scanning
 308   FLAG_SET_DEFAULT(ShenandoahConcurrentScanCodeRoots, false);
 309 
 310   uint num_queues = heap->max_workers();
 311   for (uint i = 0; i < num_queues; ++i) {
 312     ShenandoahObjToScanQueue* task_queue = new ShenandoahObjToScanQueue();
 313     task_queue->initialize();
 314     _task_queues->register_queue(i, task_queue);
 315   }
 316 }
 317 
 318 ShenandoahTraversalGC::~ShenandoahTraversalGC() {
 319 }
 320 
 321 void ShenandoahTraversalGC::prepare_regions() {
 322   size_t num_regions = _heap->num_regions();
 323   ShenandoahMarkingContext* const ctx = _heap->marking_context();
 324   for (size_t i = 0; i < num_regions; i++) {
 325     ShenandoahHeapRegion* region = _heap->get_region(i);
 326     if (_heap->is_bitmap_slice_committed(region)) {
 327       if (_traversal_set.is_in(i)) {
 328         ctx->capture_top_at_mark_start(region);
 329         region->clear_live_data();
 330         assert(ctx->is_bitmap_clear_range(region->bottom(), region->end()), "bitmap for traversal regions must be cleared");
 331       } else {
 332         // Everything outside the traversal set is always considered live.
 333         ctx->reset_top_at_mark_start(region);
 334       }
 335     } else {
 336       // FreeSet may contain uncommitted empty regions, once they are recommitted,
 337       // their TAMS may have old values, so reset them here.
 338       ctx->reset_top_at_mark_start(region);
 339     }
 340   }
 341 }
 342 
 343 void ShenandoahTraversalGC::prepare() {
 344   _heap->collection_set()->clear();
 345   assert(_heap->collection_set()->count() == 0, "collection set not clear");
 346 
 347   {
 348     ShenandoahGCPhase phase(ShenandoahPhaseTimings::traversal_gc_make_parsable);
 349     _heap->make_parsable(true);
 350   }
 351 
 352   if (UseTLAB) {
 353     ShenandoahGCPhase phase(ShenandoahPhaseTimings::traversal_gc_resize_tlabs);
 354     _heap->resize_tlabs();
 355   }
 356 
 357   assert(_heap->marking_context()->is_bitmap_clear(), "need clean mark bitmap");
 358   assert(!_heap->marking_context()->is_complete(), "should not be complete");
 359 
 360   ShenandoahFreeSet* free_set = _heap->free_set();
 361   ShenandoahCollectionSet* collection_set = _heap->collection_set();
 362 
 363   // Find collection set
 364   _heap->heuristics()->choose_collection_set(collection_set);
 365   prepare_regions();
 366 
 367   // Rebuild free set
 368   free_set->rebuild();
 369 
 370   log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "M, " SIZE_FORMAT "M CSet, " SIZE_FORMAT " CSet regions",
 371                      collection_set->garbage() / M, collection_set->live_data() / M, collection_set->count());
 372 }
 373 
 374 void ShenandoahTraversalGC::init_traversal_collection() {
 375   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "STW traversal GC");
 376 
 377   if (ShenandoahVerify) {
 378     _heap->verifier()->verify_before_traversal();
 379   }
 380 
 381   if (VerifyBeforeGC) {
 382     Universe::verify();
 383   }
 384 
 385   {
 386     ShenandoahGCPhase phase_prepare(ShenandoahPhaseTimings::traversal_gc_prepare);
 387     ShenandoahHeapLocker lock(_heap->lock());
 388     prepare();
 389   }
 390 
 391   _heap->set_concurrent_traversal_in_progress(true);
 392 
 393   bool process_refs = _heap->process_references();
 394   if (process_refs) {
 395     ReferenceProcessor* rp = _heap->ref_processor();
 396     rp->enable_discovery(true /*verify_no_refs*/);
 397     rp->setup_policy(_heap->soft_ref_policy()->should_clear_all_soft_refs());
 398   }
 399 
 400   {
 401     ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::init_traversal_gc_work);
 402     assert(_task_queues->is_empty(), "queues must be empty before traversal GC");
 403     TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
 404 
 405 #if defined(COMPILER2) || INCLUDE_JVMCI
 406     DerivedPointerTable::clear();
 407 #endif
 408 
 409     {
 410       uint nworkers = _heap->workers()->active_workers();
 411       task_queues()->reserve(nworkers);
 412       ShenandoahCSetRootScanner rp(nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
 413       ShenandoahInitTraversalCollectionTask traversal_task(&rp);
 414       _heap->workers()->run_task(&traversal_task);
 415     }
 416 
 417 #if defined(COMPILER2) || INCLUDE_JVMCI
 418     DerivedPointerTable::update_pointers();
 419 #endif
 420   }
 421 
 422   if (ShenandoahPacing) {
 423     _heap->pacer()->setup_for_traversal();
 424   }
 425 }
 426 
 427 void ShenandoahTraversalGC::main_loop(uint w, ShenandoahTaskTerminator* t, bool sts_yield) {
 428   ShenandoahObjToScanQueue* q = task_queues()->queue(w);
 429 
 430   // Initialize live data.
 431   jushort* ld = _heap->get_liveness_cache(w);
 432 
 433   ReferenceProcessor* rp = NULL;
 434   if (_heap->process_references()) {
 435     rp = _heap->ref_processor();
 436   }
 437   {
 438     if (!_heap->is_degenerated_gc_in_progress()) {
 439       if (_heap->unload_classes()) {
 440         if (ShenandoahStringDedup::is_enabled()) {
 441           ShenandoahTraversalMetadataDedupClosure cl(q, rp);
 442           main_loop_work<ShenandoahTraversalMetadataDedupClosure>(&cl, ld, w, t, sts_yield);
 443         } else {
 444           ShenandoahTraversalMetadataClosure cl(q, rp);
 445           main_loop_work<ShenandoahTraversalMetadataClosure>(&cl, ld, w, t, sts_yield);
 446         }
 447       } else {
 448         if (ShenandoahStringDedup::is_enabled()) {
 449           ShenandoahTraversalDedupClosure cl(q, rp);
 450           main_loop_work<ShenandoahTraversalDedupClosure>(&cl, ld, w, t, sts_yield);
 451         } else {
 452           ShenandoahTraversalClosure cl(q, rp);
 453           main_loop_work<ShenandoahTraversalClosure>(&cl, ld, w, t, sts_yield);
 454         }
 455       }
 456     } else {
 457       if (_heap->unload_classes()) {
 458         if (ShenandoahStringDedup::is_enabled()) {
 459           ShenandoahTraversalMetadataDedupDegenClosure cl(q, rp);
 460           main_loop_work<ShenandoahTraversalMetadataDedupDegenClosure>(&cl, ld, w, t, sts_yield);
 461         } else {
 462           ShenandoahTraversalMetadataDegenClosure cl(q, rp);
 463           main_loop_work<ShenandoahTraversalMetadataDegenClosure>(&cl, ld, w, t, sts_yield);
 464         }
 465       } else {
 466         if (ShenandoahStringDedup::is_enabled()) {
 467           ShenandoahTraversalDedupDegenClosure cl(q, rp);
 468           main_loop_work<ShenandoahTraversalDedupDegenClosure>(&cl, ld, w, t, sts_yield);
 469         } else {
 470           ShenandoahTraversalDegenClosure cl(q, rp);
 471           main_loop_work<ShenandoahTraversalDegenClosure>(&cl, ld, w, t, sts_yield);
 472         }
 473       }
 474     }
 475   }
 476 
 477   _heap->flush_liveness_cache(w);
 478 }
 479 
 480 template <class T>
 481 void ShenandoahTraversalGC::main_loop_work(T* cl, jushort* live_data, uint worker_id, ShenandoahTaskTerminator* terminator, bool sts_yield) {
 482   ShenandoahObjToScanQueueSet* queues = task_queues();
 483   ShenandoahObjToScanQueue* q = queues->queue(worker_id);
 484   ShenandoahConcurrentMark* conc_mark = _heap->concurrent_mark();
 485 
 486   uintx stride = ShenandoahMarkLoopStride;
 487 
 488   ShenandoahMarkTask task;
 489 
 490   // Process outstanding queues, if any.
 491   q = queues->claim_next();
 492   while (q != NULL) {
 493     if (_heap->check_cancelled_gc_and_yield(sts_yield)) {
 494       return;
 495     }
 496 
 497     for (uint i = 0; i < stride; i++) {
 498       if (q->pop(task)) {
 499         conc_mark->do_task<T>(q, cl, live_data, &task);
 500       } else {
 501         assert(q->is_empty(), "Must be empty");
 502         q = queues->claim_next();
 503         break;
 504       }
 505     }
 506   }
 507 
 508   if (check_and_handle_cancelled_gc(terminator, sts_yield)) return;
 509 
 510   // Normal loop.
 511   q = queues->queue(worker_id);
 512 
 513   ShenandoahTraversalSATBBufferClosure drain_satb(q);
 514   SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
 515 
 516   while (true) {
 517     if (check_and_handle_cancelled_gc(terminator, sts_yield)) return;
 518 
 519     while (satb_mq_set.completed_buffers_num() > 0) {
 520       satb_mq_set.apply_closure_to_completed_buffer(&drain_satb);
 521     }
 522 
 523     uint work = 0;
 524     for (uint i = 0; i < stride; i++) {
 525       if (q->pop(task) ||
 526           queues->steal(worker_id, task)) {
 527         conc_mark->do_task<T>(q, cl, live_data, &task);
 528         work++;
 529       } else {
 530         break;
 531       }
 532     }
 533 
 534     if (work == 0) {
 535       // No more work, try to terminate
 536       ShenandoahEvacOOMScopeLeaver oom_scope_leaver;
 537       ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield && ShenandoahSuspendibleWorkers);
 538       ShenandoahTerminationTimingsTracker term_tracker(worker_id);
 539       ShenandoahTerminatorTerminator tt(_heap);
 540 
 541       if (terminator->offer_termination(&tt)) return;
 542     }
 543   }
 544 }
 545 
 546 bool ShenandoahTraversalGC::check_and_handle_cancelled_gc(ShenandoahTaskTerminator* terminator, bool sts_yield) {
 547   if (_heap->cancelled_gc()) {
 548     return true;
 549   }
 550   return false;
 551 }
 552 
 553 void ShenandoahTraversalGC::concurrent_traversal_collection() {
 554   ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::conc_traversal);
 555   if (!_heap->cancelled_gc()) {
 556     uint nworkers = _heap->workers()->active_workers();
 557     task_queues()->reserve(nworkers);
 558     ShenandoahTerminationTracker tracker(ShenandoahPhaseTimings::conc_traversal_termination);
 559 
 560     ShenandoahTaskTerminator terminator(nworkers, task_queues());
 561     ShenandoahConcurrentTraversalCollectionTask task(&terminator);
 562     _heap->workers()->run_task(&task);
 563   }
 564 
 565   if (!_heap->cancelled_gc() && ShenandoahPreclean && _heap->process_references()) {
 566     preclean_weak_refs();
 567   }
 568 }
 569 
 570 void ShenandoahTraversalGC::final_traversal_collection() {
 571   _heap->make_parsable(true);
 572 
 573   if (!_heap->cancelled_gc()) {
 574 #if defined(COMPILER2) || INCLUDE_JVMCI
 575     DerivedPointerTable::clear();
 576 #endif
 577     ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::final_traversal_gc_work);
 578     uint nworkers = _heap->workers()->active_workers();
 579     task_queues()->reserve(nworkers);
 580 
 581     // Finish traversal
 582     ShenandoahAllRootScanner rp(nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
 583     ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination);
 584 
 585     ShenandoahTaskTerminator terminator(nworkers, task_queues());
 586     ShenandoahFinalTraversalCollectionTask task(&rp, &terminator);
 587     _heap->workers()->run_task(&task);
 588 #if defined(COMPILER2) || INCLUDE_JVMCI
 589     DerivedPointerTable::update_pointers();
 590 #endif
 591   }
 592 
 593   if (!_heap->cancelled_gc() && _heap->process_references()) {
 594     weak_refs_work();
 595   }
 596 
 597   if (!_heap->cancelled_gc()) {
 598     fixup_roots();
 599     if (_heap->unload_classes()) {
 600       _heap->unload_classes_and_cleanup_tables(false);
 601     }
 602   }
 603 
 604   if (!_heap->cancelled_gc()) {
 605     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
 606     TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
 607     TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
 608 
 609     // No more marking expected
 610     _heap->mark_complete_marking_context();
 611 
 612     // Resize metaspace
 613     MetaspaceGC::compute_new_size();
 614 
 615     // Still good? We can now trash the cset, and make final verification
 616     {
 617       ShenandoahGCPhase phase_cleanup(ShenandoahPhaseTimings::traversal_gc_cleanup);
 618       ShenandoahHeapLocker lock(_heap->lock());
 619 
 620       // Trash everything
 621       // Clear immediate garbage regions.
 622       size_t num_regions = _heap->num_regions();
 623 
 624       ShenandoahHeapRegionSet* traversal_regions = traversal_set();
 625       ShenandoahFreeSet* free_regions = _heap->free_set();
 626       ShenandoahMarkingContext* const ctx = _heap->marking_context();
 627       free_regions->clear();
 628       for (size_t i = 0; i < num_regions; i++) {
 629         ShenandoahHeapRegion* r = _heap->get_region(i);
 630         bool not_allocated = ctx->top_at_mark_start(r) == r->top();
 631 
 632         bool candidate = traversal_regions->is_in(r) && !r->has_live() && not_allocated;
 633         if (r->is_humongous_start() && candidate) {
 634           // Trash humongous.
 635           HeapWord* humongous_obj = r->bottom();
 636           assert(!ctx->is_marked(oop(humongous_obj)), "must not be marked");
 637           r->make_trash_immediate();
 638           while (i + 1 < num_regions && _heap->get_region(i + 1)->is_humongous_continuation()) {
 639             i++;
 640             r = _heap->get_region(i);
 641             assert(r->is_humongous_continuation(), "must be humongous continuation");
 642             r->make_trash_immediate();
 643           }
 644         } else if (!r->is_empty() && candidate) {
 645           // Trash regular.
 646           assert(!r->is_humongous(), "handled above");
 647           assert(!r->is_trash(), "must not already be trashed");
 648           r->make_trash_immediate();
 649         }
 650       }
 651       _heap->collection_set()->clear();
 652       _heap->free_set()->rebuild();
 653       reset();
 654     }
 655 
 656     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
 657     _heap->set_concurrent_traversal_in_progress(false);
 658     assert(!_heap->cancelled_gc(), "must not be cancelled when getting out here");
 659 
 660     if (ShenandoahVerify) {
 661       _heap->verifier()->verify_after_traversal();
 662     }
 663 
 664     if (VerifyAfterGC) {
 665       Universe::verify();
 666     }
 667   }
 668 }
 669 
 670 class ShenandoahTraversalFixRootsClosure : public OopClosure {
 671 private:
 672   template <class T>
 673   inline void do_oop_work(T* p) {
 674     T o = RawAccess<>::oop_load(p);
 675     if (!CompressedOops::is_null(o)) {
 676       oop obj = CompressedOops::decode_not_null(o);
 677       oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
 678       if (!oopDesc::equals_raw(obj, forw)) {
 679         RawAccess<IS_NOT_NULL>::oop_store(p, forw);
 680       }
 681     }
 682   }
 683 
 684 public:
 685   inline void do_oop(oop* p) { do_oop_work(p); }
 686   inline void do_oop(narrowOop* p) { do_oop_work(p); }
 687 };
 688 
 689 class ShenandoahTraversalFixRootsTask : public AbstractGangTask {
 690 private:
 691   ShenandoahRootUpdater* _rp;
 692 
 693 public:
 694   ShenandoahTraversalFixRootsTask(ShenandoahRootUpdater* rp) :
 695     AbstractGangTask("Shenandoah traversal fix roots"),
 696     _rp(rp) {
 697     assert(ShenandoahHeap::heap()->has_forwarded_objects(), "Must be");
 698   }
 699 
 700   void work(uint worker_id) {
 701     ShenandoahParallelWorkerSession worker_session(worker_id);
 702     ShenandoahTraversalFixRootsClosure cl;
 703     ShenandoahForwardedIsAliveClosure is_alive;
 704     _rp->roots_do<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalFixRootsClosure>(worker_id, &is_alive, &cl);
 705   }
 706 };
 707 
 708 void ShenandoahTraversalGC::fixup_roots() {
 709 #if defined(COMPILER2) || INCLUDE_JVMCI
 710   DerivedPointerTable::clear();
 711 #endif
 712   ShenandoahRootUpdater rp(_heap->workers()->active_workers(), ShenandoahPhaseTimings::final_traversal_update_roots, true /* update code cache */);
 713   ShenandoahTraversalFixRootsTask update_roots_task(&rp);
 714   _heap->workers()->run_task(&update_roots_task);
 715 #if defined(COMPILER2) || INCLUDE_JVMCI
 716   DerivedPointerTable::update_pointers();
 717 #endif
 718 }
 719 
 720 void ShenandoahTraversalGC::reset() {
 721   _task_queues->clear();
 722 }
 723 
 724 ShenandoahObjToScanQueueSet* ShenandoahTraversalGC::task_queues() {
 725   return _task_queues;
 726 }
 727 
 728 class ShenandoahTraversalCancelledGCYieldClosure : public YieldClosure {
 729 private:
 730   ShenandoahHeap* const _heap;
 731 public:
 732   ShenandoahTraversalCancelledGCYieldClosure() : _heap(ShenandoahHeap::heap()) {};
 733   virtual bool should_return() { return _heap->cancelled_gc(); }
 734 };
 735 
 736 class ShenandoahTraversalPrecleanCompleteGCClosure : public VoidClosure {
 737 public:
 738   void do_void() {
 739     ShenandoahHeap* sh = ShenandoahHeap::heap();
 740     ShenandoahTraversalGC* traversal_gc = sh->traversal_gc();
 741     assert(sh->process_references(), "why else would we be here?");
 742     ShenandoahTaskTerminator terminator(1, traversal_gc->task_queues());
 743     shenandoah_assert_rp_isalive_installed();
 744     traversal_gc->main_loop((uint) 0, &terminator, true);
 745   }
 746 };
 747 
 748 class ShenandoahTraversalKeepAliveUpdateClosure : public OopClosure {
 749 private:
 750   ShenandoahObjToScanQueue* _queue;
 751   Thread* _thread;
 752   ShenandoahTraversalGC* _traversal_gc;
 753   ShenandoahMarkingContext* const _mark_context;
 754 
 755   template <class T>
 756   inline void do_oop_work(T* p) {
 757     _traversal_gc->process_oop<T, false /* string dedup */, false /* degen */>(p, _thread, _queue, _mark_context);
 758   }
 759 
 760 public:
 761   ShenandoahTraversalKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) :
 762     _queue(q), _thread(Thread::current()),
 763     _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 764     _mark_context(ShenandoahHeap::heap()->marking_context()) {}
 765 
 766   void do_oop(narrowOop* p) { do_oop_work(p); }
 767   void do_oop(oop* p)       { do_oop_work(p); }
 768 };
 769 
 770 class ShenandoahTraversalKeepAliveUpdateDegenClosure : public OopClosure {
 771 private:
 772   ShenandoahObjToScanQueue* _queue;
 773   Thread* _thread;
 774   ShenandoahTraversalGC* _traversal_gc;
 775   ShenandoahMarkingContext* const _mark_context;
 776 
 777   template <class T>
 778   inline void do_oop_work(T* p) {
 779     _traversal_gc->process_oop<T, false /* string dedup */, true /* degen */>(p, _thread, _queue, _mark_context);
 780   }
 781 
 782 public:
 783   ShenandoahTraversalKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) :
 784           _queue(q), _thread(Thread::current()),
 785           _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 786           _mark_context(ShenandoahHeap::heap()->marking_context()) {}
 787 
 788   void do_oop(narrowOop* p) { do_oop_work(p); }
 789   void do_oop(oop* p)       { do_oop_work(p); }
 790 };
 791 
 792 class ShenandoahTraversalSingleThreadKeepAliveUpdateClosure : public OopClosure {
 793 private:
 794   ShenandoahObjToScanQueue* _queue;
 795   Thread* _thread;
 796   ShenandoahTraversalGC* _traversal_gc;
 797   ShenandoahMarkingContext* const _mark_context;
 798 
 799   template <class T>
 800   inline void do_oop_work(T* p) {
 801     ShenandoahEvacOOMScope evac_scope;
 802     _traversal_gc->process_oop<T, false /* string dedup */, false /* degen */>(p, _thread, _queue, _mark_context);
 803   }
 804 
 805 public:
 806   ShenandoahTraversalSingleThreadKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) :
 807           _queue(q), _thread(Thread::current()),
 808           _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 809           _mark_context(ShenandoahHeap::heap()->marking_context()) {}
 810 
 811   void do_oop(narrowOop* p) { do_oop_work(p); }
 812   void do_oop(oop* p)       { do_oop_work(p); }
 813 };
 814 
 815 class ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure : public OopClosure {
 816 private:
 817   ShenandoahObjToScanQueue* _queue;
 818   Thread* _thread;
 819   ShenandoahTraversalGC* _traversal_gc;
 820   ShenandoahMarkingContext* const _mark_context;
 821 
 822   template <class T>
 823   inline void do_oop_work(T* p) {
 824     ShenandoahEvacOOMScope evac_scope;
 825     _traversal_gc->process_oop<T, false /* string dedup */, true /* degen */>(p, _thread, _queue, _mark_context);
 826   }
 827 
 828 public:
 829   ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) :
 830           _queue(q), _thread(Thread::current()),
 831           _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 832           _mark_context(ShenandoahHeap::heap()->marking_context()) {}
 833 
 834   void do_oop(narrowOop* p) { do_oop_work(p); }
 835   void do_oop(oop* p)       { do_oop_work(p); }
 836 };
 837 
 838 class ShenandoahTraversalPrecleanTask : public AbstractGangTask {
 839 private:
 840   ReferenceProcessor* _rp;
 841 
 842 public:
 843   ShenandoahTraversalPrecleanTask(ReferenceProcessor* rp) :
 844           AbstractGangTask("Precleaning task"),
 845           _rp(rp) {}
 846 
 847   void work(uint worker_id) {
 848     assert(worker_id == 0, "The code below is single-threaded, only one worker is expected");
 849     ShenandoahParallelWorkerSession worker_session(worker_id);
 850     ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
 851     ShenandoahEvacOOMScope oom_evac_scope;
 852 
 853     ShenandoahHeap* sh = ShenandoahHeap::heap();
 854 
 855     ShenandoahObjToScanQueue* q = sh->traversal_gc()->task_queues()->queue(worker_id);
 856 
 857     ShenandoahForwardedIsAliveClosure is_alive;
 858     ShenandoahTraversalCancelledGCYieldClosure yield;
 859     ShenandoahTraversalPrecleanCompleteGCClosure complete_gc;
 860     ShenandoahTraversalKeepAliveUpdateClosure keep_alive(q);
 861     ResourceMark rm;
 862     _rp->preclean_discovered_references(&is_alive, &keep_alive,
 863                                         &complete_gc, &yield,
 864                                         NULL);
 865   }
 866 };
 867 
 868 void ShenandoahTraversalGC::preclean_weak_refs() {
 869   // Pre-cleaning weak references before diving into STW makes sense at the
 870   // end of concurrent mark. This will filter out the references which referents
 871   // are alive. Note that ReferenceProcessor already filters out these on reference
 872   // discovery, and the bulk of work is done here. This phase processes leftovers
 873   // that missed the initial filtering, i.e. when referent was marked alive after
 874   // reference was discovered by RP.
 875 
 876   assert(_heap->process_references(), "sanity");
 877   assert(!_heap->is_degenerated_gc_in_progress(), "must be in concurrent non-degenerated phase");
 878 
 879   // Shortcut if no references were discovered to avoid winding up threads.
 880   ReferenceProcessor* rp = _heap->ref_processor();
 881   if (!rp->has_discovered_references()) {
 882     return;
 883   }
 884 
 885   ReferenceProcessorMTDiscoveryMutator fix_mt_discovery(rp, false);
 886 
 887   shenandoah_assert_rp_isalive_not_installed();
 888   ShenandoahForwardedIsAliveClosure is_alive;
 889   ReferenceProcessorIsAliveMutator fix_isalive(rp, &is_alive);
 890 
 891   assert(task_queues()->is_empty(), "Should be empty");
 892 
 893   // Execute precleaning in the worker thread: it will give us GCLABs, String dedup
 894   // queues and other goodies. When upstream ReferenceProcessor starts supporting
 895   // parallel precleans, we can extend this to more threads.
 896   ShenandoahPushWorkerScope scope(_heap->workers(), 1, /* check_workers = */ false);
 897 
 898   WorkGang* workers = _heap->workers();
 899   uint nworkers = workers->active_workers();
 900   assert(nworkers == 1, "This code uses only a single worker");
 901   task_queues()->reserve(nworkers);
 902 
 903   ShenandoahTraversalPrecleanTask task(rp);
 904   workers->run_task(&task);
 905 
 906   assert(_heap->cancelled_gc() || task_queues()->is_empty(), "Should be empty");
 907 }
 908 
 909 // Weak Reference Closures
 910 class ShenandoahTraversalDrainMarkingStackClosure: public VoidClosure {
 911   uint _worker_id;
 912   ShenandoahTaskTerminator* _terminator;
 913   bool _reset_terminator;
 914 
 915 public:
 916   ShenandoahTraversalDrainMarkingStackClosure(uint worker_id, ShenandoahTaskTerminator* t, bool reset_terminator = false):
 917     _worker_id(worker_id),
 918     _terminator(t),
 919     _reset_terminator(reset_terminator) {
 920   }
 921 
 922   void do_void() {
 923     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
 924 
 925     ShenandoahHeap* sh = ShenandoahHeap::heap();
 926     ShenandoahTraversalGC* traversal_gc = sh->traversal_gc();
 927     assert(sh->process_references(), "why else would we be here?");
 928     shenandoah_assert_rp_isalive_installed();
 929 
 930     traversal_gc->main_loop(_worker_id, _terminator, false);
 931 
 932     if (_reset_terminator) {
 933       _terminator->reset_for_reuse();
 934     }
 935   }
 936 };
 937 
 938 class ShenandoahTraversalSingleThreadedDrainMarkingStackClosure: public VoidClosure {
 939   uint _worker_id;
 940   ShenandoahTaskTerminator* _terminator;
 941   bool _reset_terminator;
 942 
 943 public:
 944   ShenandoahTraversalSingleThreadedDrainMarkingStackClosure(uint worker_id, ShenandoahTaskTerminator* t, bool reset_terminator = false):
 945           _worker_id(worker_id),
 946           _terminator(t),
 947           _reset_terminator(reset_terminator) {
 948   }
 949 
 950   void do_void() {
 951     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
 952 
 953     ShenandoahHeap* sh = ShenandoahHeap::heap();
 954     ShenandoahTraversalGC* traversal_gc = sh->traversal_gc();
 955     assert(sh->process_references(), "why else would we be here?");
 956     shenandoah_assert_rp_isalive_installed();
 957 
 958     ShenandoahEvacOOMScope evac_scope;
 959     traversal_gc->main_loop(_worker_id, _terminator, false);
 960 
 961     if (_reset_terminator) {
 962       _terminator->reset_for_reuse();
 963     }
 964   }
 965 };
 966 
 967 void ShenandoahTraversalGC::weak_refs_work() {
 968   assert(_heap->process_references(), "sanity");
 969 
 970   ShenandoahPhaseTimings::Phase phase_root = ShenandoahPhaseTimings::weakrefs;
 971 
 972   ShenandoahGCPhase phase(phase_root);
 973 
 974   ReferenceProcessor* rp = _heap->ref_processor();
 975 
 976   // NOTE: We cannot shortcut on has_discovered_references() here, because
 977   // we will miss marking JNI Weak refs then, see implementation in
 978   // ReferenceProcessor::process_discovered_references.
 979   weak_refs_work_doit();
 980 
 981   rp->verify_no_references_recorded();
 982   assert(!rp->discovery_enabled(), "Post condition");
 983 
 984 }
 985 
 986 class ShenandoahTraversalRefProcTaskProxy : public AbstractGangTask {
 987 private:
 988   AbstractRefProcTaskExecutor::ProcessTask& _proc_task;
 989   ShenandoahTaskTerminator* _terminator;
 990 
 991 public:
 992   ShenandoahTraversalRefProcTaskProxy(AbstractRefProcTaskExecutor::ProcessTask& proc_task,
 993                                       ShenandoahTaskTerminator* t) :
 994     AbstractGangTask("Process reference objects in parallel"),
 995     _proc_task(proc_task),
 996     _terminator(t) {
 997   }
 998 
 999   void work(uint worker_id) {
1000     ShenandoahEvacOOMScope oom_evac_scope;
1001     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
1002     ShenandoahHeap* heap = ShenandoahHeap::heap();
1003     ShenandoahTraversalDrainMarkingStackClosure complete_gc(worker_id, _terminator);
1004 
1005     ShenandoahForwardedIsAliveClosure is_alive;
1006     if (!heap->is_degenerated_gc_in_progress()) {
1007       ShenandoahTraversalKeepAliveUpdateClosure keep_alive(heap->traversal_gc()->task_queues()->queue(worker_id));
1008       _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
1009     } else {
1010       ShenandoahTraversalKeepAliveUpdateDegenClosure keep_alive(heap->traversal_gc()->task_queues()->queue(worker_id));
1011       _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
1012     }
1013   }
1014 };
1015 
1016 class ShenandoahTraversalRefProcTaskExecutor : public AbstractRefProcTaskExecutor {
1017 private:
1018   WorkGang* _workers;
1019 
1020 public:
1021   ShenandoahTraversalRefProcTaskExecutor(WorkGang* workers) : _workers(workers) {}
1022 
1023   // Executes a task using worker threads.
1024   void execute(ProcessTask& task, uint ergo_workers) {
1025     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
1026 
1027     ShenandoahHeap* heap = ShenandoahHeap::heap();
1028     ShenandoahTraversalGC* traversal_gc = heap->traversal_gc();
1029     ShenandoahPushWorkerQueuesScope scope(_workers,
1030                                           traversal_gc->task_queues(),
1031                                           ergo_workers,
1032                                           /* do_check = */ false);
1033     uint nworkers = _workers->active_workers();
1034     traversal_gc->task_queues()->reserve(nworkers);
1035     ShenandoahTaskTerminator terminator(nworkers, traversal_gc->task_queues());
1036     ShenandoahTraversalRefProcTaskProxy proc_task_proxy(task, &terminator);
1037     _workers->run_task(&proc_task_proxy);
1038   }
1039 };
1040 
1041 void ShenandoahTraversalGC::weak_refs_work_doit() {
1042   ReferenceProcessor* rp = _heap->ref_processor();
1043 
1044   ShenandoahPhaseTimings::Phase phase_process = ShenandoahPhaseTimings::weakrefs_process;
1045 
1046   shenandoah_assert_rp_isalive_not_installed();
1047   ShenandoahForwardedIsAliveClosure is_alive;
1048   ReferenceProcessorIsAliveMutator fix_isalive(rp, &is_alive);
1049 
1050   WorkGang* workers = _heap->workers();
1051   uint nworkers = workers->active_workers();
1052 
1053   rp->setup_policy(_heap->soft_ref_policy()->should_clear_all_soft_refs());
1054   rp->set_active_mt_degree(nworkers);
1055 
1056   assert(task_queues()->is_empty(), "Should be empty");
1057 
1058   // complete_gc and keep_alive closures instantiated here are only needed for
1059   // single-threaded path in RP. They share the queue 0 for tracking work, which
1060   // simplifies implementation. Since RP may decide to call complete_gc several
1061   // times, we need to be able to reuse the terminator.
1062   uint serial_worker_id = 0;
1063   ShenandoahTaskTerminator terminator(1, task_queues());
1064   ShenandoahTraversalSingleThreadedDrainMarkingStackClosure complete_gc(serial_worker_id, &terminator, /* reset_terminator = */ true);
1065   ShenandoahPushWorkerQueuesScope scope(workers, task_queues(), 1, /* do_check = */ false);
1066 
1067   ShenandoahTraversalRefProcTaskExecutor executor(workers);
1068 
1069   ReferenceProcessorPhaseTimes pt(_heap->gc_timer(), rp->num_queues());
1070   if (!_heap->is_degenerated_gc_in_progress()) {
1071     ShenandoahTraversalSingleThreadKeepAliveUpdateClosure keep_alive(task_queues()->queue(serial_worker_id));
1072     rp->process_discovered_references(&is_alive, &keep_alive,
1073                                       &complete_gc, &executor,
1074                                       &pt);
1075   } else {
1076     ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure keep_alive(task_queues()->queue(serial_worker_id));
1077     rp->process_discovered_references(&is_alive, &keep_alive,
1078                                       &complete_gc, &executor,
1079                                       &pt);
1080   }
1081 
1082   pt.print_all_references();
1083   assert(task_queues()->is_empty() || _heap->cancelled_gc(), "Should be empty");
1084 }