Skip to content

Commit 9d3b593

Browse files
committed
JVM_getAllEventClasses support
Signed-off-by: Gengchen Tuo <gengchen.tuo@ibm.com>
1 parent f8b93be commit 9d3b593

3 files changed

Lines changed: 125 additions & 4 deletions

File tree

runtime/jcl/common/jdk_jfr_internal_JVM_common.cpp

Lines changed: 78 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,86 @@ 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+
Assert_JCL_notNull(javaLangClass);
138+
139+
J9Class *classArrayClass = javaLangClass->arrayClass;
140+
if (NULL == classArrayClass) {
141+
J9ROMArrayClass *arrayOfObjectsROMClass = (J9ROMArrayClass*)J9ROMIMAGEHEADER_FIRSTCLASS(vm->arrayROMClasses);
142+
classArrayClass = vmFuncs->internalCreateArrayClass(currentThread, arrayOfObjectsROMClass, javaLangClass);
143+
if (NULL == classArrayClass) {
144+
goto done;
145+
}
146+
}
147+
148+
/* Allocate the Class[] array. */
149+
classArray = (j9array_t)mmFuncs->J9AllocateIndexableObject(
150+
currentThread, classArrayClass, (U_32)eventCount, J9_GC_ALLOCATE_OBJECT_NON_INSTRUMENTABLE);
151+
if (NULL == classArray) {
152+
vmFuncs->setNativeOutOfMemoryError(currentThread, 0, 0);
153+
goto done;
154+
}
155+
156+
/* Second pass: populate the array with event classes from all classloaders */
157+
classLoader = vmFuncs->allClassLoadersStartDo(&walkState, vm, 0);
158+
159+
while (NULL != classLoader) {
160+
J9HashTable *typeIDTable = classLoader->typeIDs;
161+
if (NULL != typeIDTable) {
162+
J9HashTableState hashTableState = {0};
163+
J9JFRTypeID *entry = (J9JFRTypeID *)hashTableStartDo(typeIDTable, &hashTableState);
164+
165+
while (NULL != entry) {
166+
if (entry->isEvent && (NULL != entry->eventClass)) {
167+
/* Use the stored eventClass pointer directly */
168+
j9object_t classObject = J9VM_J9CLASS_TO_HEAPCLASS(entry->eventClass);
169+
J9JAVAARRAYOFOBJECT_STORE(currentThread, classArray, arrayIndex, classObject);
170+
arrayIndex += 1;
171+
}
172+
entry = (J9JFRTypeID *)hashTableNextDo(&hashTableState);
173+
}
174+
}
175+
classLoader = vmFuncs->allClassLoadersNextDo(&walkState);
176+
}
177+
vmFuncs->allClassLoadersEndDo(&walkState);
178+
179+
/* Convert array to list and create local ref */
180+
result = vmFuncs->j9jni_createLocalRef(env, vmFuncs->jvmUpcallTransformArrayToList(currentThread, (j9object_t)classArray));
181+
182+
done:
183+
omrthread_monitor_exit(vm->jfrState.typeIDMonitor);
107184
vmFuncs->internalExitVMToJNI(currentThread);
108185

109186
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 & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,13 @@ 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);
78+
static void jfrClassInitialize(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData);
7879

7980
static void
8081
freeThreadIDs(J9VMThread *currentThread)
@@ -1152,6 +1153,7 @@ stopJFRRecording(J9JavaVM *vm)
11521153
(*vmHooks)->J9HookUnregister(vmHooks, J9HOOK_VM_MONITOR_CONTENDED_ENTERED, jfrVMMonitorEntered, NULL);
11531154
(*vmHooks)->J9HookUnregister(vmHooks, J9HOOK_VM_UNPARKED, jfrVMThreadParked, NULL);
11541155
(*vmHooks)->J9HookUnregister(vmHooks, J9HOOK_SYSTEM_GC_CALLED, jfrSystemGC, NULL);
1156+
11551157
/* Deregister GC-related hooks via gc_base */
11561158
vm->memoryManagerFunctions->j9gc_deregister_jfr_hooks(vm);
11571159
}
@@ -1707,13 +1709,25 @@ getTypeId(J9VMThread *currentThread, J9Class *clazz)
17071709
}
17081710

