mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-09 07:35:49 +00:00
review: simplify interp-only; remove _thread_saved; add more asserts
This commit is contained in:
parent
61d16e8086
commit
e591f869fb
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2491,7 +2491,7 @@ SetOrClearFramePopClosure::do_thread(Thread *target) {
|
||||
_result = JVMTI_ERROR_NO_MORE_FRAMES;
|
||||
return;
|
||||
}
|
||||
assert(_state->get_thread_or_saved() == java_thread, "Must be");
|
||||
assert(_state->get_thread() == java_thread, "Must be");
|
||||
|
||||
RegisterMap reg_map(java_thread,
|
||||
RegisterMap::UpdateMap::include,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -151,11 +151,6 @@ bool JvmtiEnvThreadState::is_virtual() {
|
||||
return _state->is_virtual();
|
||||
}
|
||||
|
||||
// Use _thread_saved if cthread is detached from JavaThread (_thread == nullptr).
|
||||
JavaThread* JvmtiEnvThreadState::get_thread_or_saved() {
|
||||
return _state->get_thread_or_saved();
|
||||
}
|
||||
|
||||
JavaThread* JvmtiEnvThreadState::get_thread() {
|
||||
return _state->get_thread();
|
||||
}
|
||||
@ -344,7 +339,7 @@ void JvmtiEnvThreadState::reset_current_location(jvmtiEvent event_type, bool ena
|
||||
if (enabled) {
|
||||
// If enabling breakpoint, no need to reset.
|
||||
// Can't do anything if empty stack.
|
||||
JavaThread* thread = get_thread_or_saved();
|
||||
JavaThread* thread = get_thread();
|
||||
|
||||
if (event_type == JVMTI_EVENT_SINGLE_STEP &&
|
||||
((thread == nullptr && is_virtual()) || thread->has_last_Java_frame())) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -170,8 +170,6 @@ public:
|
||||
|
||||
inline JvmtiThreadState* jvmti_thread_state() { return _state; }
|
||||
|
||||
// use _thread_saved if cthread is detached from JavaThread
|
||||
JavaThread *get_thread_or_saved();
|
||||
JavaThread *get_thread();
|
||||
inline JvmtiEnv *get_env() { return _env; }
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -217,6 +217,10 @@ class EnterInterpOnlyModeClosure : public HandshakeClosure {
|
||||
|
||||
assert(state != nullptr, "sanity check");
|
||||
assert(state->get_thread() == jt, "handshake unsafe conditions");
|
||||
assert(jt->jvmti_thread_state() == state, "sanity check");
|
||||
assert(!jt->is_interp_only_mode(), "sanity check");
|
||||
assert(!state->is_interp_only_mode(), "sanity check");
|
||||
|
||||
if (!state->is_pending_interp_only_mode()) {
|
||||
_completed = true;
|
||||
return; // The pending flag has been already cleared, so bail out.
|
||||
@ -361,7 +365,8 @@ void VM_ChangeSingleStep::doit() {
|
||||
|
||||
void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state) {
|
||||
EC_TRACE(("[%s] # Entering interpreter only mode",
|
||||
JvmtiTrace::safe_get_thread_name(state->get_thread_or_saved())));
|
||||
JvmtiTrace::safe_get_thread_name(state->get_thread())));
|
||||
|
||||
JavaThread *target = state->get_thread();
|
||||
Thread *current = Thread::current();
|
||||
|
||||
@ -371,7 +376,8 @@ void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state
|
||||
}
|
||||
// This flag will be cleared in EnterInterpOnlyModeClosure handshake.
|
||||
state->set_pending_interp_only_mode(true);
|
||||
if (target == nullptr) { // an unmounted virtual thread
|
||||
if (target == nullptr || // an unmounted virtual thread
|
||||
JvmtiEnvBase::is_thread_carrying_vthread(target, state->get_thread_oop())) { // a vthread carrying thread
|
||||
return; // EnterInterpOnlyModeClosure will be executed right after mount.
|
||||
}
|
||||
EnterInterpOnlyModeClosure hs(state);
|
||||
@ -388,7 +394,8 @@ void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state
|
||||
void
|
||||
JvmtiEventControllerPrivate::leave_interp_only_mode(JvmtiThreadState *state) {
|
||||
EC_TRACE(("[%s] # Leaving interpreter only mode",
|
||||
JvmtiTrace::safe_get_thread_name(state->get_thread_or_saved())));
|
||||
JvmtiTrace::safe_get_thread_name(state->get_thread())));
|
||||
|
||||
if (state->is_pending_interp_only_mode()) {
|
||||
state->set_pending_interp_only_mode(false); // Just clear the pending flag.
|
||||
assert(!state->is_interp_only_mode(), "sanity check");
|
||||
@ -409,7 +416,7 @@ JvmtiEventControllerPrivate::trace_changed(JvmtiThreadState *state, jlong now_en
|
||||
if (changed & bit) {
|
||||
// it changed, print it
|
||||
log_trace(jvmti)("[%s] # %s event %s",
|
||||
JvmtiTrace::safe_get_thread_name(state->get_thread_or_saved()),
|
||||
JvmtiTrace::safe_get_thread_name(state->get_thread()),
|
||||
(now_enabled & bit)? "Enabling" : "Disabling", JvmtiTrace::event_name((jvmtiEvent)ei));
|
||||
}
|
||||
}
|
||||
@ -932,7 +939,7 @@ JvmtiEventControllerPrivate::set_user_enabled(JvmtiEnvBase *env, JavaThread *thr
|
||||
void
|
||||
JvmtiEventControllerPrivate::set_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
|
||||
EC_TRACE(("[%s] # set frame pop - frame=%d",
|
||||
JvmtiTrace::safe_get_thread_name(ets->get_thread_or_saved()),
|
||||
JvmtiTrace::safe_get_thread_name(ets->get_thread()),
|
||||
fpop.frame_number() ));
|
||||
|
||||
ets->get_frame_pops()->set(fpop);
|
||||
@ -943,7 +950,7 @@ JvmtiEventControllerPrivate::set_frame_pop(JvmtiEnvThreadState *ets, JvmtiFrameP
|
||||
void
|
||||
JvmtiEventControllerPrivate::clear_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
|
||||
EC_TRACE(("[%s] # clear frame pop - frame=%d",
|
||||
JvmtiTrace::safe_get_thread_name(ets->get_thread_or_saved()),
|
||||
JvmtiTrace::safe_get_thread_name(ets->get_thread()),
|
||||
fpop.frame_number() ));
|
||||
|
||||
ets->get_frame_pops()->clear(fpop);
|
||||
@ -953,7 +960,7 @@ JvmtiEventControllerPrivate::clear_frame_pop(JvmtiEnvThreadState *ets, JvmtiFram
|
||||
void
|
||||
JvmtiEventControllerPrivate::clear_all_frame_pops(JvmtiEnvThreadState *ets) {
|
||||
EC_TRACE(("[%s] # clear all frame pops",
|
||||
JvmtiTrace::safe_get_thread_name(ets->get_thread_or_saved())
|
||||
JvmtiTrace::safe_get_thread_name(ets->get_thread())
|
||||
));
|
||||
|
||||
ets->get_frame_pops()->clear_all();
|
||||
@ -965,7 +972,7 @@ JvmtiEventControllerPrivate::clear_to_frame_pop(JvmtiEnvThreadState *ets, JvmtiF
|
||||
int cleared_cnt = ets->get_frame_pops()->clear_to(fpop);
|
||||
|
||||
EC_TRACE(("[%s] # clear to frame pop - frame=%d, count=%d",
|
||||
JvmtiTrace::safe_get_thread_name(ets->get_thread_or_saved()),
|
||||
JvmtiTrace::safe_get_thread_name(ets->get_thread()),
|
||||
fpop.frame_number(),
|
||||
cleared_cnt ));
|
||||
|
||||
|
||||
@ -58,19 +58,10 @@ JvmtiThreadState::JvmtiThreadState(JavaThread* thread, oop thread_oop)
|
||||
assert(JvmtiThreadState_lock->is_locked(), "sanity check");
|
||||
|
||||
// The _thread field is a link to the JavaThread associated with JvmtiThreadState.
|
||||
// The _thread_saved field is used for carrier threads only when a virtual thread
|
||||
// is mounted. Otherwise, it must be set to nullptr.
|
||||
// Carrier and virtual threads can temporarily share same JavaThread. In such a case,
|
||||
// only virtual _thread should have a link from JvmtiThreadState to JavaThread.
|
||||
// The carrier thread _thread field is set to nullptr if a virtual thread is monted.
|
||||
// This is important for interp-only mechanism.
|
||||
if (JvmtiEnvBase::is_thread_carrying_vthread(thread, thread_oop)) {
|
||||
_thread = nullptr;
|
||||
_thread_saved = thread;
|
||||
} else { // virtual or non-carrying platform thread
|
||||
_thread = thread;
|
||||
_thread_saved = nullptr;
|
||||
}
|
||||
// A carrier thread shgould always have a stable link to its JavaThread.
|
||||
// The _thread field of a virtual thread should point to the JavaThread when
|
||||
// virtual thread is mounted. It should be set to null when it is unmounted.
|
||||
_thread = thread;
|
||||
_exception_state = ES_CLEARED;
|
||||
_hide_single_stepping = false;
|
||||
_pending_interp_only_mode = false;
|
||||
@ -131,11 +122,11 @@ JvmtiThreadState::JvmtiThreadState(JavaThread* thread, oop thread_oop)
|
||||
|
||||
if (thread != nullptr) {
|
||||
if (thread_oop == nullptr || thread->jvmti_vthread() == nullptr || thread->jvmti_vthread() == thread_oop) {
|
||||
// The JavaThread for carrier or mounted virtual thread case.
|
||||
// The JavaThread for an active carrier or a mounted virtual thread case.
|
||||
// Set this only if thread_oop is current thread->jvmti_vthread().
|
||||
thread->set_jvmti_thread_state(this);
|
||||
thread->set_interp_only_mode(false);
|
||||
}
|
||||
thread->set_interp_only_mode(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +139,11 @@ JvmtiThreadState::~JvmtiThreadState() {
|
||||
}
|
||||
|
||||
// clear this as the state for the thread
|
||||
get_thread()->set_jvmti_thread_state(nullptr);
|
||||
assert(get_thread() != nullptr, "sanity check");
|
||||
if (get_thread()->jvmti_thread_state() == this) { // check for safety
|
||||
get_thread()->set_jvmti_thread_state(nullptr);
|
||||
get_thread()->set_interp_only_mode(false);
|
||||
}
|
||||
|
||||
// zap our env thread states
|
||||
{
|
||||
@ -335,6 +330,9 @@ void JvmtiThreadState::add_env(JvmtiEnvBase *env) {
|
||||
void JvmtiThreadState::enter_interp_only_mode() {
|
||||
assert(_thread != nullptr, "sanity check");
|
||||
assert(!is_interp_only_mode(), "entering interp only when in interp only mode");
|
||||
assert(_thread->jvmti_vthread() == nullptr || _thread->jvmti_vthread() == get_thread_oop(), "sanity check");
|
||||
assert(_thread->jvmti_thread_state() == this, "sanity check");
|
||||
_saved_interp_only_mode = true;
|
||||
_seen_interp_only_mode = true;
|
||||
_thread->set_interp_only_mode(true);
|
||||
invalidate_cur_stack_depth();
|
||||
@ -342,10 +340,9 @@ void JvmtiThreadState::enter_interp_only_mode() {
|
||||
|
||||
void JvmtiThreadState::leave_interp_only_mode() {
|
||||
assert(is_interp_only_mode(), "leaving interp only when not in interp only mode");
|
||||
if (_thread == nullptr) {
|
||||
// Unmounted virtual thread updates the saved value.
|
||||
_saved_interp_only_mode = false;
|
||||
} else {
|
||||
_saved_interp_only_mode = false;
|
||||
if (_thread != nullptr && _thread->jvmti_thread_state() == this) {
|
||||
assert(_thread->jvmti_vthread() == nullptr || _thread->jvmti_vthread() == get_thread_oop(), "sanity check");
|
||||
_thread->set_interp_only_mode(false);
|
||||
}
|
||||
}
|
||||
@ -353,7 +350,7 @@ void JvmtiThreadState::leave_interp_only_mode() {
|
||||
|
||||
// Helper routine used in several places
|
||||
int JvmtiThreadState::count_frames() {
|
||||
JavaThread* thread = get_thread_or_saved();
|
||||
JavaThread* thread = get_thread();
|
||||
javaVFrame *jvf;
|
||||
ResourceMark rm;
|
||||
if (thread == nullptr) {
|
||||
@ -492,8 +489,6 @@ void JvmtiThreadState::update_for_pop_top_frame() {
|
||||
}
|
||||
// force stack depth to be recalculated
|
||||
invalidate_cur_stack_depth();
|
||||
} else {
|
||||
assert(!is_enabled(JVMTI_EVENT_FRAME_POP), "Must have no framepops set");
|
||||
}
|
||||
}
|
||||
|
||||
@ -592,11 +587,8 @@ void JvmtiThreadState::update_thread_oop_during_vm_start() {
|
||||
}
|
||||
}
|
||||
|
||||
// For virtual threads only.
|
||||
void JvmtiThreadState::set_thread(JavaThread* thread) {
|
||||
_thread_saved = nullptr; // Common case.
|
||||
if (!_is_virtual && thread == nullptr) {
|
||||
// Save JavaThread* if carrier thread is being detached.
|
||||
_thread_saved = _thread;
|
||||
}
|
||||
assert(is_virtual(), "sanity check");
|
||||
_thread = thread;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -124,7 +124,6 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
|
||||
private:
|
||||
friend class JvmtiEnv;
|
||||
JavaThread *_thread;
|
||||
JavaThread *_thread_saved;
|
||||
OopHandle _thread_oop_h;
|
||||
// Jvmti Events that cannot be posted in their current context.
|
||||
JvmtiDeferredEventQueue* _jvmti_event_queue;
|
||||
@ -216,7 +215,7 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
|
||||
|
||||
// Used by the interpreter for fullspeed debugging support
|
||||
bool is_interp_only_mode() {
|
||||
return _thread == nullptr ? _saved_interp_only_mode : _thread->is_interp_only_mode();
|
||||
return _saved_interp_only_mode;
|
||||
}
|
||||
void enter_interp_only_mode();
|
||||
void leave_interp_only_mode();
|
||||
@ -245,8 +244,10 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
|
||||
|
||||
int count_frames();
|
||||
|
||||
inline JavaThread *get_thread() { return _thread; }
|
||||
inline JavaThread *get_thread_or_saved(); // return _thread_saved if _thread is null
|
||||
inline JavaThread *get_thread() {
|
||||
assert(is_virtual() || _thread != nullptr, "sanity check");
|
||||
return _thread;
|
||||
}
|
||||
|
||||
// Needed for virtual threads as they can migrate to different JavaThread's.
|
||||
// Also used for carrier threads to clear/restore _thread.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -130,22 +130,21 @@ inline JvmtiThreadState* JvmtiThreadState::state_for(JavaThread *thread, Handle
|
||||
return state;
|
||||
}
|
||||
|
||||
inline JavaThread* JvmtiThreadState::get_thread_or_saved() {
|
||||
// Use _thread_saved if cthread is detached from JavaThread (_thread == null).
|
||||
return (_thread == nullptr && !is_virtual()) ? _thread_saved : _thread;
|
||||
}
|
||||
|
||||
inline void JvmtiThreadState::set_should_post_on_exceptions(bool val) {
|
||||
get_thread_or_saved()->set_should_post_on_exceptions_flag(val ? JNI_TRUE : JNI_FALSE);
|
||||
get_thread()->set_should_post_on_exceptions_flag(val ? JNI_TRUE : JNI_FALSE);
|
||||
}
|
||||
|
||||
inline void JvmtiThreadState::unbind_from(JvmtiThreadState* state, JavaThread* thread) {
|
||||
if (state == nullptr) {
|
||||
assert(!thread->is_interp_only_mode(), "sanity check");
|
||||
return;
|
||||
}
|
||||
// Save thread's interp_only_mode.
|
||||
state->_saved_interp_only_mode = thread->is_interp_only_mode();
|
||||
state->set_thread(nullptr); // Make sure stale _thread value is never used.
|
||||
assert(thread->jvmti_thread_state() == state, "sanity check");
|
||||
assert(state->get_thread() == thread, "sanity check");
|
||||
assert(thread->is_interp_only_mode() == state->_saved_interp_only_mode, "sanity check");
|
||||
if (state->is_virtual()) { // clean _thread link for virtual threads only
|
||||
state->set_thread(nullptr); // make sure stale _thread value is never used
|
||||
}
|
||||
}
|
||||
|
||||
inline void JvmtiThreadState::bind_to(JvmtiThreadState* state, JavaThread* thread) {
|
||||
@ -158,7 +157,7 @@ inline void JvmtiThreadState::bind_to(JvmtiThreadState* state, JavaThread* threa
|
||||
// Bind JavaThread to JvmtiThreadState.
|
||||
thread->set_jvmti_thread_state(state);
|
||||
|
||||
if (state != nullptr) {
|
||||
if (state != nullptr && state->is_virtual()) {
|
||||
// Bind to JavaThread.
|
||||
state->set_thread(thread);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user