Skip to content

Commit 79a92d2

Browse files
authored
Merge pull request #24125 from thallium/jfr-getAllEventClasses
JVM_getAllEventClasses support
2 parents cc5e5d2 + 59f95d0 commit 79a92d2

3 files changed

Lines changed: 124 additions & 3 deletions

File tree

runtime/jcl/common/jdk_jfr_internal_JVM_common.cpp

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "j9.h"
2424
#include "jni.h"
2525
#include "jclprots.h"
26+
#include "ut_j9jcl.h"
2627

2728
#include "ObjectAccessBarrierAPI.hpp"
2829
#include "VMHelpers.hpp"
@@ -100,10 +101,85 @@ Java_jdk_jfr_internal_JVM_getAllEventClasses(JNIEnv *env, jobject obj)
100101
J9VMThread *currentThread = (J9VMThread*) env;
101102
J9JavaVM *vm = currentThread->javaVM;
102103
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
104+
J9MemoryManagerFunctions *mmFuncs = vm->memoryManagerFunctions;
103105
jobject result = NULL;
104106

105107
vmFuncs->internalEnterVMFromJNI(currentThread);
106-
result = vmFuncs->j9jni_createLocalRef(env, vmFuncs->jvmUpcallTransformArrayToList(currentThread, NULL));
108+
109+
omrthread_monitor_enter(vm->jfrState.typeIDMonitor);
110+
111+
/* First pass: count event classes with valid eventClass pointers across all classloaders. */
112+
UDATA eventCount = 0;
113+
J9ClassLoaderWalkState walkState;
114+
J9ClassLoader *classLoader = vmFuncs->allClassLoadersStartDo(&walkState, vm, 0);
115+
116+
while (NULL != classLoader) {
117+
J9HashTable *typeIDTable = classLoader->typeIDs;
118+
if (NULL != typeIDTable) {
119+
J9HashTableState hashTableState = {0};
120+
J9JFRTypeID *entry = (J9JFRTypeID *)hashTableStartDo(typeIDTable, &hashTableState);
121+
122+
while (NULL != entry) {
123+
if (entry->isEvent && (NULL != entry->eventClass)) {
124+
eventCount += 1;
125+
}
126+
entry = (J9JFRTypeID *)hashTableNextDo(&hashTableState);
127+
}
128+
}
129+
classLoader = vmFuncs->allClassLoadersNextDo(&walkState);
130+
}
131+
vmFuncs->allClassLoadersEndDo(&walkState);
132+
133+
/* Get the Class class and create Class[] array class. */
134+
J9Class *javaLangClass = J9VMJAVALANGCLASS_OR_NULL(vm);
135+
UDATA arrayIndex = 0;
136+
j9array_t classArray = NULL;
137+
138+
J9Class *classArrayClass = javaLangClass->arrayClass;
139+
if (NULL == classArrayClass) {
140+
J9ROMArrayClass *arrayOfObjectsROMClass = (J9ROMArrayClass*)J9ROMIMAGEHEADER_FIRSTCLASS(vm->arrayROMClasses);
141+
classArrayClass = vmFuncs->internalCreateArrayClass(currentThread, arrayOfObjectsROMClass, javaLangClass);
142+
if (NULL == classArrayClass) {
143+
goto done;
144+
}
145+
}
146+
147+
/* Allocate the Class[] array. */
148+
classArray = (j9array_t)mmFuncs->J9AllocateIndexableObject(
149+
currentThread, classArrayClass, (U_32)eventCount, J9_GC_ALLOCATE_OBJECT_NON_INSTRUMENTABLE);
150+
if (NULL == classArray) {
151+
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
152+
goto done;
153+
}
154+
155+
/* Second pass: populate the array with event classes from all classloaders */
156+
classLoader = vmFuncs->allClassLoadersStartDo(&walkState, vm, 0);
157+
158+
while (NULL != classLoader) {
159+
J9HashTable *typeIDTable = classLoader->typeIDs;
160+
if (NULL != typeIDTable) {
161+
J9HashTableState hashTableState = {0};
162+
J9JFRTypeID *entry = (J9JFRTypeID *)hashTableStartDo(typeIDTable, &hashTableState);
163+
164+
while (NULL != entry) {
165+
if (entry->isEvent && (NULL != entry->eventClass)) {
166+
/* Use the stored eventClass pointer directly */
167+
j9object_t classObject = J9VM_J9CLASS_TO_HEAPCLASS(entry->eventClass);
168+
J9JAVAARRAYOFOBJECT_STORE(currentThread, classArray, arrayIndex, classObject);
169+
arrayIndex += 1;
170+
}
171+
entry = (J9JFRTypeID *)hashTableNextDo(&hashTableState);
172+
}
173+
}
174+
classLoader = vmFuncs->allClassLoadersNextDo(&walkState);
175+
}
176+
vmFuncs->allClassLoadersEndDo(&walkState);
177+
178+
/* Convert array to list and create local ref */
179+
result = vmFuncs->j9jni_createLocalRef(env, vmFuncs->jvmUpcallTransformArrayToList(currentThread, (j9object_t)classArray));
180+
181+
done:
182+
omrthread_monitor_exit(vm->jfrState.typeIDMonitor);
107183
vmFuncs->internalExitVMToJNI(currentThread);
108184

