Skip to content

Commit 8e75976

Browse files
authored
Merge pull request #18494 from babsingh/0.42_backports
[0.42] Virtual Thread Support
2 parents 07c68b3 + 38907fd commit 8e75976

File tree

6 files changed

+48
-37
lines changed

6 files changed

+48
-37
lines changed

runtime/j9vm/javanextvmi.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,6 @@ virtualThreadMountBegin(JNIEnv *env, jobject thread)
310310
{
311311
J9VMThread *currentThread = (J9VMThread *)env;
312312

313-
VM_VMHelpers::virtualThreadHideFrames(currentThread, JNI_TRUE);
314-
315313
j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread);
316314
Assert_SC_true(IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObj));
317315

@@ -351,6 +349,8 @@ virtualThreadMountBegin(JNIEnv *env, jobject thread)
351349
enterVThreadTransitionCritical(currentThread, thread);
352350
threadObj = J9_JNI_UNWRAP_REFERENCE(thread);
353351
}
352+
353+
VM_VMHelpers::virtualThreadHideFrames(currentThread, JNI_TRUE);
354354
}
355355

356356
/* Caller must have VMAccess. */
@@ -361,8 +361,6 @@ virtualThreadMountEnd(JNIEnv *env, jobject thread)
361361
J9JavaVM *vm = currentThread->javaVM;
362362
j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread);
363363

364-
VM_VMHelpers::virtualThreadHideFrames(currentThread, JNI_FALSE);
365-
366364
Assert_SC_true(IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObj));
367365

368366
if (TrcEnabled_Trc_SC_VirtualThread_Info) {
@@ -377,6 +375,8 @@ virtualThreadMountEnd(JNIEnv *env, jobject thread)
377375
J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj));
378376
}
379377

378+
VM_VMHelpers::virtualThreadHideFrames(currentThread, JNI_FALSE);
379+
380380
/* Allow thread to be inspected again. */
381381
exitVThreadTransitionCritical(currentThread, threadObj);
382382

@@ -409,7 +409,6 @@ virtualThreadUnmountBegin(JNIEnv *env, jobject thread)
409409
TRIGGER_J9HOOK_VM_VIRTUAL_THREAD_UNMOUNT(vm->hookInterface, currentThread);
410410

411411
enterVThreadTransitionCritical(currentThread, thread);
412-
VM_VMHelpers::virtualThreadHideFrames(currentThread, JNI_TRUE);
413412

414413
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
415414
j9object_t carrierThreadObject = currentThread->carrierThreadObject;
@@ -432,6 +431,8 @@ virtualThreadUnmountBegin(JNIEnv *env, jobject thread)
432431
carrierThreadObject = currentThread->carrierThreadObject;
433432
threadObj = J9_JNI_UNWRAP_REFERENCE(thread);
434433
}
434+
435+
VM_VMHelpers::virtualThreadHideFrames(currentThread, JNI_TRUE);
435436
}
436437

437438
/* Caller must have VMAccess. */
@@ -442,8 +443,6 @@ virtualThreadUnmountEnd(JNIEnv *env, jobject thread)
442443
J9JavaVM *vm = currentThread->javaVM;
443444
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
444445

445-
VM_VMHelpers::virtualThreadHideFrames(currentThread, JNI_FALSE);
446-
447446
j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread);
448447
j9object_t continuationObj = J9VMJAVALANGVIRTUALTHREAD_CONT(currentThread, threadObj);
449448
ContinuationState continuationState = *VM_ContinuationHelpers::getContinuationStateAddress(currentThread, continuationObj);
@@ -465,6 +464,8 @@ virtualThreadUnmountEnd(JNIEnv *env, jobject thread)
465464
vmFuncs->freeTLS(currentThread, threadObj);
466465
}
467466

