8382150: Shenandoah: Clean up nmethod entry barrier support

Reviewed-by: xpeng, kdnilsen, wkemper
This commit is contained in:
Aleksey Shipilev 2026-04-16 18:20:29 +00:00
parent 2c30f12080
commit 17ee366ff9
8 changed files with 16 additions and 65 deletions

View File

@ -180,9 +180,6 @@ public:
};
class ShenandoahNMethodAndDisarmClosure : public NMethodToOopClosure {
private:
BarrierSetNMethod* const _bs;
public:
inline ShenandoahNMethodAndDisarmClosure(OopClosure* cl);
inline void do_nmethod(nmethod* nm);

View File

@ -209,15 +209,13 @@ void ShenandoahCleanUpdateWeakOopsClosure<CONCURRENT, IsAlive, KeepAlive>::do_oo
}
ShenandoahNMethodAndDisarmClosure::ShenandoahNMethodAndDisarmClosure(OopClosure* cl) :
NMethodToOopClosure(cl, true /* fix_relocations */),
_bs(BarrierSet::barrier_set()->barrier_set_nmethod()) {
}
NMethodToOopClosure(cl, true /* fix_relocations */) {}
void ShenandoahNMethodAndDisarmClosure::do_nmethod(nmethod* nm) {
assert(nm != nullptr, "Sanity");
assert(!ShenandoahNMethod::gc_data(nm)->is_unregistered(), "Should not be here");
NMethodToOopClosure::do_nmethod(nm);
_bs->disarm(nm);
ShenandoahNMethod::disarm_nmethod(nm);
}

View File