109185
return result;

runtime/oti/j9nonbuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,8 @@ typedef struct J9JFRTypeID {
554554
jlong id;
555555
struct J9UTF8 *className;
556556
BOOLEAN free;
557+
BOOLEAN isEvent;
558+
struct J9Class *eventClass;
557559
} J9JFRTypeID;
558560

559561
typedef struct J9JFRNetworkUtilization {

runtime/vm/jfr.cpp

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,15 @@ static int J9THREAD_PROC jfrSamplingThreadProc(void *entryArg);
6969
static void jfrExecutionSampleCallback(J9VMThread *currentThread, IDATA handlerKey, void *userData);
7070
static void jfrThreadCPULoadCallback(J9VMThread *currentThread, IDATA handlerKey, void *userData);
7171
static void jfrCheckJFRCMDLineOptions(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData);
72-
static jlong getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *className, BOOLEAN freeName);
72+
static jlong getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *className, BOOLEAN freeName, J9Class *clazz = NULL);
7373
#if JAVA_SPEC_VERSION >= 17
7474
static bool addEventIds(J9JavaVM *vm);
7575
static bool addTypeIds(J9JavaVM *vm);
7676
#endif /* JAVA_SPEC_VERSION >= 17 */
7777
static void jfrShutdownInternalStructures(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData);
7878
static void notifyForChunkRotation(J9VMThread *currentThread);
7979
static void checkAvailableSpaceInGlobalBuffer(J9VMThread *currentThread);
80+
static void jfrClassInitialize(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData);
8081

8182
static void
8283
freeThreadIDs(J9VMThread *currentThread)
@@ -1159,6 +1160,7 @@ stopJFRRecording(J9JavaVM *vm)
11591160
(*vmHooks)->J9HookUnregister(vmHooks, J9HOOK_VM_MONITOR_CONTENDED_ENTERED, jfrVMMonitorEntered, NULL);
11601161
(*vmHooks)->J9HookUnregister(vmHooks, J9HOOK_VM_UNPARKED, jfrVMThreadParked, NULL);
11611162
(*vmHooks)->J9HookUnregister(vmHooks, J9HOOK_SYSTEM_GC_CALLED, jfrSystemGC, NULL);
1163+
11621164
/* Deregister GC-related hooks via gc_base */
11631165
vm->memoryManagerFunctions->j9gc_deregister_jfr_hooks(vm);
11641166
}
@@ -1717,13 +1719,25 @@ getTypeId(J9VMThread *currentThread, J9Class *clazz)
17171719
}
17181720

