Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
AlanBateman committed Oct 15, 2024
2 parents f7fe851 + c3e0e0e commit 7396d65
Show file tree
Hide file tree
Showing 20 changed files with 85 additions and 120 deletions.
10 changes: 10 additions & 0 deletions src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,16 @@ void InterpreterMacroAssembler::call_VM_preemptable(Register oop_result,
assert(arg_1 == c_rarg1, "");
Label resume_pc, not_preempted;

#ifdef ASSERT
{
Label L;
ldr(rscratch1, Address(rthread, JavaThread::preempt_alternate_return_offset()));
cbz(rscratch1, L);
stop("Should not have alternate return address set");
bind(L);
}
#endif /* ASSERT */

push_cont_fastpath();

// Make VM call. In case of preemption set last_pc to the one we want to resume to.
Expand Down
3 changes: 0 additions & 3 deletions src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7147,9 +7147,6 @@ class StubGenerator: public StubCodeGenerator {

__ reset_last_Java_frame(true);

// reset the flag
__ strb(zr, Address(rthread, JavaThread::preempting_offset()));

// Set sp to enterSpecial frame, i.e. remove all frames copied into the heap.
__ ldr(rscratch2, Address(rthread, JavaThread::cont_entry_offset()));
__ mov(sp, rscratch2);
Expand Down
10 changes: 10 additions & 0 deletions src/hotspot/cpu/riscv/interp_masm_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,16 @@ void InterpreterMacroAssembler::call_VM_preemptable(Register oop_result,
assert(arg_1 == c_rarg1, "");
Label resume_pc, not_preempted;

#ifdef ASSERT
{
Label L;
ld(t0, Address(xthread, JavaThread::preempt_alternate_return_offset()));
beqz(t0, L);
stop("Should not have alternate return address set");
bind(L);
}
#endif /* ASSERT */

push_cont_fastpath();

// Make VM call. In case of preemption set last_pc to the one we want to resume to.
Expand Down
3 changes: 0 additions & 3 deletions src/hotspot/cpu/riscv/stubGenerator_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3880,9 +3880,6 @@ class StubGenerator: public StubCodeGenerator {

__ reset_last_Java_frame(true);

// reset the flag
__ sb(zr, Address(xthread, JavaThread::preempting_offset()));

// Set sp to enterSpecial frame, i.e. remove all frames copied into the heap.
__ ld(sp, Address(xthread, JavaThread::cont_entry_offset()));

Expand Down
10 changes: 10 additions & 0 deletions src/hotspot/cpu/x86/interp_masm_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,16 @@ void InterpreterMacroAssembler::call_VM_preemptable(Register oop_result,
assert(arg_1 == c_rarg1, "");
Label resume_pc, not_preempted;

#ifdef ASSERT
{
Label L;
cmpptr(Address(r15_thread, JavaThread::preempt_alternate_return_offset()), NULL_WORD);
jcc(Assembler::equal, L);
stop("Should not have alternate return address set");
bind(L);
}
#endif /* ASSERT */

push_cont_fastpath();

// Make VM call. In case of preemption set last_pc to the one we want to resume to.
Expand Down
24 changes: 0 additions & 24 deletions src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3785,32 +3785,8 @@ address StubGenerator::generate_cont_preempt_stub() {
StubCodeMark mark(this, "StubRoutines","Continuation preempt stub");
address start = __ pc();

#ifdef ASSERT
__ push(rax);
{ Label L;
__ get_thread(rax);
__ cmpptr(r15_thread, rax);
__ jcc(Assembler::equal, L);
__ stop("r15 should have been preserved across VM call");
__ bind(L);
}
__ pop(rax);
#endif

__ reset_last_Java_frame(true);

// Check and reset _preempting flag.
#ifdef ASSERT
{ Label L;
__ movbool(rscratch1, Address(r15_thread, JavaThread::preempting_offset()));
__ testbool(rscratch1);
__ jcc(Assembler::notZero, L);
__ stop("preempting flag should be set");
__ bind(L);
}
#endif
__ movbool(Address(r15_thread, JavaThread::preempting_offset()), false);

// Set rsp to enterSpecial frame, i.e. remove all frames copied into the heap.
__ movptr(rsp, Address(r15_thread, JavaThread::cont_entry_offset()));

Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/interpreter/interpreterRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,6 @@ JRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* current, B
Handle h_obj(current, elem->obj());
assert(Universe::heap()->is_in_or_null(h_obj()),
"must be null or an object");
ThreadOnMonitorEnter tme(current);
ObjectSynchronizer::enter(h_obj, elem->lock(), current);
assert(Universe::heap()->is_in_or_null(elem->obj()),
"must be null or an object");
Expand Down
9 changes: 0 additions & 9 deletions src/hotspot/share/prims/jvmtiExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2868,15 +2868,6 @@ void JvmtiExport::vthread_post_monitor_waited(JavaThread *current, ObjectMonitor

// Finish the VTMS transition temporarily to post the event.
current->rebind_to_jvmti_thread_state_of(vthread());
{
MutexLocker mu(JvmtiThreadState_lock);
JvmtiThreadState* state = current->jvmti_thread_state();
if (state != NULL && state->is_pending_interp_only_mode()) {
JvmtiEventController::enter_interp_only_mode(state);
}
}
assert(current->is_in_VTMS_transition(), "sanity check");
assert(!current->is_in_tmp_VTMS_transition(), "sanity check");
JvmtiVTMSTransitionDisabler::finish_VTMS_transition((jthread)vthread.raw_value(), /* is_mount */ true);

// Post event.
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/prims/jvmtiThreadState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ JvmtiVTMSTransitionDisabler::finish_VTMS_transition(jthread vthread, bool is_mou
JavaThread* thread = JavaThread::current();

assert(thread->is_in_VTMS_transition(), "sanity check");
assert(!thread->is_in_tmp_VTMS_transition(), "sanity check");
thread->set_is_in_VTMS_transition(false);
oop vt = JNIHandles::resolve_external_guard(vthread);
java_lang_Thread::set_is_in_VTMS_transition(vt, false);
Expand Down
20 changes: 8 additions & 12 deletions src/hotspot/share/runtime/continuation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,19 @@ class JvmtiUnmountBeginMark : public StackObj {
JvmtiVTMSTransitionDisabler::start_VTMS_transition((jthread)_vthread.raw_value(), /* is_mount */ false);

// Don't preempt if there is a pending popframe or earlyret operation. This can
// happen in start_VTMS_transition() so we need to check it here.
// be installed in start_VTMS_transition() so we need to check it here.
if (JvmtiExport::can_pop_frame() || JvmtiExport::can_force_early_return()) {
JvmtiThreadState* state = _target->jvmti_thread_state();
if (_target->has_pending_popframe() || (state != nullptr && state->is_earlyret_pending())) {
_failed = true;
}
}

// Don't preempt in case there is an async exception installed since
// we would incorrectly throw it during the unmount logic in the carrier.
if (_target->has_async_exception_condition()) {
_failed = false;
}
} else {
_target->set_is_in_VTMS_transition(true);
java_lang_Thread::set_is_in_VTMS_transition(_vthread(), true);
Expand Down Expand Up @@ -146,34 +152,24 @@ static void verify_preempt_preconditions(JavaThread* target, oop continuation) {
assert(target->last_continuation()->cont_oop(target) == continuation, "");
assert(Continuation::continuation_scope(continuation) == java_lang_VirtualThread::vthread_scope(), "");
assert(!target->has_pending_exception(), "");
assert(!target->is_suspended() JVMTI_ONLY(|| target->is_disable_suspend()) || target->obj_locker_count() > 0, "");
}

int Continuation::try_preempt(JavaThread* target, oop continuation, preempt_kind preempt_kind) {
int Continuation::try_preempt(JavaThread* target, oop continuation) {
verify_preempt_preconditions(target, continuation);

if (LockingMode == LM_LEGACY) {
return freeze_unsupported;
}

if (preempt_kind == freeze_on_monitorenter && !target->is_on_monitorenter()) {
// ObjectLocker or jni_enter case. We can't preempt in these cases.
return freeze_pinned_native;
}

if (!is_safe_vthread_to_preempt(target, target->vthread())) {
return freeze_pinned_native;
}

JVMTI_ONLY(JvmtiUnmountBeginMark jubm(target);)
JVMTI_ONLY(if (jubm.failed()) return freeze_pinned_native;)
target->set_preempting(true);
int res = CAST_TO_FN_PTR(FreezeContFnT, freeze_preempt_entry())(target, target->last_Java_sp());
log_trace(continuations, preempt)("try_preempt: %d", res);
JVMTI_ONLY(jubm.set_preempt_result(res);)
if (res != freeze_ok) {
target->set_preempting(false);
}
return res;
}
#endif // LOOM_MONITOR_SUPPORT
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/runtime/continuation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class Continuation : AllStatic {
static int prepare_thaw(JavaThread* thread, bool return_barrier);
static address thaw_entry();

static int try_preempt(JavaThread* target, oop continuation, preempt_kind preempt_kind) NOT_LOOM_MONITOR_SUPPORT({ return freeze_unsupported; });
static int try_preempt(JavaThread* target, oop continuation) NOT_LOOM_MONITOR_SUPPORT({ return freeze_unsupported; });

static ContinuationEntry* get_continuation_entry_for_continuation(JavaThread* thread, oop continuation);
static ContinuationEntry* get_continuation_entry_for_sp(JavaThread* thread, intptr_t* const sp);
Expand Down
11 changes: 0 additions & 11 deletions src/hotspot/share/runtime/continuationFreezeThaw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,6 @@ freeze_result FreezeBase::recurse_freeze_compiled_frame(frame& f, frame& caller,
NOINLINE freeze_result FreezeBase::recurse_freeze_stub_frame(frame& f, frame& caller) {
DEBUG_ONLY(frame fsender = sender(f);)
assert(fsender.is_compiled_frame(), "sender should be compiled frame");
assert(_thread->is_on_monitorenter(), "");

intptr_t* const stack_frame_top = ContinuationHelper::StubFrame::frame_top(f);
const int fsize = f.cb()->frame_size();
Expand Down Expand Up @@ -1283,7 +1282,6 @@ NOINLINE freeze_result FreezeBase::recurse_freeze_stub_frame(frame& f, frame& ca
NOINLINE freeze_result FreezeBase::recurse_freeze_native_frame(frame& f, frame& caller) {
if (!f.cb()->as_nmethod()->method()->is_object_wait0()) {
assert(f.cb()->as_nmethod()->method()->is_synchronized(), "");
assert(_thread->is_on_monitorenter(), "");
// Synchronized native method case. Unlike the interpreter native wrapper, the compiled
// native wrapper tries to acquire the monitor after marshalling the arguments from the
// caller into the native convention. This is so that we have a valid oopMap in case of
Expand Down Expand Up @@ -1604,15 +1602,6 @@ static void jvmti_mount_end(JavaThread* current, ContinuationWrapper& cont, fram

JRT_BLOCK
current->rebind_to_jvmti_thread_state_of(vth());
{
MutexLocker mu(JvmtiThreadState_lock);
JvmtiThreadState* state = current->jvmti_thread_state();
if (state != NULL && state->is_pending_interp_only_mode()) {
JvmtiEventController::enter_interp_only_mode(state);
}
}
assert(current->is_in_VTMS_transition(), "sanity check");
assert(!current->is_in_tmp_VTMS_transition(), "sanity check");
JvmtiVTMSTransitionDisabler::finish_VTMS_transition((jthread)vth.raw_value(), /* is_mount */ true);

// If pending_jvmti_unmount_event() is true here we are in the preemption
Expand Down
6 changes: 1 addition & 5 deletions src/hotspot/share/runtime/javaThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,6 @@ JavaThread::JavaThread(MemTag mem_tag) :
_active_handles(nullptr),
_free_handle_block(nullptr),
_lock_id(0),
_on_monitorenter(false),

_suspend_flags(0),

Expand Down Expand Up @@ -500,11 +499,9 @@ JavaThread::JavaThread(MemTag mem_tag) :
_jni_monitor_count(0),
_unlocked_inflated_monitor(nullptr),

_preempting(false),
_preempt_alternate_return(nullptr),
_preemption_cancelled(false),
_pending_interrupted_exception(false),
_preempt_alternate_return(nullptr),
DEBUG_ONLY(_obj_locker_count(0) COMMA)

_handshake(this),

Expand Down Expand Up @@ -951,7 +948,6 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
log_debug(jni)("JavaThread %s (tid: " UINTX_FORMAT ") with Objects still locked by JNI MonitorEnter.",
exit_type == JavaThread::normal_exit ? "exiting" : "detaching", os::current_thread_id());
}
assert(obj_locker_count() == 0, "expected 0 but found: " INTX_FORMAT, obj_locker_count());

// These things needs to be done while we are still a Java Thread. Make sure that thread
// is in a consistent state, in case GC happens
Expand Down
68 changes: 27 additions & 41 deletions src/hotspot/share/runtime/javaThread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "oops/oopHandle.hpp"
#include "runtime/continuationEntry.hpp"
#include "runtime/frame.hpp"
#include "runtime/globals.hpp"
#include "runtime/handshake.hpp"
Expand All @@ -51,7 +52,6 @@
#endif

class AsyncExceptionHandshake;
class ContinuationEntry;
class DeoptResourceMark;
class InternalOOMEMark;
class JNIHandleBlock;
Expand Down Expand Up @@ -160,17 +160,12 @@ class JavaThread: public Thread {
// One-element thread local free list
JNIHandleBlock* _free_handle_block;

// ID used as owner for inflated monitors. Same as the tid field of the current
// _vthread object, except during creation of the primordial and JNI attached
// thread cases where this field can have a temporal value.
// ID used as owner for inflated monitors. Same as the j.l.Thread.tid of the
// current _vthread object, except during creation of the primordial and JNI
// attached thread cases where this field can have a temporal value.
int64_t _lock_id;

public:
bool _on_monitorenter;

bool is_on_monitorenter() { return _on_monitorenter; }
void set_on_monitorenter(bool val) { _on_monitorenter = val; }

void set_lock_id(int64_t tid) {
assert(tid >= ThreadIdentifier::initial() && tid < ThreadIdentifier::current(), "invalid tid");
_lock_id = tid;
Expand Down Expand Up @@ -484,25 +479,27 @@ class JavaThread: public Thread {
intx _jni_monitor_count;
ObjectMonitor* _unlocked_inflated_monitor;

bool _preempting;
// This is the field we poke in the interpreter and native
// wrapper (Object.wait) to check for preemption.
address _preempt_alternate_return;
// When preempting on monitorenter we could have acquired the
// monitor after freezing all vthread frames. In that case we
// set this field so that in the preempt stub we call thaw again
// instead of unmounting.
bool _preemption_cancelled;
// For Object.wait() we set this field to know if we need to
// throw IE at the end of thawing before returning to Java.
bool _pending_interrupted_exception;
address _preempt_alternate_return; // used when preempting a thread

#ifdef ASSERT
intx _obj_locker_count;

public:
intx obj_locker_count() { return _obj_locker_count; }
void inc_obj_locker_count() {
assert(_obj_locker_count >= 0, "Must always be greater than 0: " INTX_FORMAT, _obj_locker_count);
_obj_locker_count++;
}
void dec_obj_locker_count() {
_obj_locker_count--;
assert(_obj_locker_count >= 0, "Must always be greater than 0: " INTX_FORMAT, _obj_locker_count);
}
#endif // ASSERT
bool preemption_cancelled() { return _preemption_cancelled; }
void set_preemption_cancelled(bool b) { _preemption_cancelled = b; }

bool pending_interrupted_exception() { return _pending_interrupted_exception; }
void set_pending_interrupted_exception(bool b) { _pending_interrupted_exception = b; }

bool preempting() { return _preempt_alternate_return != nullptr; }
void set_preempt_alternate_return(address val) { _preempt_alternate_return = val; }

private:

Expand Down Expand Up @@ -679,17 +676,6 @@ class JavaThread: public Thread {
inline bool is_vthread_mounted() const;
inline const ContinuationEntry* vthread_continuation() const;

bool preempting() { return _preempting; }
void set_preempting(bool b) { _preempting = b; }

bool preemption_cancelled() { return _preemption_cancelled; }
void set_preemption_cancelled(bool b) { _preemption_cancelled = b; }

bool pending_interrupted_exception() { return _pending_interrupted_exception; }
void set_pending_interrupted_exception(bool b) { _pending_interrupted_exception = b; }

void set_preempt_alternate_return(address val) { _preempt_alternate_return = val; }

private:
DEBUG_ONLY(void verify_frame_info();)

Expand Down Expand Up @@ -910,7 +896,6 @@ class JavaThread: public Thread {
static ByteSize cont_fastpath_offset() { return byte_offset_of(JavaThread, _cont_fastpath); }
static ByteSize held_monitor_count_offset() { return byte_offset_of(JavaThread, _held_monitor_count); }
static ByteSize jni_monitor_count_offset() { return byte_offset_of(JavaThread, _jni_monitor_count); }
static ByteSize preempting_offset() { return byte_offset_of(JavaThread, _preempting); }
static ByteSize preemption_cancelled_offset() { return byte_offset_of(JavaThread, _preemption_cancelled); }
static ByteSize preempt_alternate_return_offset() { return byte_offset_of(JavaThread, _preempt_alternate_return); }
static ByteSize unlocked_inflated_monitor_offset() { return byte_offset_of(JavaThread, _unlocked_inflated_monitor); }
Expand Down Expand Up @@ -1333,13 +1318,14 @@ class JNIHandleMark : public StackObj {
~JNIHandleMark() { _thread->pop_jni_handle_block(); }
};

class ThreadOnMonitorEnter {
JavaThread* _thread;
class NoPreemptMark {
ContinuationEntry* _ce;
bool _unpin;
public:
ThreadOnMonitorEnter(JavaThread* thread) : _thread(thread) {
_thread->set_on_monitorenter(true);
NoPreemptMark(JavaThread* thread) : _ce(thread->last_continuation()), _unpin(false) {
if (_ce != nullptr) _unpin = _ce->pin();
}
~ThreadOnMonitorEnter() { _thread->set_on_monitorenter(false); }
~NoPreemptMark() { if (_unpin) _ce->unpin(); }
};

class ThreadOnMonitorWaitedEvent {
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/runtime/javaThread.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include "memory/universe.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oopHandle.inline.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/atomic.hpp"
#include "runtime/continuation.hpp"
#include "runtime/continuationEntry.inline.hpp"
Expand Down
Loading

0 comments on commit 7396d65

Please sign in to comment.