Skip to content

Commit

Permalink
Merge pull request #16325 from babsingh/null_checks_vt_list
Browse files Browse the repository at this point in the history
Add asserts and tracepoints in JVM_VirtualThread* functions
  • Loading branch information
tajila committed Nov 16, 2022
2 parents 4c499f8 + 744ab4a commit e5ee930
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 13 deletions.
16 changes: 15 additions & 1 deletion runtime/j9vm/j9scar.tdf
@@ -1,4 +1,4 @@
// Copyright (c) 2006, 2021 IBM Corp. and others
// Copyright (c) 2006, 2022 IBM Corp. and others
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -350,3 +350,17 @@ TraceEvent=Trc_SC_LoadLibrary_OpenShared NoEnv Overhead=1 Level=3 Template="JVM_
TraceEvent=Trc_SC_LoadLibrary_OpenShared_Decorate NoEnv Overhead=1 Level=3 Template="JVM_LoadLibrary(name=%s) j9sl_open_shared_library J9PORT_SLOPEN_DECORATE"

TraceExit=Trc_SC_LoadLibrary_Exit NoEnv Overhead=1 Level=2 Template="JVM_LoadLibrary -- return 0x%zx"

TraceEntry=Trc_SC_VirtualThreadMountBegin_Entry Overhead=1 Level=3 Template="thread = 0x%p, firstMount = %d"
TraceExit=Trc_SC_VirtualThreadMountBegin_Exit Overhead=1 Level=3 Template="thread = 0x%p, firstMount = %d"

TraceEntry=Trc_SC_VirtualThreadMountEnd_Entry Overhead=1 Level=3 Template="thread = 0x%p, firstMount = %d"
TraceExit=Trc_SC_VirtualThreadMountEnd_Exit Overhead=1 Level=3 Template="thread = 0x%p, firstMount = %d"

TraceEntry=Trc_SC_VirtualThreadUnmountBegin_Entry Overhead=1 Level=3 Template="thread = 0x%p, lastUnmount = %d"
TraceExit=Trc_SC_VirtualThreadUnmountBegin_Exit Overhead=1 Level=3 Template="thread = 0x%p, lastUnmount = %d"

TraceEntry=Trc_SC_VirtualThreadUnmountEnd_Entry Overhead=1 Level=3 Template="thread = 0x%p, lastUnmount = %d"
TraceExit=Trc_SC_VirtualThreadUnmountEnd_Exit Overhead=1 Level=3 Template="thread = 0x%p, lastUnmount = %d"

TraceEvent=Trc_SC_VirtualThread_Info Overhead=1 Level=3 Test Template="virtualThreadObj = 0x%p, virtualThreadState = 0x%p, virtualThreadInspectorCount = %lld, carrierThreadObj = 0x%p, continuationObj = 0x%p, J9VMContinuation = 0x%p"
104 changes: 92 additions & 12 deletions runtime/j9vm/javanextvmi.cpp
Expand Up @@ -19,7 +19,6 @@
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
*******************************************************************************/
#include <assert.h>
#include <jni.h>

#include "bcverify_api.h"
Expand Down Expand Up @@ -52,13 +51,13 @@ extern IDATA (*f_monitorNotifyAll)(omrthread_monitor_t monitor);
JNIEXPORT void JNICALL
JVM_DefineArchivedModules(JNIEnv *env, jobject obj1, jobject obj2)
{
assert(!"JVM_DefineArchivedModules unimplemented");
Assert_SC_true(!"JVM_DefineArchivedModules unimplemented");
}

JNIEXPORT void JNICALL
JVM_LogLambdaFormInvoker(JNIEnv *env, jstring str)
{
assert(!"JVM_LogLambdaFormInvoker unimplemented");
Assert_SC_true(!"JVM_LogLambdaFormInvoker unimplemented");
}

JNIEXPORT jboolean JNICALL
Expand Down Expand Up @@ -188,13 +187,13 @@ JVM_GetExtendedNPEMessage(JNIEnv *env, jthrowable throwableObj)
JNIEXPORT void JNICALL
JVM_DumpClassListToFile(JNIEnv *env, jstring str)
{
assert(!"JVM_DumpClassListToFile unimplemented");
Assert_SC_true(!"JVM_DumpClassListToFile unimplemented");
}

JNIEXPORT void JNICALL
JVM_DumpDynamicArchive(JNIEnv *env, jstring str)
{
assert(!"JVM_DumpDynamicArchive unimplemented");
Assert_SC_true(!"JVM_DumpDynamicArchive unimplemented");
}
#endif /* JAVA_SPEC_VERSION >= 17 */

Expand All @@ -213,21 +212,21 @@ JVM_IsFinalizationEnabled(JNIEnv *env)
JNIEXPORT void JNICALL
JVM_ReportFinalizationComplete(JNIEnv *env, jobject obj)
{
assert(!"JVM_ReportFinalizationComplete unimplemented");
Assert_SC_true(!"JVM_ReportFinalizationComplete unimplemented");
}
#endif /* JAVA_SPEC_VERSION >= 18 */