17091711
static jlong
1710-
getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *className, BOOLEAN freeName)
1712+
getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *className, BOOLEAN freeName, J9Class *clazz)
17111713
{
17121714
J9JavaVM *vm = currentThread->javaVM;
17131715
jlong result = INVALID_TYPE_ID;
17141716
J9JFRTypeID entry = {0};
17151717
J9JFRTypeID *jfrTypeID = &entry;
17161718

1719+
if (NULL != clazz) {
1720+
if (NULL == vm->jfrState.jfrEventClassRef) {
1721+
return -1;
1722+
}
1723+
J9Class *eventClass = J9VMJAVALANGCLASS_VMREF(currentThread, J9_JNI_UNWRAP_REFERENCE(vm->jfrState.jfrEventClassRef));
1724+
if (!isSameOrSuperClassOf(eventClass, clazz)
1725+
|| J9_ARE_NO_BITS_SET(clazz->romClass->modifiers, J9AccAbstract)
1726+
) {
1727+
return -1;
1728+
}
1729+
}
1730+
17171731
Assert_VM_mustHaveVMAccess(currentThread);
17181732

17191733
omrthread_monitor_enter(vm->jfrState.typeIDMonitor);
@@ -1739,7 +1753,6 @@ getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *cla
17391753
setNativeOutOfMemoryError(currentThread, 0, 0);
17401754
goto done;
17411755
}
1742-
classLoader->typeIDs = typeIDTable;
17431756

17441757
#if JAVA_SPEC_VERSION >= 17
17451758
if (vm->systemClassLoader == classLoader) {
@@ -1760,6 +1773,8 @@ getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *cla
17601773
}
17611774
}
17621775
#endif /* JAVA_SPEC_VERSION >= 17 */
1776+
1777+
classLoader->typeIDs = typeIDTable;
17631778
}
17641779

17651780
jfrTypeID->className = className;
@@ -1770,6 +1785,8 @@ getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *cla
17701785
jfrTypeID = &entry;
17711786
jfrTypeID->id = vm->jfrState.typeIDcount;
17721787
jfrTypeID->free = freeName;
1788+
jfrTypeID->isEvent = FALSE;
1789+
jfrTypeID->eventClass = NULL;
17731790

17741791
vm->jfrState.typeIDcount += 1;
17751792
Assert_VM_true(vm->jfrState.typeIDcount > 0);
@@ -1779,6 +1796,9 @@ getTypeIdImpl(J9VMThread *currentThread, J9ClassLoader *classLoader, J9UTF8 *cla
17791796
setNativeOutOfMemoryError(currentThread, 0, 0);
17801797
goto done;
17811798
}
1799+
} else if (NULL != clazz) {
1800+
jfrTypeID->isEvent = TRUE;
1801+
jfrTypeID->eventClass = clazz;
17821802
}
17831803
result = jfrTypeID->id;
17841804

@@ -1802,6 +1822,12 @@ initializeJFRv2(J9JavaVM *vm)
18021822
goto done;
18031823
}
18041824

1825+
if (J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_JFR_V2_SUPPORT)) {
1826+
if ((*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_CLASS_INITIALIZE, jfrClassInitialize, OMR_GET_CALLSITE(), NULL)) {
1827+
goto done;
1828+
}
1829+
}
1830+
18051831
if (0 != initializeJFRIDs(vm)) {
18061832
goto done;
18071833
}
@@ -1853,6 +1879,9 @@ jfrShutdownInternalStructures(J9HookInterface **hook, UDATA eventNum, void *even
18531879
internalReleaseVMAccess(currentThread);
18541880
vm->jfrState.jfrEventClassRef = NULL;
18551881
vm->jfrState.jfrInternalEventClassRef = NULL;
1882+
if (J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_JFR_V2_SUPPORT)) {
1883+
(*hook)->J9HookUnregister(hook, J9HOOK_VM_CLASS_INITIALIZE, jfrClassInitialize, NULL);
1884+
}
18561885
}
18571886

18581887
static void
@@ -2017,6 +2046,8 @@ addType(J9JavaVM *vm, const char *eventOrTypeName, UDATA id, bool isEvent)
20172046
entry.id = id;
20182047
entry.className = className;
20192048
entry.free = TRUE;
2049+
entry.isEvent = isEvent;
2050+
entry.eventClass = NULL;
20202051

20212052
/* Add to hash table */
20222053
if (NULL == hashTableAdd(typeIDTable, &entry)) {
@@ -2332,6 +2363,17 @@ requestJFREvent(J9VMThread *currentThread, jlong id)
23322363
#endif /* JAVA_SPEC_VERSION >= 17 */
23332364
}
23342365

2366+
void
2367+
jfrClassInitialize(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData)
2368+
{
2369+
J9VMClassInitializeEvent *event = (J9VMClassInitializeEvent *)eventData;
2370+
J9VMThread *currentThread = event->currentThread;
2371+
J9Class *clazz = event->clazz;
2372+
2373+
/* getTypeIdImpl will add clazz to the TypeID table. */
2374+
getTypeIdImpl(currentThread, clazz->classLoader, J9ROMCLASS_CLASSNAME(clazz->romClass), FALSE, clazz);
2375+
}
2376+
23352377
} /* extern "C" */
23362378

23372379
#endif /* defined(J9VM_OPT_JFR) */

0 commit comments

Comments
 (0)