Skip to content

Commit

Permalink
Merge pull request #15254 from fengxue-IS/jvmti_stub
Browse files Browse the repository at this point in the history
add JVMTI callback/hook for virtualThread
  • Loading branch information
tajila authored Jun 17, 2022
2 parents cddb8bf + fead2f3 commit dbe2071
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 9 deletions.
5 changes: 4 additions & 1 deletion runtime/include/jvmti.h.m4
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,10 @@ ifelse(eval(JAVA_SPEC_VERSION >= 11), 1, [ JVMTI_EVENT_SAMPLED_OBJECT_ALLOC = 86
ifelse(eval(JAVA_SPEC_VERSION >= 19), 1, [ JVMTI_EVENT_VIRTUAL_THREAD_START = 87,], [dnl])
ifelse(eval(JAVA_SPEC_VERSION >= 19), 1, [ JVMTI_EVENT_VIRTUAL_THREAD_END = 88,], [dnl])

JVMTI_MAX_EVENT_TYPE_VAL = 86,
ifelse(eval(JAVA_SPEC_VERSION >= 19), 1, [ JVMTI_MAX_EVENT_TYPE_VAL = 88,],[
ifelse(eval(JAVA_SPEC_VERSION >= 11), 1, [ JVMTI_MAX_EVENT_TYPE_VAL = 86,],[
JVMTI_MAX_EVENT_TYPE_VAL = 84,])])

jvmtiEventEnsureWideEnum = 0x1000000 /* ensure 4-byte enum */
} jvmtiEvent;

Expand Down
7 changes: 6 additions & 1 deletion runtime/jvmti/j9jvmti.tdf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//Copyright (c) 2006, 2020 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 @@ -630,3 +630,8 @@ TraceEvent=Trc_JVMTI_lookupNativeAddressHelper_Bound_ClassLoader_Library Overhea
TraceEvent=Trc_JVMTI_lookupNativeAddressHelper_Bound_Null_Library Overhead=1 Level=3 Template="lookupNativeAddressHelper (bound without classloader library) - nativeMethod (%p) longJNI (%s) shortJNI (%s) functionArgCount (%zu)"
TraceEvent=Trc_JVMTI_lookupNativeAddressHelper_Bound_Agent_Library Overhead=1 Level=3 Template="lookupNativeAddressHelper (bound with agent library) - nativeMethod (%p) nativeLibrary (%p) longJNI (%s) shortJNI (%s) functionArgCount (%zu)"
TraceExit=Trc_JVMTI_lookupNativeAddressHelper_Exit Overhead=1 Level=3 Template="lookupNativeAddressHelper - prefixOffset (%zu)"

TraceEntry=Trc_JVMTI_jvmtiHookVirtualThreadEnd_Entry Overhead=1 Level=5 Noenv Template="HookVirtualThreadEnd"
TraceExit=Trc_JVMTI_jvmtiHookVirtualThreadEnd_Exit Overhead=1 Level=5 Noenv Template="HookVirtualThreadEnd"
TraceEntry=Trc_JVMTI_jvmtiHookVirtualThreadStarted_Entry Overhead=1 Level=5 Noenv Template="HookVirtualThreadStarted"
TraceExit=Trc_JVMTI_jvmtiHookVirtualThreadStarted_Exit Overhead=1 Level=5 Noenv Template="HookVirtualThreadStarted"
15 changes: 15 additions & 0 deletions runtime/jvmti/jvmtiCapability.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ jvmtiGetPotentialCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr
}
#endif /* JAVA_SPEC_VERSION >= 11 */

#if JAVA_SPEC_VERSION >= 19
if (isEventHookable(j9env, JVMTI_EVENT_VIRTUAL_THREAD_START)
&& isEventHookable(j9env, JVMTI_EVENT_VIRTUAL_THREAD_END)
) {
rv_capabilities.can_support_virtual_threads = 1;
}
#endif /* JAVA_SPEC_VERSION >= 19 */

if (isEventHookable(j9env, JVMTI_EVENT_NATIVE_METHOD_BIND)) {
rv_capabilities.can_generate_native_method_bind_events = 1;
}
Expand Down Expand Up @@ -591,6 +599,13 @@ mapCapabilitiesToEvents(J9JVMTIEnv * j9env, jvmtiCapabilities * capabilities, J9
}
#endif /* JAVA_SPEC_VERSION >= 11 */

#if JAVA_SPEC_VERSION >= 19
if (capabilities->can_support_virtual_threads) {
rc |= eventHookFunction(j9env, JVMTI_EVENT_VIRTUAL_THREAD_START);
rc |= eventHookFunction(j9env, JVMTI_EVENT_VIRTUAL_THREAD_END);
}
#endif /* JAVA_SPEC_VERSION >= 19 */

