@@ -104,6 +104,20 @@ void ShenandoahParallelCodeHeapIterator::parallel_blobs_do(CodeBlobClosure* f) {
104104ShenandoahNMethodTable* ShenandoahCodeRoots::_nmethod_table;
105105int ShenandoahCodeRoots::_disarmed_value = 1 ;
106106
107+ bool ShenandoahCodeRoots::use_nmethod_barriers_for_mark () {
108+ // Continuations need nmethod barriers for scanning stack chunk nmethods.
109+ if (Continuations::enabled ()) return true ;
110+
111+ // Concurrent class unloading needs nmethod barriers.
112+ // When a nmethod is about to be executed, we need to make sure that all its
113+ // metadata are marked. The alternative is to remark thread roots at final mark
114+ // pause, which would cause latency issues.
115+ if (ShenandoahHeap::heap ()->unload_classes ()) return true ;
116+
117+ // Otherwise, we can go without nmethod barriers.
118+ return false ;
119+ }
120+
107121void ShenandoahCodeRoots::initialize () {
108122 _nmethod_table = new ShenandoahNMethodTable ();
109123}
@@ -118,8 +132,13 @@ void ShenandoahCodeRoots::unregister_nmethod(nmethod* nm) {
118132 _nmethod_table->unregister_nmethod (nm);
119133}
120134
121- void ShenandoahCodeRoots::arm_nmethods () {
122- assert (BarrierSet::barrier_set ()->barrier_set_nmethod () != nullptr , " Sanity" );
135+ void ShenandoahCodeRoots::arm_nmethods_for_mark () {
136+ if (use_nmethod_barriers_for_mark ()) {
137+ BarrierSet::barrier_set ()->barrier_set_nmethod ()->arm_all_nmethods ();
138+ }
139+ }
140+
141+ void ShenandoahCodeRoots::arm_nmethods_for_evac () {
123142 BarrierSet::barrier_set ()->barrier_set_nmethod ()->arm_all_nmethods ();
124143}
125144
@@ -163,7 +182,7 @@ class ShenandoahDisarmNMethodsTask : public WorkerTask {
163182};
164183
165184void ShenandoahCodeRoots::disarm_nmethods () {
166- if (ShenandoahNMethodBarrier ) {
185+ if (use_nmethod_barriers_for_mark () ) {
167186 ShenandoahDisarmNMethodsTask task;
168187 ShenandoahHeap::heap ()->workers ()->run_task (&task);
169188 }
0 commit comments