467+
VM_VMHelpers::virtualThreadHideFrames(currentThread, JNI_FALSE);
468+
468469
/* Allow thread to be inspected again. */
469470
exitVThreadTransitionCritical(currentThread, threadObj);
470471
}
@@ -577,13 +578,31 @@ JNIEXPORT void JNICALL
577578
JVM_VirtualThreadHideFrames(JNIEnv *env, jobject vthread, jboolean hide)
578579
{
579580
J9VMThread *currentThread = (J9VMThread *)env;
581+
J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions;
580582

583+
vmFuncs->internalEnterVMFromJNI(currentThread);
584+
585+
j9object_t vThreadObj = currentThread->threadObject;
586+
Assert_SC_true(IS_JAVA_LANG_VIRTUALTHREAD(currentThread, vThreadObj));
587+
/* Do not allow JVMTI operations because J9VMThread->threadObject is modified
588+
* between the first invocation with hide=true and the second invocation with
589+
* hide=false. Otherwise, JVMTI functions will see an unstable
590+
* J9VMThread->threadObject.
591+
*/
592+
bool hiddenFrames = J9_ARE_ALL_BITS_SET(currentThread->privateFlags, J9_PRIVATE_FLAGS_VIRTUAL_THREAD_HIDDEN_FRAMES);
581593
if (hide) {
582-
Assert_SC_true(J9_ARE_NO_BITS_SET(currentThread->privateFlags, J9_PRIVATE_FLAGS_VIRTUAL_THREAD_HIDDEN_FRAMES));
583-
} else {
584-
Assert_SC_true(J9_ARE_ALL_BITS_SET(currentThread->privateFlags, J9_PRIVATE_FLAGS_VIRTUAL_THREAD_HIDDEN_FRAMES));
594+
Assert_SC_true(!hiddenFrames && (vThreadObj == J9_JNI_UNWRAP_REFERENCE(vthread)));
595+
enterVThreadTransitionCritical(currentThread, vthread);
585596
}
597+
586598
VM_VMHelpers::virtualThreadHideFrames(currentThread, hide);
599+
600+
if (!hide) {
601+
Assert_SC_true(hiddenFrames);
602+
exitVThreadTransitionCritical(currentThread, vThreadObj);
603+
}
604+
605+
vmFuncs->internalExitVMToJNI(currentThread);
587606
}
588607
#endif /* JAVA_SPEC_VERSION >= 20 */
589608

