mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8365192: post_meth_exit should be in vm state when calling get_jvmti_thread_state
Reviewed-by: mdoerr, dholmes
This commit is contained in:
parent
f96403986b
commit
8cd4e7d856
@ -418,6 +418,7 @@ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
|
||||
JvmtiThreadState*
|
||||
JvmtiExport::get_jvmti_thread_state(JavaThread *thread, bool allow_suspend) {
|
||||
assert(thread == JavaThread::current(), "must be current thread");
|
||||
assert(thread->thread_state() == _thread_in_vm, "thread should be in vm");
|
||||
if (thread->is_vthread_mounted() && thread->jvmti_thread_state() == nullptr) {
|
||||
JvmtiEventController::thread_started(thread);
|
||||
if (allow_suspend && thread->is_suspended()) {
|
||||
@ -1826,47 +1827,50 @@ void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame cu
|
||||
}
|
||||
|
||||
void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame current_frame) {
|
||||
// At this point we only have the address of a "raw result" and
|
||||
// we just call into the interpreter to convert this into a jvalue.
|
||||
// This method always makes transition to vm and back where GC can happen.
|
||||
// So it is needed to preserve result and then restore it
|
||||
// even if events are not actually posted.
|
||||
// Saving oop_result into value.j is deferred until jvmti state is ready.
|
||||
HandleMark hm(thread);
|
||||
methodHandle mh(thread, method);
|
||||
|
||||
JvmtiThreadState *state = get_jvmti_thread_state(thread);
|
||||
|
||||
if (state == nullptr || !state->is_interp_only_mode()) {
|
||||
// for any thread that actually wants method exit, interp_only_mode is set
|
||||
return;
|
||||
}
|
||||
|
||||
Handle result;
|
||||
oop oop_result;
|
||||
jvalue value;
|
||||
value.j = 0L;
|
||||
|
||||
if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {
|
||||
// At this point we only have the address of a "raw result" and
|
||||
// we just call into the interpreter to convert this into a jvalue.
|
||||
oop oop_result;
|
||||
BasicType type = current_frame.interpreter_frame_result(&oop_result, &value);
|
||||
assert(type == T_VOID || current_frame.interpreter_frame_expression_stack_size() > 0,
|
||||
"Stack shouldn't be empty");
|
||||
if (is_reference_type(type)) {
|
||||
result = Handle(thread, oop_result);
|
||||
value.l = JNIHandles::make_local(thread, result());
|
||||
}
|
||||
BasicType type = current_frame.interpreter_frame_result(&oop_result, &value);
|
||||
assert(mh->is_native() || type == T_VOID || current_frame.interpreter_frame_expression_stack_size() > 0,
|
||||
"Stack shouldn't be empty");
|
||||
if (is_reference_type(type)) {
|
||||
result = Handle(thread, oop_result);
|
||||
}
|
||||
|
||||
// Do not allow NotifyFramePop to add new FramePop event request at
|
||||
// depth 0 as it is already late in the method exiting dance.
|
||||
state->set_top_frame_is_exiting();
|
||||
|
||||
// Deferred transition to VM, so we can stash away the return oop before GC.
|
||||
JvmtiThreadState* state; // should be initialized in vm state only
|
||||
JavaThread* current = thread; // for JRT_BLOCK
|
||||
bool interp_only; // might be changed in JRT_BLOCK_END
|
||||
JRT_BLOCK
|
||||
post_method_exit_inner(thread, mh, state, false /* not exception exit */, current_frame, value);
|
||||
state = get_jvmti_thread_state(thread);
|
||||
interp_only = state != nullptr && state->is_interp_only_mode();
|
||||
if (interp_only) {
|
||||
if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {
|
||||
// Deferred saving Object result into value.
|
||||
if (is_reference_type(type)) {
|
||||
value.l = JNIHandles::make_local(thread, result());
|
||||
}
|
||||
}
|
||||
|
||||
// Do not allow NotifyFramePop to add new FramePop event request at
|
||||
// depth 0 as it is already late in the method exiting dance.
|
||||
state->set_top_frame_is_exiting();
|
||||
|
||||
post_method_exit_inner(thread, mh, state, false /* not exception exit */, current_frame, value);
|
||||
}
|
||||
JRT_BLOCK_END
|
||||
|
||||
// The JRT_BLOCK_END can safepoint in ThreadInVMfromJava desctructor. Now it is safe to allow
|
||||
// adding FramePop event requests as no safepoint can happen before removing activation.
|
||||
state->clr_top_frame_is_exiting();
|
||||
|
||||
if (interp_only) {
|
||||
// The JRT_BLOCK_END can safepoint in ThreadInVMfromJava destructor. Now it is safe to allow
|
||||
// adding FramePop event requests as no safepoint can happen before removing activation.
|
||||
state->clr_top_frame_is_exiting();
|
||||
}
|
||||
if (result.not_null() && !mh->is_native()) {
|
||||
// We have to restore the oop on the stack for interpreter frames
|
||||
*(oop*)current_frame.interpreter_frame_tos_address() = result();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user