#if JAVA_SPEC_VERSION >= 19
JNIEXPORT void JNICALL
JVM_LoadZipLibrary(void)
{
assert(!"JVM_LoadZipLibrary unimplemented");
Assert_SC_true(!"JVM_LoadZipLibrary unimplemented");
}

JNIEXPORT void JNICALL
JVM_RegisterContinuationMethods(JNIEnv *env, jclass clz)
{
assert(!"JVM_RegisterContinuationMethods unimplemented");
Assert_SC_true(!"JVM_RegisterContinuationMethods unimplemented");
}

JNIEXPORT jboolean JNICALL
Expand All @@ -254,11 +253,25 @@ JVM_VirtualThreadMountBegin(JNIEnv *env, jobject thread, jboolean firstMount)
J9JavaVM *vm = currentThread->javaVM;
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;

Trc_SC_VirtualThreadMountBegin_Entry(currentThread, thread, firstMount);

vmFuncs->internalEnterVMFromJNI(currentThread);
f_monitorEnter(vm->liveVirtualThreadListMutex);
j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread);

assert(IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObj));
Assert_SC_true(IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObj));

if (TrcEnabled_Trc_SC_VirtualThread_Info) {
j9object_t continuationObj = J9VMJAVALANGVIRTUALTHREAD_CONT(currentThread, threadObj);
Trc_SC_VirtualThread_Info(
currentThread,
threadObj,
J9VMJAVALANGVIRTUALTHREAD_STATE(currentThread, threadObj),
J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset),
J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, threadObj),
continuationObj,
J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj));
}

while (vm->inspectingLiveVirtualThreadList
|| (0 != J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset))
Expand All @@ -282,6 +295,8 @@ JVM_VirtualThreadMountBegin(JNIEnv *env, jobject thread, jboolean firstMount)

f_monitorExit(vm->liveVirtualThreadListMutex);
vmFuncs->internalExitVMToJNI(currentThread);

Trc_SC_VirtualThreadMountBegin_Exit(currentThread, thread, firstMount);
}

JNIEXPORT void JNICALL
Expand All @@ -291,10 +306,24 @@ JVM_VirtualThreadMountEnd(JNIEnv *env, jobject thread, jboolean firstMount)
J9JavaVM *vm = currentThread->javaVM;
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;

Trc_SC_VirtualThreadMountEnd_Entry(currentThread, thread, firstMount);

vmFuncs->internalEnterVMFromJNI(currentThread);
f_monitorEnter(vm->liveVirtualThreadListMutex);
j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread);

if (TrcEnabled_Trc_SC_VirtualThread_Info) {
j9object_t continuationObj = J9VMJAVALANGVIRTUALTHREAD_CONT(currentThread, threadObj);
Trc_SC_VirtualThread_Info(
currentThread,
threadObj,
J9VMJAVALANGVIRTUALTHREAD_STATE(currentThread, threadObj),
J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset),
J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, threadObj),
continuationObj,
J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj));
}

if (firstMount) {
if (NULL == vm->liveVirtualThreadList) {
J9Class *virtualThreadClass = J9OBJECT_CLAZZ(currentThread, J9_JNI_UNWRAP_REFERENCE(thread));
Expand Down Expand Up @@ -322,6 +351,14 @@ JVM_VirtualThreadMountEnd(JNIEnv *env, jobject thread, jboolean firstMount)
}

if (NULL != vm->liveVirtualThreadList) {
j9object_t threadPrev = J9OBJECT_OBJECT_LOAD(currentThread, threadObj, vm->virtualThreadLinkPreviousOffset);
j9object_t threadNext = J9OBJECT_OBJECT_LOAD(currentThread, threadObj, vm->virtualThreadLinkNextOffset);

/* Non-null previous and next elements in the list suggest that the thread has
* already been added to the list. Only add to the list if the previous and
* next elements in the list are null.
*/
Assert_SC_true((NULL == threadPrev) && (NULL == threadNext));
j9object_t root = *(vm->liveVirtualThreadList);
j9object_t rootPrev = J9OBJECT_OBJECT_LOAD(currentThread, root, vm->virtualThreadLinkPreviousOffset);

Expand All @@ -336,7 +373,7 @@ JVM_VirtualThreadMountEnd(JNIEnv *env, jobject thread, jboolean firstMount)
}

/* Allow thread to be inspected again. */
assert(-1 == J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset));
Assert_SC_true(-1 == J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset));
J9OBJECT_I64_STORE(currentThread, threadObj, vm->virtualThreadInspectorCountOffset, 0);