runtime/jvmti/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ j9vm_add_library(j9jvmti SHARED
4949
jvmtiStackFrame.c
5050
jvmtiStartup.c
5151
jvmtiSystemProperties.c
52-
jvmtiThread.c
52+
jvmtiThread.cpp
5353
jvmtiThreadGroup.c
5454
jvmtiTimers.c
5555
jvmtiWatchedField.c

runtime/jvmti/jvmtiHelpers.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -846,25 +846,12 @@ getVirtualThreadState(J9VMThread *currentThread, jthread thread)
846846
break;
847847
case JVMTI_VTHREAD_STATE_STARTED:
848848
{
849-
JNIEnv *env = (JNIEnv *)currentThread;
850-
jfieldID fid = NULL;
851-
jclass jlThread = NULL;
852-
853-
vm->internalVMFunctions->internalExitVMToJNI(currentThread);
854-
jlThread = env->FindClass("java/lang/Thread");
855-
if (NULL != jlThread) {
856-
fid = env->GetFieldID(jlThread, "container", "Ljdk/internal/vm/ThreadContainer;");
857-
}
858-
if ((NULL != fid)
859-
&& (NULL == env->GetObjectField(thread, fid))
860-
) {
849+
j9object_t threadContainer = J9VMJAVALANGTHREAD_CONTAINER(currentThread, vThreadObject);
850+
if (NULL == threadContainer) {
861851
rc = JVMTI_JAVA_LANG_THREAD_STATE_NEW;
862852
} else {
863853
rc = JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE;
864854
}
865-
vm->internalVMFunctions->internalEnterVMFromJNI(currentThread);
866-
/* Re-fetch object to correctly set the isSuspendedInternal field. */
867-
vThreadObject = J9_JNI_UNWRAP_REFERENCE(thread);
868855
break;
869856
}
870857
case JVMTI_VTHREAD_STATE_RUNNABLE:

runtime/jvmti/jvmtiThread.c renamed to runtime/jvmti/jvmtiThread.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include "jvmtiHelpers.h"
2525
#include "jvmti_internal.h"
2626

27+
extern "C" {
28+
2729
typedef struct J9JVMTIRunAgentThreadArgs {
2830
jvmtiEnv *jvmti_env;
2931
jvmtiStartFunction proc;
@@ -180,7 +182,7 @@ jvmtiGetAllThreads(jvmtiEnv *env,
180182

181183
vm->internalVMFunctions->acquireExclusiveVMAccess(currentThread);
182184

183-
threads = j9mem_allocate_memory(sizeof(jthread) * vm->totalThreadCount, J9MEM_CATEGORY_JVMTI_ALLOCATE);
185+
threads = (jthread *)j9mem_allocate_memory(sizeof(jthread) * vm->totalThreadCount, J9MEM_CATEGORY_JVMTI_ALLOCATE);
184186
if (NULL == threads) {
185187
rc = JVMTI_ERROR_OUT_OF_MEMORY;
186188
} else {
@@ -525,7 +527,7 @@ jvmtiGetThreadInfo(jvmtiEnv *env,
525527
j9object_t threadName = J9VMJAVALANGTHREAD_NAME(currentThread, threadObject);
526528

527529
if (NULL == threadName) {
528-
name = j9mem_allocate_memory(1, J9MEM_CATEGORY_JVMTI_ALLOCATE);
530+
name = (char *)j9mem_allocate_memory(1, J9MEM_CATEGORY_JVMTI_ALLOCATE);
529531
if (NULL == name) {
530532
rc = JVMTI_ERROR_OUT_OF_MEMORY;
531533
goto release;
@@ -543,7 +545,7 @@ jvmtiGetThreadInfo(jvmtiEnv *env,
543545
size_t threadNameLen = (NULL == threadName) ? 1 : (strlen(threadName) + 1);
544546

545547
/* Be sure to allocate at least one byte for the nul termination. */
546-
name = j9mem_allocate_memory(threadNameLen, J9MEM_CATEGORY_JVMTI_ALLOCATE);
548+
name = (char *)j9mem_allocate_memory(threadNameLen, J9MEM_CATEGORY_JVMTI_ALLOCATE);
547549
if (NULL == name) {
548550
/* Failed to allocate memory, so release VMTthread and exit. */
549551
releaseOMRVMThreadName(targetThread->omrVMThread);
@@ -698,7 +700,7 @@ jvmtiGetOwnedMonitorInfo(jvmtiEnv *env,
698700

699701
count = walkLocalMonitorRefs(currentThread, NULL, targetThread, threadToWalk, UDATA_MAX);
700702

701-
locks = j9mem_allocate_memory(sizeof(jobject) * count, J9MEM_CATEGORY_JVMTI_ALLOCATE);
703+
locks = (jobject *)j9mem_allocate_memory(sizeof(jobject) * count, J9MEM_CATEGORY_JVMTI_ALLOCATE);
702704
if (NULL == locks) {
703705
rc = JVMTI_ERROR_OUT_OF_MEMORY;
704706
} else if (0 != count) {
@@ -817,7 +819,7 @@ jvmtiGetOwnedMonitorStackDepthInfo(jvmtiEnv *env,
817819

818820
/* Do we have any records at all? */
819821
if (maxRecords > 0) {
820-
resultArray = j9mem_allocate_memory((jlong)maxRecords * sizeof(jvmtiMonitorStackDepthInfo), J9MEM_CATEGORY_JVMTI_ALLOCATE);
822+
resultArray = (jvmtiMonitorStackDepthInfo *)j9mem_allocate_memory((jlong)maxRecords * sizeof(jvmtiMonitorStackDepthInfo), J9MEM_CATEGORY_JVMTI_ALLOCATE);
821823
if (NULL == resultArray) {
822824
maxRecords = 0;
823825
resultArray = NULL;
@@ -970,7 +972,7 @@ jvmtiRunAgentThread(jvmtiEnv *env,
970972
}
971973

972974
/* Create entry args for the thread proc. */
973-
args = j9mem_allocate_memory(sizeof(J9JVMTIRunAgentThreadArgs), J9MEM_CATEGORY_JVMTI);
975+
args = (J9JVMTIRunAgentThreadArgs *)j9mem_allocate_memory(sizeof(J9JVMTIRunAgentThreadArgs), J9MEM_CATEGORY_JVMTI);
974976
if (NULL == args) {
975977
rc = JVMTI_ERROR_OUT_OF_MEMORY;
976978
} else {
@@ -1169,7 +1171,7 @@ static int J9THREAD_PROC
11691171
agentThreadStart(void *entryArg)
11701172
{
11711173
UDATA result = 0;
1172-
J9JVMTIRunAgentThreadArgs *args = entryArg;
1174+
J9JVMTIRunAgentThreadArgs *args = (J9JVMTIRunAgentThreadArgs *)entryArg;
11731175
J9JavaVM *vm = JAVAVM_FROM_ENV((J9JVMTIEnv *)args->jvmti_env);
11741176
J9VMThread *vmThread = vm->internalVMFunctions->currentVMThread(vm);
11751177
PORT_ACCESS_FROM_JAVAVM(vm);
@@ -1189,7 +1191,7 @@ agentThreadStart(void *entryArg)
11891191
static UDATA
11901192
wrappedAgentThreadStart(J9PortLibrary *portLib, void *entryArg)
11911193
{
1192-
J9JVMTIRunAgentThreadArgs *args = entryArg;
1194+
J9JVMTIRunAgentThreadArgs *args = (J9JVMTIRunAgentThreadArgs *)entryArg;
11931195
J9JavaVM *vm = JAVAVM_FROM_ENV((J9JVMTIEnv *)args->jvmti_env);
11941196
J9VMThread *vmThread = vm->internalVMFunctions->currentVMThread(vm);
11951197
jvmtiEnv *jvmti_env = args->jvmti_env;
@@ -1279,10 +1281,10 @@ walkLocalMonitorRefs(J9VMThread *currentThread, jobject *locks, J9VMThread *targ
12791281

12801282
/* Check the local JNI refs. */
12811283
while (NULL != frame) {
1282-
ref = pool_startDo(frame->references, &poolState);
1284+
ref = (j9object_t *)pool_startDo((J9Pool *)frame->references, &poolState);
12831285
while (NULL != ref) {
12841286
ownedMonitorIterator(currentThread, &walkState, ref, ref);
1285-
ref = pool_nextDo(&poolState);
1287+
ref = (j9object_t *)pool_nextDo(&poolState);
12861288
}
12871289
frame = frame->previous;
12881290
}
@@ -1475,3 +1477,5 @@ jvmtiResumeAllVirtualThreads(jvmtiEnv *env,
14751477
TRACE_JVMTI_RETURN(jvmtiResumeAllVirtualThreads);
14761478
}
14771479
#endif /* JAVA_SPEC_VERSION >= 19 */
1480+
1481+
} /* extern "C" */

runtime/jvmti/jvmti_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2238,7 +2238,7 @@ jvmtiSetSystemProperty(jvmtiEnv* env,
22382238
const char* value);
22392239

22402240

2241-
/* ---------------- jvmtiThread.c ---------------- */
2241+
/* ---------------- jvmtiThread.cpp ---------------- */
22422242

22432243
/**
22442244
* @brief

runtime/oti/vmconstantpool.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
247247
<!-- Field references for Java 19 Virtual Thread. -->
248248
<fieldref class="java/lang/Thread" name="cont" signature="Ljdk/internal/vm/Continuation;" versions="19-"/>
249249
<fieldref class="java/lang/Thread" name="holder" signature="Ljava/lang/Thread$FieldHolder;" versions="19-"/>
250+
<fieldref class="java/lang/Thread" name="container" signature="Ljdk/internal/vm/ThreadContainer;" versions="19-"/>
250251
<fieldref class="java/lang/Thread$FieldHolder" name="daemon" signature="Z" versions="19-"/>
251252
<fieldref class="java/lang/Thread$FieldHolder" name="group" signature="Ljava/lang/ThreadGroup;" versions="19-"/>
252253
<fieldref class="java/lang/Thread$FieldHolder" name="priority" signature="I" versions="19-"/>

0 commit comments

Comments
 (0)