Skip to content

Commit 5f11894

Browse files
Harshitha PopuriHarshitha Popuri
authored andcommitted
Implement ROMMethodInfo caching support in mapcache
Add ROMMethodInfo hashing, equality, and caching to populateROMMethodInfo. Update stackmap API and swalk to support ROMMethodInfo cache.
1 parent 91a43ab commit 5f11894

File tree

3 files changed

+231
-5
lines changed

3 files changed

+231
-5
lines changed

runtime/oti/stackmap_api.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,16 @@ j9stackmap_StackBitsForPC(J9PortLibrary * portLib, UDATA pc, J9ROMClass * romCla
206206
void
207207
initializeBasicROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod);
208208

209+
/**
210+
* Populate ROM method info, including argbits, stackmap, and localmap.
211+
*
212+
* @param walkState current stack walk state
213+
* @param romMethod ROM method pointer
214+
* @param key identifying key (method address for method-case, PC for PC-case)
215+
*/
216+
void
217+
populateROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod, void *key);
218+
209219
#ifdef __cplusplus
210220
}
211221
#endif

runtime/stackmap/mapcache.cpp

Lines changed: 217 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
#include "rommeth.h"
2424
#include "stackmap_api.h"
25-
2625
extern "C" {
2726

2827
void
@@ -43,11 +42,228 @@ initializeBasicROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod
4342
}
4443
}
4544