17191721
static jlong
1720-
getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *className, BOOLEAN freeName)
1722+
getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *className, BOOLEAN freeName, J9Class *clazz)
17211723
{
17221724
J9JavaVM *vm = currentThread->javaVM;
17231725
jlong result = INVALID_TYPE_ID;
17241726
J9JFRTypeID entry = {0};
17251727
J9JFRTypeID *jfrTypeID = &entry;
17261728

1729+
if (NULL != clazz) {
1730+
if (NULL == vm->jfrState.jfrEventClassRef) {
1731+
return -1;
1732+
}
1733+
J9Class *eventClass = J9VMJAVALANGCLASS_VMREF(currentThread, J9_JNI_UNWRAP_REFERENCE(vm->jfrState.jfrEventClassRef));
1734+
if (!isSameOrSuperClassOf(eventClass, clazz)
1735+
|| J9_ARE_NO_BITS_SET(clazz->romClass->modifiers, J9AccAbstract)
1736+
) {
1737+
return -1;
1738+
}
1739+
}
1740+
17271741
Assert_VM_mustHaveVMAccess(currentThread);
17281742

17291743
omrthread_monitor_enter(vm->jfrState.typeIDMonitor);
@@ -1770,6 +1784,8 @@ getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *cla
17701784
}
17711785
}
17721786
#endif /* JAVA_SPEC_VERSION >= 17 */
1787+
1788+
classLoader->typeIDs = typeIDTable;
17731789
}
17741790

17751791
jfrTypeID->className = className;
@@ -1780,6 +1796,8 @@ getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *cla
17801796
jfrTypeID = &entry;
17811797
jfrTypeID->id = vm->jfrState.typeIDcount;
17821798
jfrTypeID->free = freeName;
1799+
jfrTypeID->isEvent = FALSE;
1800+
jfrTypeID->eventClass = NULL;
17831801

17841802
vm->jfrState.typeIDcount += 1;
17851803
Assert_VM_true(vm->jfrState.typeIDcount > 0);
@@ -1789,6 +1807,9 @@ getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *cla
17891807
setNativeOutOfMemoryError(currentThread, 0, 0);
17901808
goto done;
17911809
}
1810+
} else if (NULL != clazz) {
1811+
jfrTypeID->isEvent = TRUE;
1812+
jfrTypeID->eventClass = clazz;
17921813
}
17931814
result = jfrTypeID->id;
17941815

@@ -1812,6 +1833,12 @@ initializeJFRv2(J9JavaVM *vm)
18121833
goto done;
18131834
}
18141835

1836+
if (J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_JFR_V2_SUPPORT)) {
1837+
if ((*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_CLASS_INITIALIZE, jfrClassInitialize, OMR_GET_CALLSITE(), NULL)) {
1838+
goto done;
1839+
}
1840+
}
1841+
18151842
if (0 != initializeJFRIDs(vm)) {
18161843
goto done;
18171844
}
@@ -1865,6 +1892,9 @@ jfrShutdownInternalStructures(J9HookInterface **hook, UDATA eventNum, void *even
18651892
vm->jfrState.jfrEventClassRef = NULL;
18661893
vm->jfrState.jfrInternalEventClassRef = NULL;
18671894
vm->jfrState.chunkRotationMonitor = NULL;
1895+
if (J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_JFR_V2_SUPPORT)) {
1896+
(*hook)->J9HookUnregister(hook, J9HOOK_VM_CLASS_INITIALIZE, jfrClassInitialize, NULL);
1897+
}
18681898
}
18691899

18701900
static void
@@ -2029,6 +2059,8 @@ addType(J9JavaVM *vm, const char *eventOrTypeName, UDATA id, bool isEvent)
20292059
entry.id = id;
20302060
entry.className = className;
20312061
entry.free = TRUE;
2062+
entry.isEvent = isEvent;
2063+
entry.eventClass = NULL;
20322064

20332065
/* Add to hash table */
20342066
if (NULL == hashTableAdd(typeIDTable, &entry)) {
@@ -2402,6 +2434,17 @@ checkAvailableSpaceInGlobalBuffer(J9VMThread *currentThread)
24022434
}
24032435
}
24042436

2437+
void
2438+
jfrClassInitialize(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData)
2439+
{
2440+
J9VMClassInitializeEvent *event = (J9VMClassInitializeEvent *)eventData;
2441+
J9VMThread *currentThread = event->currentThread;
2442+
J9Class *clazz = event->clazz;
2443+
2444+
/* getTypeIdImpl will add clazz to the TypeID table. */
2445+
getTypeIdImpl(currentThread, clazz->classLoader, J9ROMCLASS_CLASSNAME(clazz->romClass), FALSE, clazz);
2446+
}
2447+
24052448
} /* extern "C" */
24062449

24072450
#endif /* defined(J9VM_OPT_JFR) */

0 commit comments

Comments
 (0)