@@ -1142,9 +1142,7 @@ void ShenandoahHeap::evacuate_and_update_roots() {
1142
1142
{
1143
1143
// Include concurrent roots if current cycle can not process those roots concurrently
1144
1144
ShenandoahRootEvacuator rp (workers ()->active_workers (),
1145
- ShenandoahPhaseTimings::init_evac,
1146
- !ShenandoahConcurrentRoots::should_do_concurrent_roots (),
1147
- !ShenandoahConcurrentRoots::should_do_concurrent_class_unloading ());
1145
+ ShenandoahPhaseTimings::init_evac);
1148
1146
ShenandoahEvacuateUpdateRootsTask roots_task (&rp);
1149
1147
workers ()->run_task (&roots_task);
1150
1148
}
@@ -1744,9 +1742,8 @@ void ShenandoahHeap::op_final_mark() {
1744
1742
set_has_forwarded_objects (true );
1745
1743
1746
1744
if (!is_degenerated_gc_in_progress ()) {
1747
- if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading ()) {
1748
- ShenandoahCodeRoots::arm_nmethods ();
1749
- }
1745
+ // Arm nmethods for concurrent codecache processing.
1746
+ ShenandoahCodeRoots::arm_nmethods ();
1750
1747
evacuate_and_update_roots ();
1751
1748
}
1752
1749
@@ -1757,17 +1754,10 @@ void ShenandoahHeap::op_final_mark() {
1757
1754
if (ShenandoahVerify) {
1758
1755
// If OOM while evacuating/updating of roots, there is no guarantee of their consistencies
1759
1756
if (!cancelled_gc ()) {
1760
- ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::None;
1761
- if (ShenandoahConcurrentRoots::should_do_concurrent_roots ()) {
1762
- types = ShenandoahRootVerifier::combine (ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
1763
- types = ShenandoahRootVerifier::combine (types, ShenandoahRootVerifier::CLDGRoots);
1764
- types = ShenandoahRootVerifier::combine (types, ShenandoahRootVerifier::StringDedupRoots);
1765
- }
1766
-
1767
- if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading ()) {
1768
- types = ShenandoahRootVerifier::combine (types, ShenandoahRootVerifier::CodeRoots);
1769
- }
1770
- verifier ()->verify_roots_no_forwarded_except (types);
1757
+ // We only evacuate/update thread and serial weak roots at this pause
1758
+ ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine (ShenandoahRootVerifier::ThreadRoots,
1759
+ ShenandoahRootVerifier::SerialWeakRoots);
1760
+ verifier ()->verify_roots_no_forwarded (types);
1771
1761
}
1772
1762
verifier ()->verify_during_evacuation ();
1773
1763
}
@@ -1840,16 +1830,53 @@ void ShenandoahHeap::op_cleanup_complete() {
1840
1830
free_set ()->recycle_trash ();
1841
1831
}
1842
1832
1833
+ class ShenandoahEvacUpdateCodeCacheClosure : public NMethodClosure {
1834
+ private:
1835
+ BarrierSetNMethod* const _bs;
1836
+ ShenandoahEvacuateUpdateRootsClosure<> _cl;
1837
+
1838
+ public:
1839
+ ShenandoahEvacUpdateCodeCacheClosure () :
1840
+ _bs (BarrierSet::barrier_set()->barrier_set_nmethod ()),
1841
+ _cl() {
1842
+ }
1843
+
1844
+ void do_nmethod (nmethod* n) {
1845
+ ShenandoahNMethod* data = ShenandoahNMethod::gc_data (n);
1846
+ ShenandoahReentrantLocker locker (data->lock ());
1847
+ data->oops_do (&_cl, true /* fix relocation*/ );
1848
+ _bs->disarm (n);
1849
+ }
1850
+ };
1851
+
1843
1852
class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask {
1844
1853
private:
1854
+ ShenandoahPhaseTimings::Phase _phase;
1845
1855
ShenandoahVMRoots<true /* concurrent*/ > _vm_roots;
1846
1856
ShenandoahClassLoaderDataRoots<true /* concurrent*/ , false /* single threaded*/ > _cld_roots;
1857
+ ShenandoahConcurrentNMethodIterator _nmethod_itr;
1858
+ bool _process_codecache;
1847
1859
1848
1860
public:
1849
1861
ShenandoahConcurrentRootsEvacUpdateTask (ShenandoahPhaseTimings::Phase phase) :
1850
1862
AbstractGangTask (" Shenandoah Evacuate/Update Concurrent Strong Roots" ),
1863
+ _phase (phase),
1851
1864
_vm_roots (phase),
1852
- _cld_roots (phase, ShenandoahHeap::heap()->workers ()->active_workers()) {}
1865
+ _cld_roots (phase, ShenandoahHeap::heap()->workers ()->active_workers()),
1866
+ _nmethod_itr(ShenandoahCodeRoots::table()),
1867
+ _process_codecache(!ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
1868
+ if (_process_codecache) {
1869
+ MutexLocker mu (CodeCache_lock, Mutex::_no_safepoint_check_flag);
1870
+ _nmethod_itr.nmethods_do_begin ();
1871
+ }
1872
+ }
1873
+
1874
+ ~ShenandoahConcurrentRootsEvacUpdateTask () {
1875
+ if (_process_codecache) {
1876
+ MutexLocker mu (CodeCache_lock, Mutex::_no_safepoint_check_flag);
1877
+ _nmethod_itr.nmethods_do_end ();
1878
+ }
1879
+ }
1853
1880
1854
1881
void work (uint worker_id) {
1855
1882
ShenandoahConcurrentWorkerSession worker_session (worker_id);
@@ -1866,6 +1893,12 @@ class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask {
1866
1893
CLDToOopClosure clds (&cl, ClassLoaderData::_claim_strong);
1867
1894
_cld_roots.cld_do (&clds, worker_id);
1868
1895
}
1896
+
1897
+ if (_process_codecache) {
1898
+ ShenandoahWorkerTimingsTracker timer (_phase, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
1899
+ ShenandoahEvacUpdateCodeCacheClosure cl;
1900
+ _nmethod_itr.nmethods_do (&cl);
1901
+ }
1869
1902
}
1870
1903
};
1871
1904
0 commit comments