/* If isSuspendedByJVMTI is non-zero, J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND is set
Expand All @@ -352,6 +389,8 @@ JVM_VirtualThreadMountEnd(JNIEnv *env, jobject thread, jboolean firstMount)
f_monitorExit(vm->liveVirtualThreadListMutex);

vmFuncs->internalExitVMToJNI(currentThread);

Trc_SC_VirtualThreadMountEnd_Exit(currentThread, thread, firstMount);
}

JNIEXPORT void JNICALL
Expand All @@ -361,10 +400,24 @@ JVM_VirtualThreadUnmountBegin(JNIEnv *env, jobject thread, jboolean lastUnmount)
J9JavaVM *vm = currentThread->javaVM;
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;

Trc_SC_VirtualThreadUnmountBegin_Entry(currentThread, thread, lastUnmount);

vmFuncs->internalEnterVMFromJNI(currentThread);
f_monitorEnter(vm->liveVirtualThreadListMutex);
j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread);

if (TrcEnabled_Trc_SC_VirtualThread_Info) {
j9object_t continuationObj = J9VMJAVALANGVIRTUALTHREAD_CONT(currentThread, threadObj);
Trc_SC_VirtualThread_Info(
currentThread,
threadObj,
J9VMJAVALANGVIRTUALTHREAD_STATE(currentThread, threadObj),
J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset),
J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, threadObj),
continuationObj,
J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj));
}

while (vm->inspectingLiveVirtualThreadList
|| (0 != J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset))
) {
Expand All @@ -390,16 +443,27 @@ JVM_VirtualThreadUnmountBegin(JNIEnv *env, jobject thread, jboolean lastUnmount)
j9object_t threadPrev = J9OBJECT_OBJECT_LOAD(currentThread, threadObj, vm->virtualThreadLinkPreviousOffset);
j9object_t threadNext = J9OBJECT_OBJECT_LOAD(currentThread, threadObj, vm->virtualThreadLinkNextOffset);

/* Remove thread from list. The root will never be removed. */
/* Non-null previous and next elements in the list suggest that the thread has
* been added to the list. Only remove from the list if the previous and next
* elements in the list are non-null.
*/
Assert_SC_true((NULL != threadPrev) && (NULL != threadNext));
/* Remove thread from the list. The root will never be removed. */
J9OBJECT_OBJECT_STORE(currentThread, threadPrev, vm->virtualThreadLinkNextOffset, threadNext);
J9OBJECT_OBJECT_STORE(currentThread, threadNext, vm->virtualThreadLinkPreviousOffset, threadPrev);

/* Reset previous and next fields in the thread object to null. */
J9OBJECT_OBJECT_STORE(currentThread, threadObj, vm->virtualThreadLinkNextOffset, NULL);
J9OBJECT_OBJECT_STORE(currentThread, threadObj, vm->virtualThreadLinkPreviousOffset, NULL);
}

TRIGGER_J9HOOK_VM_VIRTUAL_THREAD_END(vm->hookInterface, currentThread);
}

f_monitorExit(vm->liveVirtualThreadListMutex);
vmFuncs->internalExitVMToJNI(currentThread);

Trc_SC_VirtualThreadUnmountBegin_Exit(currentThread, thread, lastUnmount);
}

JNIEXPORT void JNICALL
Expand All @@ -409,10 +473,24 @@ JVM_VirtualThreadUnmountEnd(JNIEnv *env, jobject thread, jboolean lastUnmount)
J9JavaVM *vm = currentThread->javaVM;
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;

Trc_SC_VirtualThreadUnmountEnd_Entry(currentThread, thread, lastUnmount);

vmFuncs->internalEnterVMFromJNI(currentThread);
f_monitorEnter(vm->liveVirtualThreadListMutex);
j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread);

if (TrcEnabled_Trc_SC_VirtualThread_Info) {
j9object_t continuationObj = J9VMJAVALANGVIRTUALTHREAD_CONT(currentThread, threadObj);
Trc_SC_VirtualThread_Info(
currentThread,
threadObj,
J9VMJAVALANGVIRTUALTHREAD_STATE(currentThread, threadObj),
J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset),
J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, threadObj),
continuationObj,
J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj));
}

if (lastUnmount) {
vmFuncs->freeTLS(currentThread, threadObj);
/* CleanupContinuation */
Expand All @@ -421,12 +499,14 @@ JVM_VirtualThreadUnmountEnd(JNIEnv *env, jobject thread, jboolean lastUnmount)
}

/* Allow thread to be inspected again. */
assert(-1 == J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset));
Assert_SC_true(-1 == J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset));
J9OBJECT_I64_STORE(currentThread, threadObj, vm->virtualThreadInspectorCountOffset, 0);
f_monitorNotifyAll(vm->liveVirtualThreadListMutex);

f_monitorExit(vm->liveVirtualThreadListMutex);
vmFuncs->internalExitVMToJNI(currentThread);

Trc_SC_VirtualThreadUnmountEnd_Exit(currentThread, thread, lastUnmount);
}
#endif /* JAVA_SPEC_VERSION >= 19 */

Expand Down

0 comments on commit e5ee930

Please sign in to comment.