45+
static UDATA
46+
romMethodInfoHashFn(void *key, void *userData)
47+
{
48+
J9ROMMethodInfo *entry = (J9ROMMethodInfo *)key;
49+
return (UDATA)entry->key;
50+
}
51+
52+
static UDATA
53+
romMethodInfoEqualFn(void *leftKey, void *rightKey, void *userData)
54+
{
55+
J9ROMMethodInfo *left = (J9ROMMethodInfo *)leftKey;
56+
J9ROMMethodInfo *right = (J9ROMMethodInfo *)rightKey;
57+
return (left->key == right->key);
58+
}
59+
60+
static bool
61+
checkROMMethodInfoCache(J9ClassLoader *classLoader, void *key, J9ROMMethodInfo *outInfo)
62+
{
63+
bool found = false;
64+
omrthread_monitor_t mapCacheMutex = classLoader->mapCacheMutex;
65+
66+
if (NULL != mapCacheMutex) {
67+
omrthread_monitor_enter(mapCacheMutex);
68+
69+
J9HashTable *cache = classLoader->romMethodInfoCache;
70+
if (NULL != cache) {
71+
J9ROMMethodInfo exemplar = {0};
72+
exemplar.key = key;
73+
J9ROMMethodInfo *entry = (J9ROMMethodInfo *)hashTableFind(cache, &exemplar);
74+
if (NULL != entry) {
75+
*outInfo = *entry; /* Copy struct */
76+
found = true;
77+
}
78+
}
79+
80+
omrthread_monitor_exit(mapCacheMutex);
81+
}
82+
83+
return found;
84+
}
85+
86+
static void
87+
updateROMMethodInfoCache(J9JavaVM *vm, J9ClassLoader *classLoader, J9ROMMethodInfo *info)
88+
{
89+
omrthread_monitor_t mapCacheMutex = classLoader->mapCacheMutex;
90+
if (NULL == mapCacheMutex) {
91+
return; /* caching disabled */
92+
}
93+
94+
omrthread_monitor_enter(mapCacheMutex);
95+
96+
J9HashTable *cache = classLoader->romMethodInfoCache;
97+
if (NULL == cache) {
98+
cache = hashTableNew(
99+
OMRPORT_FROM_J9PORT(vm->portLibrary),
100+
J9_GET_CALLSITE(),
101+
0,
102+
sizeof(J9ROMMethodInfo),
103+
sizeof(J9ROMMethodInfo *),
104+
0,
105+
J9MEM_CATEGORY_VM,
106+
romMethodInfoHashFn,
107+
romMethodInfoEqualFn,
108+
NULL,
109+
NULL);
110+
classLoader->romMethodInfoCache = cache;
111+
}
112+
113+
if (NULL != cache) {
114+
hashTableAdd(cache, info);
115+
}
116+
117+
omrthread_monitor_exit(mapCacheMutex);
118+
}
119+
46120
void
47121
populateROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod, void *key)
48122
{
49123
initializeBasicROMMethodInfo(walkState, romMethod);
124+
125+
J9Method *method = walkState->method;
126+
J9ClassLoader *classLoader = J9_CLASS_FROM_METHOD(method)->classLoader;
127+
J9JavaVM *vm = walkState->javaVM;
128+
129+
UDATA codeSize = (UDATA)J9_BYTECODE_SIZE_FROM_ROM_METHOD(romMethod);
130+
void *bytecodeStart = (void*)J9_BYTECODE_START_FROM_ROM_METHOD(romMethod);
131+
132+
bool isMethodCase = (key == (void *)romMethod);
133+
UDATA pc = 0;
134+
135+
if (!isMethodCase) {
136+
// Compute PC only if key points into bytecode range
137+
if ((uintptr_t)key >= (uintptr_t)bytecodeStart &&
138+
(uintptr_t)key < (uintptr_t)bytecodeStart + codeSize) {
139+
pc = (UDATA)((uintptr_t)key - (uintptr_t)bytecodeStart);
140+
}
141+
}
142+
143+
J9ROMClass *romClass = J9_CLASS_FROM_METHOD(method)->romClass;
144+
J9ROMMethodInfo newInfo = {0};
145+
newInfo.key = key;
146+
147+
// Always compute argbits
148+
j9localmap_ArgBitsForPC0(romClass, romMethod, newInfo.argbits);
149+
150+
if (!isMethodCase && pc < codeSize) {
151+
// Stack map
152+
j9stackmap_StackBitsForPC(
153+
vm->portLibrary,
154+
pc,
155+
romClass,
156+
romMethod,
157+
newInfo.stackmap,
158+
J9_STACKMAP_CACHE_SLOTS << 5,
159+
NULL, NULL, NULL);
160+
161+
// Local map
162+
vm->localMapFunction(
163+
vm->portLibrary,
164+
romClass,
165+
romMethod,
166+
pc,
167+
newInfo.localmap,
168+
NULL, NULL, NULL);
169+
}
170+
171+
// Copy metadata
172+
newInfo.modifiers = romMethod->modifiers;
173+
newInfo.argCount = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod);
174+
newInfo.tempCount = J9_TEMP_COUNT_FROM_ROM_METHOD(romMethod);
175+
176+
// Insert into cache
177+
updateROMMethodInfoCache(vm, classLoader, &newInfo);
178+
179+
// Reflect it into the current walkState
180+
walkState->romMethodInfo = newInfo;
181+
}
182+
50183
#if 0
184+
185+
void
186+
populateROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod, void *key)
187+
{
188+
initializeBasicROMMethodInfo(walkState, romMethod);
189+
190+
J9Method *method = walkState->method;
191+
J9ClassLoader *classLoader = J9_CLASS_FROM_METHOD(method)->classLoader;
192+
J9JavaVM *vm = walkState->javaVM;
193+
J9ROMMethodInfo cachedInfo = {0};
194+
195+
/* Try to find in cache first */
196+
bool found = checkROMMethodInfoCache(classLoader, key, &cachedInfo);
197+
if (found) {
198+
walkState->romMethodInfo = cachedInfo;
199+
return;
200+
}
201+
202+
/* Cache miss — build new info */
203+
J9ROMMethodInfo newInfo = {0};
204+
newInfo.key = key;
205+
206+
bool isMethodCase = (key == (void *)romMethod);
207+
J9ROMClass *romClass = J9_CLASS_FROM_METHOD(method)->romClass;
208+
209+
/* Always compute argbits */
210+
{
211+
UDATA argWords = (J9_ARG_COUNT_FROM_ROM_METHOD(romMethod) + 31) >> 5;
212+
if (argWords > J9_ARGBITS_CACHE_SLOTS) {
213+
argWords = J9_ARGBITS_CACHE_SLOTS;
214+
}
215+
j9localmap_ArgBitsForPC0(romClass, romMethod, newInfo.argbits);
216+
}
217+
218+
if (!isMethodCase) {
219+
/* PC case: compute stack and local maps */
220+
UDATA pc = (UDATA)((UDATA)key - (UDATA)J9_BYTECODE_START_FROM_ROM_METHOD(romMethod));
221+
/* Stack map */
222+
UDATA stackWords = (J9_STACKMAP_CACHE_SLOTS);
223+
if (stackWords > J9_STACKMAP_CACHE_SLOTS) {
224+
stackWords = J9_STACKMAP_CACHE_SLOTS;
225+
}
226+
j9stackmap_StackBitsForPC(
227+
vm->portLibrary,
228+
pc,
229+
romClass,
230+
romMethod,
231+
newInfo.stackmap,
232+
stackWords << 5,
233+
NULL, NULL, NULL);
234+
235+
/* Local map */
236+
UDATA localWords = (J9_TEMP_COUNT_FROM_ROM_METHOD(romMethod) +
237+
J9_ARG_COUNT_FROM_ROM_METHOD(romMethod) + 31) >> 5;
238+
if (localWords > J9_ARGBITS_CACHE_SLOTS) {
239+
localWords = J9_ARGBITS_CACHE_SLOTS;
240+
}
241+
vm->localMapFunction(
242+
vm->portLibrary,
243+
romClass,
244+
romMethod,
245+
pc,
246+
newInfo.localmap,
247+
NULL, NULL, NULL);
248+
}
249+
250+
/* Copy metadata */
251+
newInfo.modifiers = romMethod->modifiers;
252+
newInfo.argCount = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod);
253+
newInfo.tempCount = J9_TEMP_COUNT_FROM_ROM_METHOD(romMethod);
254+
255+
/* Insert into cache */
256+
updateROMMethodInfoCache(vm, classLoader, &newInfo);
257+
258+
/* Reflect it into the current walkState */
259+
walkState->romMethodInfo = newInfo;
260+
}
261+
262+
void
263+
populateROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod, void *key)
264+
{
265+
initializeBasicROMMethodInfo(walkState, romMethod);
266+
51267
bool found = false;
52268
J9Method *method = walkState->method;
53269
J9ClassLoader *classLoader = J9_CLASS_FROM_METHOD(method)->classLoader;
@@ -74,10 +290,8 @@ populateROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod, void
74290

75291
omrthread_monitor_exit(mapCacheMutex);
76292
}
77-
#endif
78293
}
79294

