On Sun, 19 Nov 2023 09:41:34 GMT, Serguei Spitsyn <sspit...@openjdk.org> wrote:

>> @dcubed-ojdk
>> I don't know FJP implementation well enough to point at the code where it 
>> happens. However, I observe that new `JavaThread `is being created between 
>> two points of the execution path.
>>  - First point is in the `JvmtiEventControllerPrivate::recompute_enabled()` 
>> at the line where a `ThreadsListHandle` is set. I've added a trap checking 
>> if any `JavaThread` pointed by `state->get_thread()` is not protected by the 
>> `tlh`. I can see this trap is not fired (I can't say it has never been 
>> fired).
>>  - Second point is in the 
>> `JvmtiEventControllerPrivate::enter_interp_only_mode()`. If  a 
>> `ThreadsListHandle` is NOT set then I can observe a `JavaThread` referenced 
>> by the state->get_thread() which is not protected by any TLH. It a TLH added 
>> into `JvmtiEventControllerPrivate::enter_interp_only_mode()` then this 
>> `JavaThread` is observed as protected by TLH.
>> I can provide a full stack trace for this `JavaThread` consisting of two 
>> parts: carrier thread and virtual thread frames. The name of carrier thread 
>> is  `ForkJoinPool-1-worker-1`. The virtual thread is a tested virtual 
>> thread. 
>> The thread dump looks las below:
>> 
>> DBG: enter_interp_only_mode: target: 0x7f93f8043d00 <unnamed> virt: 1 
>> carrier: ForkJoinPool-1-worker-1
>> DBG: ##### NATIVE stacktrace of JavaThread: 0x7f93f8043d00 #####
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> j  fieldacc02.check(Ljava/lang/Object;)I+0
>> j  fieldacc02.lambda$testVirtualThread$0()V+12
>> j  fieldacc02$$Lambda+0x00007f943b001428.run()V+0
>> j  java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 
>> java.base@22-internal
>> j  java.lang.VirtualThread.run(Ljava/lang/Runnable;)V+66 
>> java.base@22-internal
>> j  java.lang.VirtualThread$VThreadContinuation$1.run()V+8 
>> java.base@22-internal
>> j  jdk.internal.vm.Continuation.enter0()V+4 java.base@22-internal
>> j  jdk.internal.vm.Continuation.enter(Ljdk/internal/vm/Continuation;Z)V+1 
>> java.base@22-internal
>> J 124  
>> jdk.internal.vm.Continuation.enterSpecial(Ljdk/internal/vm/Continuation;ZZ)V 
>> java.base@22-internal (0 bytes) @ 0x00007f94c7cdf744 
>> [0x00007f94c7cdf5e0+0x0000000000000164]
>> j  jdk.internal.vm.Continuation.run()V+122 java.base@22-internal
>> j  java.lang.VirtualThread.runContinuation()V+70 java.base@22-internal
>> j  java.lang.VirtualThread$$Lambda+0x00007f943b0496c0.run()V+4 
>> java.base@22-internal
>> j  
>> java.util.concurrent.ForkJoinTask$RunnableExecuteAction.compute()Ljava/lang/Void;+4
>>  java.base@22-internal
>> j  java.util.concur...
>
> The stack trace of current thread (where the assert was fired) can explain 
> what is going on a little bit:
> 
> Current thread (0x00007f93f8043d00):  JavaThread "ForkJoinPool-1-worker-1" 
> daemon [_thread_in_vm, id=16779, stack(0x00007f948a597000,0x00007f948a697000) 
> (1024K)]
> 
> Stack: [0x00007f948a597000,0x00007f948a697000],  sp=0x00007f948a6949e0,  free 
> space=1014k
> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
> code)
> V  [libjvm.so+0x117937d]  
> JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState*)+0x45d  
> (jvmtiEventController.cpp:402)
> V  [libjvm.so+0x1179520]  
> JvmtiEventControllerPrivate::recompute_thread_enabled(JvmtiThreadState*) 
> [clone .part.0]+0x190  (jvmtiEventController.cpp:632)
> V  [libjvm.so+0x117a1e1]  
> JvmtiEventControllerPrivate::thread_started(JavaThread*)+0x351  
> (jvmtiEventController.cpp:1174)
> V  [libjvm.so+0x117e608]  
> JvmtiExport::get_jvmti_thread_state(JavaThread*)+0x98  (jvmtiExport.cpp:424)
> V  [libjvm.so+0x118a86c]  JvmtiExport::post_field_access(JavaThread*, 
> Method*, unsigned char*, Klass*, Handle, _jfieldID*)+0x6c  
> (jvmtiExport.cpp:2214)
> V  [libjvm.so+0x118b3a1]  JvmtiExport::post_field_access_by_jni(JavaThread*, 
> oop, Klass*, _jfieldID*, bool)+0x321  (jvmtiExport.cpp:2202)
> V  [libjvm.so+0x118b4e9]  JvmtiExport::jni_GetField_probe(JavaThread*, 
> _jobject*, oop, Klass*, _jfieldID*, bool)+0x79  (jvmtiExport.cpp:2168)
> V  [libjvm.so+0xf83847]  jni_GetStaticBooleanField+0x257  (jni.cpp:2047)
> C  [libfieldacc02.so+0x379b]  Java_fieldacc02_check+0x6b  (jni.h:1546)
> j  fieldacc02.check(Ljava/lang/Object;)I+0
> j  fieldacc02.lambda$testVirtualThread$0()V+12
> j  fieldacc02$$Lambda+0x00007f943b001428.run()V+0
> j  java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 
> java.base@22-internal
> j  java.lang.VirtualThread.run(Ljava/lang/Runnable;)V+66 java.base@22-internal
> j  java.lang.VirtualThread$VThreadContinuation$1.run()V+8 
> java.base@22-internal
> j  jdk.internal.vm.Continuation.enter0()V+4 java.base@22-internal
> j  jdk.internal.vm.Continuation.enter(Ljdk/internal/vm/Continuation;Z)V+1 
> java.base@22-internal
> J 124  
> jdk.internal.vm.Continuation.enterSpecial(Ljdk/internal/vm/Continuation;ZZ)V 
> java.base@22-internal (0 bytes) @ 0x00007f94c7cdf744 
> [0x00007f94c7cdf5e0+0x0000000000000164]
> j  jdk.internal.vm.Continuation.run()V+122 java.base@22-internal
> j  java.lang.VirtualThread.runContinuation()V+70 java.base@22-internal
> j  java.lang.VirtualThread$$Lambda+0x00007f943b0496c0.run()V+4 
> java.base@22-internal
> j  java.util.concur...

Just to re-iterate what Dan was saying, the TLH is only of use if you are 
accessing threads known to be included in the TLH.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/16686#discussion_r1398540533

Reply via email to