@ -40,20 +40,6 @@
ShenandoahNMethodTable* ShenandoahCodeRoots::_nmethod_table;
int ShenandoahCodeRoots::_disarmed_value = 1;
bool ShenandoahCodeRoots::use_nmethod_barriers_for_mark() {
// Continuations need nmethod barriers for scanning stack chunk nmethods.
if (Continuations::enabled()) return true;
// Concurrent class unloading needs nmethod barriers.
// When a nmethod is about to be executed, we need to make sure that all its
// metadata are marked. The alternative is to remark thread roots at final mark
// pause, which would cause latency issues.
if (ShenandoahHeap::heap()->unload_classes()) return true;
// Otherwise, we can go without nmethod barriers.
return false;
}
void ShenandoahCodeRoots::initialize() {
_nmethod_table = new ShenandoahNMethodTable();
}
@ -68,27 +54,14 @@ void ShenandoahCodeRoots::unregister_nmethod(nmethod* nm) {
_nmethod_table->unregister_nmethod(nm);
}
void ShenandoahCodeRoots::arm_nmethods_for_mark() {
if (use_nmethod_barriers_for_mark()) {
BarrierSet::barrier_set()->barrier_set_nmethod()->arm_all_nmethods();
}
}
void ShenandoahCodeRoots::arm_nmethods_for_evac() {
void ShenandoahCodeRoots::arm_nmethods() {
BarrierSet::barrier_set()->barrier_set_nmethod()->arm_all_nmethods();
}
class ShenandoahDisarmNMethodClosure : public NMethodClosure {
private:
BarrierSetNMethod* const _bs;
public:
ShenandoahDisarmNMethodClosure() :
_bs(BarrierSet::barrier_set()->barrier_set_nmethod()) {
}
virtual void do_nmethod(nmethod* nm) {
_bs->disarm(nm);
ShenandoahNMethod::disarm_nmethod(nm);
}
};
@ -111,10 +84,8 @@ public:
};
void ShenandoahCodeRoots::disarm_nmethods() {
if (use_nmethod_barriers_for_mark()) {
ShenandoahDisarmNMethodsTask task;
ShenandoahHeap::heap()->workers()->run_task(&task);
}
ShenandoahDisarmNMethodsTask task;
ShenandoahHeap::heap()->workers()->run_task(&task);
}
class ShenandoahNMethodUnlinkClosure : public NMethodClosure {

View File

@ -67,14 +67,11 @@ public:
// Concurrent nmethod unloading support
static void unlink(WorkerThreads* workers, bool unloading_occurred);
static void purge();
static void arm_nmethods_for_mark();
static void arm_nmethods_for_evac();
static void arm_nmethods();
static void disarm_nmethods();
static int disarmed_value() { return _disarmed_value; }
static int* disarmed_value_address() { return &_disarmed_value; }
static bool use_nmethod_barriers_for_mark();
private:
static ShenandoahNMethodTable* _nmethod_table;
static int _disarmed_value;

View File

@ -744,9 +744,8 @@ void ShenandoahConcurrentGC::op_init_mark() {
// Make above changes visible to worker threads
OrderAccess::fence();
// Arm nmethods for concurrent mark
ShenandoahCodeRoots::arm_nmethods_for_mark();
// Arm nmethods/stack for concurrent processing
ShenandoahCodeRoots::arm_nmethods();
ShenandoahStackWatermark::change_epoch_id();
{
@ -805,7 +804,7 @@ void ShenandoahConcurrentGC::op_final_mark() {
heap->set_has_forwarded_objects(true);
// Arm nmethods/stack for concurrent processing
ShenandoahCodeRoots::arm_nmethods_for_evac();
ShenandoahCodeRoots::arm_nmethods();
ShenandoahStackWatermark::change_epoch_id();
} else {
@ -1035,14 +1034,10 @@ void ShenandoahConcurrentGC::op_class_unloading() {
class ShenandoahEvacUpdateCodeCacheClosure : public NMethodClosure {
private:
BarrierSetNMethod* const _bs;
ShenandoahEvacuateUpdateMetadataClosure _cl;
public:
ShenandoahEvacUpdateCodeCacheClosure() :
_bs(BarrierSet::barrier_set()->barrier_set_nmethod()),
_cl() {
}
ShenandoahEvacUpdateCodeCacheClosure() : _cl() {}
void do_nmethod(nmethod* n) {
ShenandoahNMethod* data = ShenandoahNMethod::gc_data(n);
@ -1050,8 +1045,8 @@ public:
// Setup EvacOOM scope below reentrant lock to avoid deadlock with
// nmethod_entry_barrier
ShenandoahEvacOOMScope oom;
data->oops_do(&_cl, true/*fix relocation*/);
_bs->disarm(n);
data->oops_do(&_cl, /* fix_relocations = */ true);
ShenandoahNMethod::disarm_nmethod(n);
}
};

View File

@ -200,9 +200,6 @@ ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTi
void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
NMethodToOopClosure code_blob_cl(oops, NMethodToOopClosure::FixRelocations);
ShenandoahNMethodAndDisarmClosure nmethods_and_disarm_Cl(oops);
NMethodToOopClosure* adjust_code_closure = ShenandoahCodeRoots::use_nmethod_barriers_for_mark() ?
static_cast<NMethodToOopClosure*>(&nmethods_and_disarm_Cl) :
static_cast<NMethodToOopClosure*>(&code_blob_cl);
CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
// Process light-weight/limited parallel roots then
@ -211,7 +208,7 @@ void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
_cld_roots.cld_do(&adjust_cld_closure, worker_id);
// Process heavy-weight/fully parallel roots the last
_code_roots.nmethods_do(adjust_code_closure, worker_id);
_code_roots.nmethods_do(&nmethods_and_disarm_Cl, worker_id);
_thread_roots.oops_do(oops, nullptr, worker_id);
}

View File

@ -172,10 +172,6 @@ template <typename IsAlive, typename KeepAlive>
void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
NMethodToOopClosure update_nmethods(keep_alive, NMethodToOopClosure::FixRelocations);
ShenandoahNMethodAndDisarmClosure nmethods_and_disarm_Cl(keep_alive);
NMethodToOopClosure* codes_cl = ShenandoahCodeRoots::use_nmethod_barriers_for_mark() ?
static_cast<NMethodToOopClosure*>(&nmethods_and_disarm_Cl) :
static_cast<NMethodToOopClosure*>(&update_nmethods);
CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
// Process light-weight/limited parallel roots then
@ -184,7 +180,7 @@ void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAliv
_cld_roots.cld_do(&clds, worker_id);
// Process heavy-weight/fully parallel roots the last
_code_roots.nmethods_do(codes_cl, worker_id);
_code_roots.nmethods_do(&nmethods_and_disarm_Cl, worker_id);
_thread_roots.oops_do(keep_alive, nullptr, worker_id);
}

View File

@ -74,7 +74,7 @@ void ShenandoahSTWMark::mark() {
// Arm all nmethods. Even though this is STW mark, some marking code
// piggybacks on nmethod barriers for special instances.
ShenandoahCodeRoots::arm_nmethods_for_mark();
ShenandoahCodeRoots::arm_nmethods();
// Weak reference processing
ShenandoahReferenceProcessor* rp = _generation->ref_processor();