Skip to content

8365192: post_meth_exit should be in vm state when calling get_jvmti_thread_state #26713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/hotspot/share/prims/jvmtiExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,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()) {
Expand Down Expand Up @@ -1831,7 +1832,11 @@ void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame cur
HandleMark hm(thread);
methodHandle mh(thread, method);

JvmtiThreadState *state = get_jvmti_thread_state(thread);
JvmtiThreadState *state = nullptr;
JavaThread* current = thread; // for JRT_BLOCK
JRT_BLOCK
state = get_jvmti_thread_state(thread);
JRT_BLOCK_END
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JRT_BLOCK is defined as:

#define JRT_BLOCK                                                    \
    {                                                                \
    assert(current == JavaThread::current(), "Must be");             \
    ThreadInVMfromJava __tiv(current);                               \
    JavaThread* THREAD = current; /* For exception macros. */        \
    DEBUG_ONLY(VMEntryWrapper __vew;)

I'd suggest something like this instead of using JRT_BLOCK:

-  JvmtiThreadState *state = get_jvmti_thread_state(thread);
+   JvmtiThreadState *state = nullptr;
+  {
+     ThreadInVMfromJava __tiv(thread);
+     state = get_jvmti_thread_state(thread);
+  }

Alternatively, the JRT_BLOCK can be started at the line 1837 and ended with JRT_BLOCK_END at the line 1875. Not sure, what issue we can encounter with this though. At least, it is worth a try.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand the post_method_entry was called via JRT_BLOCK_ENTRY and not JRT_BLOCK by the reason. We need to be in Java. See comments for the method invocation.

// This is a JRT_BLOCK_ENTRY because we have to stash away the return oop
// before transitioning to VM, and restore it after transitioning back
// to Java. The return oop at the top-of-stack, is not walked by the GC.
JRT_BLOCK_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread* current))
  LastFrameAccessor last_frame(current);
  JvmtiExport::post_method_exit(current, last_frame.method(), last_frame.get_frame());
JRT_END

And thanks for simplification, it is a good idea. I've updated the PR.
I am running tier1-8 for Hotspot tests to ensure that nothing is broken.


if (state == nullptr || !state->is_interp_only_mode()) {
// for any thread that actually wants method exit, interp_only_mode is set
Expand Down Expand Up @@ -1867,7 +1872,6 @@ void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame cur
// Deferred transition to VM, so we can stash away the return oop before GC
// Note that this transition is not needed when throwing an exception, because
// there is no oop to retain.
JavaThread* current = thread; // for JRT_BLOCK
JRT_BLOCK
post_method_exit_inner(thread, mh, state, exception_exit, current_frame, value);
JRT_BLOCK_END
Expand Down