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.
int32_t _pending_threads;
JavaThread* _target;
Thread* _requester;
// Must use AsyncHandshakeOperation when using AsyncHandshakeClosure.
HandshakeOperation(AsyncHandshakeClosure* cl, JavaThread* target) :
HandshakeOperation(AsyncHandshakeClosure* cl, JavaThread* target, Thread* requester) :
_handshake_cl(cl),
_pending_threads(1),
_target(target) {}
_target(target),
_requester(requester) {}
public:
HandshakeOperation(HandshakeClosure* cl, JavaThread* target) :
HandshakeOperation(HandshakeClosure* cl, JavaThread* target, Thread* requester) :
_handshake_cl(cl),
_pending_threads(1),
_target(target) {}
_target(target),
_requester(requester) {}
virtual ~HandshakeOperation() {}
void prepare(JavaThread* current_target, Thread* executing_thread);
void do_handshake(JavaThread* thread);
bool is_completed() {
int32_t val = Atomic::load(&_pending_threads);
@ -77,7 +81,7 @@ class AsyncHandshakeOperation : public HandshakeOperation {
jlong _start_time_ns;
public:
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; }
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; }
};
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) {
jlong start_time_ns = 0;
if (log_is_enabled(Debug, handshake, task)) {
@ -305,14 +325,14 @@ void HandshakeOperation::do_handshake(JavaThread* thread) {
}
void Handshake::execute(HandshakeClosure* hs_cl) {
HandshakeOperation cto(hs_cl, NULL);
HandshakeOperation cto(hs_cl, NULL, Thread::current());
VM_HandshakeAllThreads handshake(&cto);
VMThread::execute(&handshake);
}
void Handshake::execute(HandshakeClosure* hs_cl, JavaThread* target) {
JavaThread* self = JavaThread::current();
HandshakeOperation op(hs_cl, target);
HandshakeOperation op(hs_cl, target, Thread::current());
jlong start_time_ns = os::javaTimeNanos();
@ -430,6 +450,7 @@ void HandshakeState::process_self_inner() {
bool async = op->is_async();
log_trace(handshake)("Proc handshake %s " INTPTR_FORMAT " on " INTPTR_FORMAT " by self",
async ? "asynchronous" : "synchronous", p2i(op), p2i(_handshakee));
op->prepare(_handshakee, _handshakee);
op->do_handshake(_handshakee);
if (async) {
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;
}
if (!_handshakee->is_terminated()) {
StackWatermarkSet::start_processing(_handshakee, StackWatermarkKind::gc);
}
op->prepare(_handshakee, current_thread);
_active_handshaker = current_thread;
op->do_handshake(_handshakee);