80-
#if 0
81295

82296
/**
83297
* @brief Map cache hash function

runtime/vm/swalk.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,8 @@ walkMethodFrame(J9StackWalkState * walkState)
760760
J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method);
761761
J9ROMMethodInfo *romMethodInfo = &walkState->romMethodInfo;
762762

763-
initializeBasicROMMethodInfo(walkState, romMethod);
763+
//initializeBasicROMMethodInfo(walkState, romMethod);
764+
populateROMMethodInfo(walkState, romMethod, walkState->pc);
764765

765766
walkState->constantPool = UNTAGGED_METHOD_CP(walkState->method);
766767
walkState->argCount = romMethodInfo->argCount;
@@ -1025,7 +1026,8 @@ walkBytecodeFrame(J9StackWalkState * walkState)
10251026
J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method);
10261027
J9ROMMethodInfo *romMethodInfo = &walkState->romMethodInfo;
10271028

1028-
initializeBasicROMMethodInfo(walkState, romMethod);
1029+
//initializeBasicROMMethodInfo(walkState, romMethod);
1030+
populateROMMethodInfo(walkState, romMethod, walkState->pc);
10291031

10301032
walkState->constantPool = UNTAGGED_METHOD_CP(walkState->method);
10311033

0 commit comments

Comments
 (0)