8261391: ZGC crash - SEGV in RevokeOneBias::do_thread

Reviewed-by: eosterlund, dcubed, dholmes
This commit is contained in:
Robbin Ehn 2021-02-22 13:16:55 +00:00
parent 5b7b18c5bf
commit d7eebdac5d

View File

@ -48,19 +48,23 @@ class HandshakeOperation : public CHeapObj<mtThread> {
// Once it reaches zero all handshake operations have been performed. // Once it reaches zero all handshake operations have been performed.
int32_t _pending_threads; int32_t _pending_threads;
JavaThread* _target; JavaThread* _target;
Thread* _requester;
// Must use AsyncHandshakeOperation when using AsyncHandshakeClosure. // Must use AsyncHandshakeOperation when using AsyncHandshakeClosure.
HandshakeOperation(AsyncHandshakeClosure* cl, JavaThread* target) : HandshakeOperation(AsyncHandshakeClosure* cl, JavaThread* target, Thread* requester) :
_handshake_cl(cl), _handshake_cl(cl),
_pending_threads(1), _pending_threads(1),
_target(target) {} _target(target),
_requester(requester) {}
public: public:
HandshakeOperation(HandshakeClosure* cl, JavaThread* target) : HandshakeOperation(HandshakeClosure* cl, JavaThread* target, Thread* requester) :
_handshake_cl(cl), _handshake_cl(cl),
_pending_threads(1), _pending_threads(1),
_target(target) {} _target(target),
_requester(requester) {}
virtual ~HandshakeOperation() {} virtual ~HandshakeOperation() {}
void prepare(JavaThread* current_target, Thread* executing_thread);
void do_handshake(JavaThread* thread); void do_handshake(JavaThread* thread);
bool is_completed() { bool is_completed() {
int32_t val = Atomic::load(&_pending_threads); int32_t val = Atomic::load(&_pending_threads);
@ -77,7 +81,7 @@ class AsyncHandshakeOperation : public HandshakeOperation {
jlong _start_time_ns; jlong _start_time_ns;
public: public:
AsyncHandshakeOperation(AsyncHandshakeClosure* cl, JavaThread* target, jlong start_ns) AsyncHandshakeOperation(AsyncHandshakeClosure* cl, JavaThread* target, jlong start_ns)
: HandshakeOperation(cl, target), _start_time_ns(start_ns) {} : HandshakeOperation(cl, target, NULL), _start_time_ns(start_ns) {}
virtual ~AsyncHandshakeOperation() { delete _handshake_cl; } virtual ~AsyncHandshakeOperation() { delete _handshake_cl; }
jlong start_time() const { return _start_time_ns; } jlong start_time() const { return _start_time_ns; }
}; };
@ -276,6 +280,22 @@ class VM_HandshakeAllThreads: public VM_Handshake {
VMOp_Type type() const { return VMOp_HandshakeAllThreads; } VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
}; };
void HandshakeOperation::prepare(JavaThread* current_target, Thread* executing_thread) {
if (current_target->is_terminated()) {
// Will never execute any handshakes on this thread.
return;
}
if (current_target != executing_thread) {
// Only when the target is not executing the handshake itself.
StackWatermarkSet::start_processing(current_target, StackWatermarkKind::gc);
}
if (_requester != NULL && _requester != executing_thread && _requester->is_Java_thread()) {
// The handshake closure may contain oop Handles from the _requester.
// We must make sure we can use them.
StackWatermarkSet::start_processing(_requester->as_Java_thread(), StackWatermarkKind::gc);
}
}
void HandshakeOperation::do_handshake(JavaThread* thread) { void HandshakeOperation::do_handshake(JavaThread* thread) {
jlong start_time_ns = 0; jlong start_time_ns = 0;
if (log_is_enabled(Debug, handshake, task)) { if (log_is_enabled(Debug, handshake, task)) {
@ -305,14 +325,14 @@ void HandshakeOperation::do_handshake(JavaThread* thread) {
} }
void Handshake::execute(HandshakeClosure* hs_cl) { void Handshake::execute(HandshakeClosure* hs_cl) {
HandshakeOperation cto(hs_cl, NULL); HandshakeOperation cto(hs_cl, NULL, Thread::current());
VM_HandshakeAllThreads handshake(&cto); VM_HandshakeAllThreads handshake(&cto);
VMThread::execute(&handshake); VMThread::execute(&handshake);
} }
void Handshake::execute(HandshakeClosure* hs_cl, JavaThread* target) { void Handshake::execute(HandshakeClosure* hs_cl, JavaThread* target) {
JavaThread* self = JavaThread::current(); JavaThread* self = JavaThread::current();
HandshakeOperation op(hs_cl, target); HandshakeOperation op(hs_cl, target, Thread::current());
jlong start_time_ns = os::javaTimeNanos(); jlong start_time_ns = os::javaTimeNanos();
@ -430,6 +450,7 @@ void HandshakeState::process_self_inner() {
bool async = op->is_async(); bool async = op->is_async();
log_trace(handshake)("Proc handshake %s " INTPTR_FORMAT " on " INTPTR_FORMAT " by self", log_trace(handshake)("Proc handshake %s " INTPTR_FORMAT " on " INTPTR_FORMAT " by self",
async ? "asynchronous" : "synchronous", p2i(op), p2i(_handshakee)); async ? "asynchronous" : "synchronous", p2i(op), p2i(_handshakee));
op->prepare(_handshakee, _handshakee);
op->do_handshake(_handshakee); op->do_handshake(_handshakee);
if (async) { if (async) {
log_handshake_info(((AsyncHandshakeOperation*)op)->start_time(), op->name(), 1, 0, "asynchronous"); log_handshake_info(((AsyncHandshakeOperation*)op)->start_time(), op->name(), 1, 0, "asynchronous");
@ -522,9 +543,7 @@ HandshakeState::ProcessResult HandshakeState::try_process(HandshakeOperation* ma
pr_ret = HandshakeState::_succeeded; pr_ret = HandshakeState::_succeeded;
} }
if (!_handshakee->is_terminated()) { op->prepare(_handshakee, current_thread);
StackWatermarkSet::start_processing(_handshakee, StackWatermarkKind::gc);
}
_active_handshaker = current_thread; _active_handshaker = current_thread;
op->do_handshake(_handshakee); op->do_handshake(_handshakee);