Skip to content

Commit cf56c7e

Browse files
committed
8254980: ZGC: ZHeapIterator visits armed nmethods with -XX:-ClassUnloading
Reviewed-by: eosterlund, pliden
1 parent 18d9905 commit cf56c7e

File tree

9 files changed

+68
-17
lines changed

9 files changed

+68
-17
lines changed

src/hotspot/share/gc/z/zHeapIterator.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ class ZHeapIteratorRootOopClosure : public ZRootsIteratorClosure {
126126
CodeBlobToOopClosure code_cl(this, false /* fix_oop_relocations */);
127127
thread->oops_do(this, &code_cl);
128128
}
129+
130+
virtual ZNMethodEntry nmethod_entry() const {
131+
if (ClassUnloading) {
132+
// All encountered nmethods should have been "entered" during stack walking
133+
return ZNMethodEntry::VerifyDisarmed;
134+
} else {
135+
// All nmethods are considered roots and will be visited.
136+
// Make sure that the unvisited gets fixed and disarmed before proceeding.
137+
return ZNMethodEntry::PreBarrier;
138+
}
139+
}
129140
};
130141

131142
template <bool VisitReferents>

src/hotspot/share/gc/z/zMark.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,9 @@ class ZMarkConcurrentRootsIteratorClosure : public ZRootsIteratorClosure {
582582
ZThreadLocalAllocBuffer::publish_statistics();
583583
}
584584

