Question about the Method Exit Test
Babneet B Singh
sbabneet at ca.ibm.com
Wed Sep 13 16:39:40 UTC 2023
Hi Chris,
Thanks for the explanation. Do you agree with the below analysis? If so, will it be possible to have the test fixed?
vthread - virtual thread.
Between breakpoint_hit1 and breakpoint_hit2, the test doesn't expect the PRODUCER vthread's carrier thread to RUN. So, the test explicitly checks that no JVMTI MethodExit event is triggered by the PRODUCER vthread's carrier thread.
I feel that this check is incorrect because the PRODUCER vthread unmounts and mounts between breakpoint_hit1 and breakpoint_hit2. Whenever a vthread unmounts, the corresponding carrier thread is mounted and allowed to RUN.
PRODUCER vthread unmounts while inserting an element to the SynchronousQueue<https://download.java.net/java/early_access/jdk21/docs/api/java.base/java/util/concurrent/SynchronousQueue.html>, which is a blocking queue. Insert and remove operations are synchronized. vthread seems to yield and unmount if it has to wait on such an operation. Below is the PRODUCER vthread's stack trace during the VirtualThreadUnmount event, which happens between breakpoint_hit1 and breakpoint_hit2.
Hit #1: VirtualThreadUnmount #340: enabling FramePop for method: java/lang/VirtualThread::notifyJvmtiUnmount on virtual thread: 0x27e640
VirtualThreadUnmount #340: method: java/lang/VirtualThread::notifyJvmtiUnmount, thread: VT-PRODUCER#0
JVMTI Stack Trace for thread VT-PRODUCER#0: frame count: 12
0: java/lang/VirtualThread: yieldContinuation()Z
1: java/lang/VirtualThread: tryYield()V
2: java/lang/Thread: yield()V
3: java/util/concurrent/SynchronousQueue$TransferStack: transfer(Ljava/lang/Object;ZJ)Ljava/lang/Object;
4: java/util/concurrent/SynchronousQueue: put(Ljava/lang/Object;)V
5: MethodExitTest: qPut(Ljava/lang/String;)V
6: MethodExitTest: lambda$static$0()V
7: MethodExitTest$$Lambda.0x00000000d7030b98: run()V
8: java/lang/VirtualThread: runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V
9: java/lang/VirtualThread: run(Ljava/lang/Runnable;)V
10: java/lang/VirtualThread$VThreadContinuation$1: run()V
11: jdk/internal/vm/Continuation: enter(Ljdk/internal/vm/Continuation;)V
Regards,
Babneet
________________________________
From: loom-dev <loom-dev-retn at openjdk.org> on behalf of Chris Plummer <chris.plummer at oracle.com>
Sent: August 8, 2023 6:21 PM
To: Gengchen Tuo <Gengchen.Tuo at ibm.com>; loom-dev at openjdk.org <loom-dev at openjdk.org>
Subject: [EXTERNAL] Re: Question about the Method Exit Test
When the first breakpoint is hit, METHOD_EXIT is enabled, but it is only
enabled on the carrier thread. Since we are only executing on the
virtual thread when the breakpoint is hit, no METHOD_EXIT event should
be generated.
// Enable METHOD_EXIT events on the cthread. We should not get one.
LOG("Hit #1: Breakpoint: %s: enabling MethodExit events on carrier
thread: %p\n",
mname, (void*)cthread);
set_event_notification_mode(jvmti, jni, JVMTI_ENABLE,
JVMTI_EVENT_METHOD_EXIT, cthread);
When the 2nd breakpoint is hit, that is when we enable METHOD_EXIT on
the virtual thread:
// Enable METHOD_EXIT events on the vthread. We should get one.
LOG("Hit #2: Breakpoint: %s: enabling MethodExit events on %s thread:
%p\n",
mname, is_virtual ? "virtual" : "carrier", (void*)thread);
set_event_notification_mode(jvmti, jni, JVMTI_ENABLE,
JVMTI_EVENT_METHOD_EXIT, thread);
So now we will see METHOD_EXIT events. I don't think this has anything
to do with lines 59-60, which have to do with deferring the enabling of
the initial breakpoint until after a warmup period:
if (i == MSG_COUNT - 10) {
// Once we have warmed up, enable the first
breakpoint which eventually will
// lead to enabling single stepping.
enableEvents(Thread.currentThread(),
MethodExitTest.class);
}
My guess is this because we have 3 threads in play, and want to make
sure they are all executing in the virtual thread before enabling
METHOD_EXIT events.
And I think it's safe to say you can ignore the "single stepping"
comment. This test was cloned from one of our very early jvmti virtual
threads tests, and that comment appears to be a relic. There is also a
reference in the C file that can go away:
if (strcmp(event_name, "SingleStep") != 0) {
print_stack_trace(jvmti, jni, thread);
}
Chris
On 8/8/23 12:35 PM, Gengchen Tuo wrote:
>
> Hi all. In the Method Exit test
> https://github.com/openjdk/jdk/blob/master/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/MethodExitTest.java ,
> no MethodExit event is expected between the first and the second
> breakpoint hit. Why are we making this assumption? Maybe that’s
> related to line 59 and 60 that I don’t really understand? To my
> knowledge, the producer thread may yield between the two breakpoint
> hits and MethodExit events will be reported.
>
>
>
> I tried to enable the MethodEntry event in the agent code and the test
> started to fail but this shouldn’t affect the test result I believe?
>
>
>
> Thanks in advance
>
> Gengchen
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20230913/09267a88/attachment.htm>
More information about the loom-dev
mailing list