if (capabilities->can_generate_object_free_events) {
rc |= eventHookFunction(j9env, JVMTI_EVENT_OBJECT_FREE);
}
Expand Down
12 changes: 11 additions & 1 deletion runtime/jvmti/jvmtiEventManagement.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2020 IBM Corp. and others
* Copyright (c) 1991, 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 @@ -156,6 +156,13 @@ jvmtiSetEventNotificationMode(jvmtiEnv* env,
break;
#endif /* JAVA_SPEC_VERSION >= 11 */

#if JAVA_SPEC_VERSION >= 19
case JVMTI_EVENT_VIRTUAL_THREAD_START:
case JVMTI_EVENT_VIRTUAL_THREAD_END:
ENSURE_CAPABILITY(env, can_support_virtual_threads);
break;
#endif /* JAVA_SPEC_VERSION >= 19 */

case JVMTI_EVENT_NATIVE_METHOD_BIND:
ENSURE_CAPABILITY(env, can_generate_native_method_bind_events);
break;
Expand Down Expand Up @@ -196,6 +203,9 @@ jvmtiSetEventNotificationMode(jvmtiEnv* env,
#if JAVA_SPEC_VERSION >= 11
case JVMTI_EVENT_SAMPLED_OBJECT_ALLOC:
#endif /* JAVA_SPEC_VERSION >= 11 */
#if JAVA_SPEC_VERSION >= 19
case JVMTI_EVENT_VIRTUAL_THREAD_START:
#endif /* JAVA_SPEC_VERSION >= 19 */
if (event_thread != NULL) {
JVMTI_ERROR(JVMTI_ERROR_ILLEGAL_ARGUMENT);
}
Expand Down
10 changes: 7 additions & 3 deletions runtime/jvmti/jvmtiHelpers.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2020 IBM Corp. and others
* Copyright (c) 1991, 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 @@ -412,8 +412,12 @@ prepareForEvent(J9JVMTIEnv * j9env, J9VMThread * currentThread, J9VMThread * eve
/* Allow the VM_DEATH and THREAD_END event to be sent on a dead thread, but no others */

if (currentThread->publicFlags & J9_PUBLIC_FLAGS_STOPPED) {
if (eventNumber != JVMTI_EVENT_VM_DEATH &&
eventNumber != JVMTI_EVENT_THREAD_END) {
if ((eventNumber != JVMTI_EVENT_VM_DEATH)
&& (eventNumber != JVMTI_EVENT_THREAD_END)
#if JAVA_SPEC_VERSION >= 19
&& (eventNumber != JVMTI_EVENT_VIRTUAL_THREAD_END)
#endif /* JAVA_SPEC_VERSION >= 19 */
) {
return FALSE;
}
}
Expand Down
79 changes: 77 additions & 2 deletions runtime/jvmti/jvmtiHook.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2021 IBM Corp. and others
* Copyright (c) 1991, 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 @@ -145,6 +145,10 @@ static void jvmtiHookGetEnv (J9HookInterface** hook, UDATA eventNum, void* event
static void jvmtiHookVmDumpStart (J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData);
static void jvmtiHookVmDumpEnd (J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData);
static UDATA methodExists(J9Class * methodClass, U_8 * nameData, UDATA nameLength, J9UTF8 * signature);
#if JAVA_SPEC_VERSION >= 19
static void jvmtiHookVirtualThreadStarted (J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData);
static void jvmtiHookVirtualThreadEnd (J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData);
#endif /* JAVA_SPEC_VERSION >= 19 */

static void
jvmtiHookThreadEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)
Expand Down Expand Up @@ -337,6 +341,69 @@ jvmtiHookMethodEnter(J9HookInterface** hook, UDATA eventNum, void* eventData, vo
TRACE_JVMTI_EVENT_RETURN(jvmtiHookMethodEnter);
}

#if JAVA_SPEC_VERSION >= 19
static void
jvmtiHookVirtualThreadStarted(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData)
{
J9VirtualThreadStartedEvent *data = eventData;
J9JVMTIEnv *j9env = userData;
jvmtiEventThreadStart callback = j9env->callbacks.VirtualThreadStart;
J9VMThread *currentThread = data->currentThread;

Trc_JVMTI_jvmtiHookVirtualThreadStarted_Entry();

ENSURE_EVENT_PHASE_START_OR_LIVE(jvmtiHookVirtualThreadStarted, j9env);

/* Call the event callback */

if (NULL != callback) {
jthread threadRef = NULL;
UDATA hadVMAccess = 0;
UDATA javaOffloadOldState = 0;

if (prepareForEvent(
j9env, currentThread, currentThread, JVMTI_EVENT_VIRTUAL_THREAD_START,
&threadRef, &hadVMAccess, FALSE, 0, &javaOffloadOldState)
) {
callback((jvmtiEnv *)j9env, (JNIEnv *)currentThread, threadRef);
finishedEvent(currentThread, JVMTI_EVENT_VIRTUAL_THREAD_START, hadVMAccess, javaOffloadOldState);
}
}

TRACE_JVMTI_EVENT_RETURN(jvmtiHookVirtualThreadStarted);
}

static void
jvmtiHookVirtualThreadEnd(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData)
{
J9VirtualThreadEndEvent *data = eventData;
J9JVMTIEnv *j9env = userData;
jvmtiEventThreadEnd callback = j9env->callbacks.VirtualThreadEnd;
J9VMThread *currentThread = data->currentThread;

Trc_JVMTI_jvmtiHookVirtualThreadEnd_Entry();

ENSURE_EVENT_PHASE_START_OR_LIVE(jvmtiHookVirtualThreadEnd, j9env);

/* Call the event callback */

if (NULL != callback) {
jthread threadRef = NULL;
UDATA hadVMAccess = 0;
UDATA javaOffloadOldState = 0;

if (prepareForEvent(
j9env, currentThread, currentThread, JVMTI_EVENT_VIRTUAL_THREAD_END,
&threadRef, &hadVMAccess, FALSE, 0, &javaOffloadOldState)
) {
callback((jvmtiEnv *)j9env, (JNIEnv *)currentThread, threadRef);
finishedEvent(data->currentThread, JVMTI_EVENT_VIRTUAL_THREAD_END, hadVMAccess, javaOffloadOldState);
}
}

TRACE_JVMTI_EVENT_RETURN(jvmtiHookVirtualThreadEnd);
}
#endif /* JAVA_SPEC_VERSION >= 19 */

static IDATA
hookRegister(J9JVMTIHookInterfaceWithID* hookInterfaceWithID, UDATA eventNum, J9HookFunction function, const char *callsite, void *userData)
Expand Down Expand Up @@ -450,8 +517,16 @@ processEvent(J9JVMTIEnv* j9env, jint event, J9HookRedirectorFunction redirectorF
J9JVMTIHookInterfaceWithID * gcHook = &j9env->gcHook;
return redirectorFunction(gcHook, J9HOOK_MM_OBJECT_ALLOCATION_SAMPLING, jvmtiHookSampledObjectAlloc, OMR_GET_CALLSITE(), j9env);
}

#endif /* JAVA_SPEC_VERSION >= 11 */

#if JAVA_SPEC_VERSION >= 19
case JVMTI_EVENT_VIRTUAL_THREAD_START:
return redirectorFunction(vmHook, J9HOOK_VM_VIRTUAL_THREAD_STARTED, jvmtiHookVirtualThreadStarted, OMR_GET_CALLSITE(), j9env);

case JVMTI_EVENT_VIRTUAL_THREAD_END:
return redirectorFunction(vmHook, J9HOOK_VM_VIRTUAL_THREAD_END, jvmtiHookVirtualThreadEnd, OMR_GET_CALLSITE(), j9env);
#endif /* JAVA_SPEC_VERSION >= 19 */

case JVMTI_EVENT_NATIVE_METHOD_BIND:
return redirectorFunction(vmHook, J9HOOK_VM_JNI_NATIVE_BIND, jvmtiHookJNINativeBind, OMR_GET_CALLSITE(), j9env);

Expand Down
20 changes: 19 additions & 1 deletion runtime/oti/j9vm.hdf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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 @@ -1333,4 +1333,22 @@ typedef UDATA (* lookupNativeAddressCallback)(struct J9VMThread *currentThread,
<struct>J9RestoreEvent</struct>
<data type="struct J9VMThread*" name="currentThread" description="current thread" />
</event>

<event>
<name>J9HOOK_VM_VIRTUAL_THREAD_STARTED</name>
<description>
Triggered once the virtual thread is ready to run. At this point the virtual thread has an object associated with it.
</description>
<struct>J9VirtualThreadStartedEvent</struct>
<data type="struct J9VMThread*" name="currentThread" description="current thread" />
</event>

<event>
<name>J9HOOK_VM_VIRTUAL_THREAD_END</name>
<description>
Triggered when a virtual thread is about to die.
</description>
<struct>J9VirtualThreadEndEvent</struct>
<data type="struct J9VMThread*" name="currentThread" description="current thread" />
</event>
</interface>

0 comments on commit dbe2071

Please sign in to comment.