--- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-06-11 11:46:37.901693835 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-06-11 11:46:37.373692868 -0400 @@ -1279,7 +1279,12 @@ // First, we process all GC roots. This populates the work stack with initial objects. ShenandoahAllRootScanner rp(1, ShenandoahPhaseTimings::_num_phases); ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack); - rp.roots_do_unchecked(&oops); + + if (unload_classes()) { + rp.strong_roots_do_unchecked(&oops); + } else { + rp.roots_do_unchecked(&oops); + } // Work through the oop stack to traverse heap. while (! oop_stack.is_empty()) { --- old/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp 2019-06-11 11:46:39.254696314 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp 2019-06-11 11:46:38.722695339 -0400 @@ -148,6 +148,7 @@ void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); // For heap object iteration void roots_do_unchecked(OopClosure* cl); + void strong_roots_do_unchecked(OopClosure* cl); }; typedef ShenandoahRootScanner ShenandoahAllRootScanner; --- old/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp 2019-06-11 11:46:40.497698591 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp 2019-06-11 11:46:39.973697631 -0400 @@ -126,6 +126,19 @@ } template +void ShenandoahRootScanner::strong_roots_do_unchecked(OopClosure* oops) { + CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong); + MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations); + ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL); + ResourceMark rm; + + _serial_roots.oops_do(oops, 0); + _jni_roots.oops_do(oops, 0); + _cld_roots.clds_do(&clds, NULL, 0); + _thread_roots.threads_do(&tc_cl, 0); +} + +template void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) { assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading"); ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);