585-
virtual bool should_disarm_nmethods() const {
586-
return true;
585+
virtual ZNMethodEntry nmethod_entry() const {
586+
// Only apply closure to armed nmethods, and then disarm them.
587+
return ZNMethodEntry::Disarm;
587588
}
588589

589590
virtual void do_thread(Thread* thread) {

src/hotspot/share/gc/z/zNMethod.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,28 +236,42 @@ void ZNMethod::nmethod_oops_do(nmethod* nm, OopClosure* cl) {
236236

237237
class ZNMethodToOopsDoClosure : public NMethodClosure {
238238
private:
239-
OopClosure* const _cl;
240-
const bool _should_disarm_nmethods;
239+
OopClosure* const _cl;
240+
const ZNMethodEntry _entry;
241+
BarrierSetNMethod* const _bs_nm;
241242

242243
public:
243-
ZNMethodToOopsDoClosure(OopClosure* cl, bool should_disarm_nmethods) :
244+
ZNMethodToOopsDoClosure(OopClosure* cl, ZNMethodEntry entry) :
244245
_cl(cl),
245-
_should_disarm_nmethods(should_disarm_nmethods) {}
246+
_entry(entry),
247+
_bs_nm(BarrierSet::barrier_set()->barrier_set_nmethod()) {}
246248

247249
virtual void do_nmethod(nmethod* nm) {
250+
if (_entry == ZNMethodEntry::PreBarrier) {
251+
// Apply entry barrier before proceeding with closure
252+
_bs_nm->nmethod_entry_barrier(nm);
253+
}
254+
248255
ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
249256
if (!nm->is_alive()) {
250257
return;
251258
}
252259

253-
if (_should_disarm_nmethods) {
260+
if (_entry == ZNMethodEntry::Disarm) {
261+
// Apply closure and disarm only armed nmethods
254262
if (ZNMethod::is_armed(nm)) {
255263
ZNMethod::nmethod_oops_do(nm, _cl);
256264
ZNMethod::disarm(nm);
257265
}
258-
} else {
259-
ZNMethod::nmethod_oops_do(nm, _cl);
266+
return;
260267
}
268+
269+
if (_entry == ZNMethodEntry::VerifyDisarmed) {
270+
// Only verify
271+
assert(!ZNMethod::is_armed(nm), "Must be disarmed");
272+
}
273+
274+
ZNMethod::nmethod_oops_do(nm, _cl);
261275
}
262276
};
263277

@@ -269,8 +283,8 @@ void ZNMethod::oops_do_end() {
269283
ZNMethodTable::nmethods_do_end();
270284
}
271285

272-
void ZNMethod::oops_do(OopClosure* cl, bool should_disarm_nmethods) {
273-
ZNMethodToOopsDoClosure nmethod_cl(cl, should_disarm_nmethods);
286+
void ZNMethod::oops_do(OopClosure* cl, ZNMethodEntry entry) {
287+
ZNMethodToOopsDoClosure nmethod_cl(cl, entry);
274288
ZNMethodTable::nmethods_do(&nmethod_cl);
275289
}
276290

src/hotspot/share/gc/z/zNMethod.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ class OopClosure;
3131
class ZReentrantLock;
3232
class ZWorkers;
3333

34+
enum class ZNMethodEntry {
35+
PreBarrier,
36+
Disarm,
37+
VerifyDisarmed,
38+
None
39+
};
40+
3441
class ZNMethod : public AllStatic {
3542
private:
3643
static void attach_gc_data(nmethod* nm);
@@ -52,7 +59,7 @@ class ZNMethod : public AllStatic {
5259

5360
static void oops_do_begin();
5461
static void oops_do_end();
55-
static void oops_do(OopClosure* cl, bool should_disarm_nmethods);
62+
static void oops_do(OopClosure* cl, ZNMethodEntry entry);
5663

5764
static ZReentrantLock* lock_for_nmethod(nmethod* nm);
5865

src/hotspot/share/gc/z/zOopClosures.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,16 @@ class ZPhantomKeepAliveOopClosure : public ZRootsIteratorClosure {
5757
public:
5858
virtual void do_oop(oop* p);
5959
virtual void do_oop(narrowOop* p);
60+
61+
virtual ZNMethodEntry nmethod_entry() const;
6062
};
6163

6264
class ZPhantomCleanOopClosure : public ZRootsIteratorClosure {
6365
public:
6466
virtual void do_oop(oop* p);
6567
virtual void do_oop(narrowOop* p);
68+
69+
virtual ZNMethodEntry nmethod_entry() const;
6670
};
6771

6872
#endif // SHARE_GC_Z_ZOOPCLOSURES_HPP

src/hotspot/share/gc/z/zOopClosures.inline.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ inline void ZPhantomKeepAliveOopClosure::do_oop(oop* p) {
8080
ZBarrier::keep_alive_barrier_on_phantom_oop_field(p);
8181
}
8282

83+
inline ZNMethodEntry ZPhantomKeepAliveOopClosure::nmethod_entry() const {
84+
ShouldNotReachHere();
85+
return ZNMethodEntry::None;
86+
}
87+
8388
inline void ZPhantomKeepAliveOopClosure::do_oop(narrowOop* p) {
8489
ShouldNotReachHere();
8590
}
@@ -104,4 +109,9 @@ inline void ZPhantomCleanOopClosure::do_oop(narrowOop* p) {
104109
ShouldNotReachHere();
105110
}
106111

112+
inline ZNMethodEntry ZPhantomCleanOopClosure::nmethod_entry() const {
113+
ShouldNotReachHere();
114+
return ZNMethodEntry::None;
115+
}
116+
107117
#endif // SHARE_GC_Z_ZOOPCLOSURES_INLINE_HPP

src/hotspot/share/gc/z/zRootsIterator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure*
122122

123123
void ZConcurrentRootsIterator::do_code_cache(ZRootsIteratorClosure* cl) {
124124
ZStatTimer timer(ZSubPhaseConcurrentRootsCodeCache);
125-
ZNMethod::oops_do(cl, cl->should_disarm_nmethods());
125+
ZNMethod::oops_do(cl, cl->nmethod_entry());
126126
}
127127

128128
class ZConcurrentRootsIteratorThreadClosure : public ThreadClosure {

src/hotspot/share/gc/z/zRootsIterator.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "classfile/classLoaderDataGraph.hpp"
2828
#include "gc/shared/oopStorageSetParState.hpp"
29+
#include "gc/z/zNMethod.hpp"
2930
#include "memory/allocation.hpp"
3031
#include "memory/iterator.hpp"
3132
#include "runtime/threadSMR.hpp"
@@ -61,9 +62,7 @@ class ZRootsIteratorClosure : public OopClosure {
6162
public:
6263
virtual void do_thread(Thread* thread) {}
6364

64-
virtual bool should_disarm_nmethods() const {
65-
return false;
66-
}
65+
virtual ZNMethodEntry nmethod_entry() const = 0;
6766
};
6867

6968
class ZJavaThreadsIterator {

src/hotspot/share/gc/z/zVerify.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ class ZVerifyRootClosure : public ZRootsIteratorClosure {
9494
bool verify_fixed() const {
9595
return _verify_fixed;
9696
}
97+
98+
virtual ZNMethodEntry nmethod_entry() const {
99+
// Verification performs its own verification
100+
return ZNMethodEntry::None;
101+
}
97102
};
98103

99104
class ZVerifyCodeBlobClosure : public CodeBlobToOopClosure {
@@ -188,7 +193,7 @@ void ZVerifyRootClosure::do_thread(Thread* thread) {
188193
verify_stack.verify_frames();
189194
}
190195

191-
class ZVerifyOopClosure : public ClaimMetadataVisitingOopIterateClosure, public ZRootsIteratorClosure {
196+
class ZVerifyOopClosure : public ClaimMetadataVisitingOopIterateClosure {
192197
private:
193198
const bool _verify_weaks;
194199

0 commit comments

Comments
 (0)