@@ -104,6 +104,20 @@ void ShenandoahParallelCodeHeapIterator::parallel_blobs_do(CodeBlobClosure* f) {
104
104
ShenandoahNMethodTable* ShenandoahCodeRoots::_nmethod_table;
105
105
int ShenandoahCodeRoots::_disarmed_value = 1 ;
106
106
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
+
107
121
void ShenandoahCodeRoots::initialize () {
108
122
_nmethod_table = new ShenandoahNMethodTable ();
109
123
}
@@ -118,8 +132,13 @@ void ShenandoahCodeRoots::unregister_nmethod(nmethod* nm) {
118
132
_nmethod_table->unregister_nmethod (nm);
119
133
}
120
134
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 () {
123
142
BarrierSet::barrier_set ()->barrier_set_nmethod ()->arm_all_nmethods ();
124
143
}
125
144
@@ -163,7 +182,7 @@ class ShenandoahDisarmNMethodsTask : public WorkerTask {
163
182
};
164
183
165
184
void ShenandoahCodeRoots::disarm_nmethods () {
166
- if (ShenandoahNMethodBarrier ) {
185
+ if (use_nmethod_barriers_for_mark () ) {
167
186
ShenandoahDisarmNMethodsTask task;
168
187
ShenandoahHeap::heap ()->workers ()->run_task (&task);
169
188
}
0 commit comments