2222
2323#include " rommeth.h"
2424#include " stackmap_api.h"
25-
2625extern " C" {
2726
2827void
@@ -43,11 +42,183 @@ 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;
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+ /* Create the cache if it doesn't exist */
99+ cache = hashTableNew (
100+ OMRPORT_FROM_J9PORT (vm->portLibrary ),
101+ J9_GET_CALLSITE (),
102+ 0 ,
103+ sizeof (J9ROMMethodInfo),
104+ sizeof (J9ROMMethodInfo *),
105+ 0 ,
106+ J9MEM_CATEGORY_VM,
107+ romMethodInfoHashFn,
108+ romMethodInfoEqualFn,
109+ NULL ,
110+ NULL );
111+ classLoader->romMethodInfoCache = cache;
112+ }
113+
114+ if (NULL != cache) {
115+ hashTableAdd (cache, info);
116+ }
117+
118+ omrthread_monitor_exit (mapCacheMutex);
119+ }
120+
121+ static void
122+ populateROMMethodInfo (J9StackWalkState *walkState, J9ROMMethod *romMethod, void *key, UDATA pc, bool computeStackAndLocals)
123+ {
124+ J9Method *method = walkState->method ;
125+ J9ClassLoader *classLoader = J9_CLASS_FROM_METHOD (method)->classLoader ;
126+ J9JavaVM *vm = walkState->javaVM ;
127+
128+ J9ROMMethodInfo newInfo = {0 };
129+ newInfo.key = key;
130+ J9ROMClass *romClass = J9_CLASS_FROM_METHOD (method)->romClass ;
131+
132+ /* Always compute argument bits */
133+ j9localmap_ArgBitsForPC0 (romClass, romMethod, newInfo.argbits );
134+
135+ if (computeStackAndLocals && pc < (UDATA)J9_BYTECODE_SIZE_FROM_ROM_METHOD (romMethod)) {
136+ /* Compute stack map for this PC */
137+ j9stackmap_StackBitsForPC (
138+ vm->portLibrary ,
139+ pc,
140+ romClass,
141+ romMethod,
142+ newInfo.stackmap ,
143+ J9_STACKMAP_CACHE_SLOTS << 5 ,
144+ NULL ,
145+ NULL ,
146+ NULL );
147+
148+ /* Compute local variable map for this PC */
149+ vm->localMapFunction (
150+ vm->portLibrary ,
151+ romClass,
152+ romMethod,
153+ pc,
154+ newInfo.localmap ,
155+ NULL ,
156+ NULL ,
157+ NULL );
158+ }
159+
160+ /* Copy metadata */
161+ newInfo.modifiers = romMethod->modifiers ;
162+ newInfo.argCount = J9_ARG_COUNT_FROM_ROM_METHOD (romMethod);
163+ newInfo.tempCount = J9_TEMP_COUNT_FROM_ROM_METHOD (romMethod);
164+
165+ /* Insert into cache */
166+ updateROMMethodInfoCache (vm, classLoader, &newInfo);
167+
168+ /* Reflect into current walkState */
169+ walkState->romMethodInfo = newInfo;
170+ }
171+
46172void
47- populateROMMethodInfo (J9StackWalkState *walkState, J9ROMMethod *romMethod, void *key )
173+ getROMMethodInfoForROMMethod (J9StackWalkState *walkState, J9ROMMethod *romMethod)
48174{
49175 initializeBasicROMMethodInfo (walkState, romMethod);
176+ J9Method *method = walkState->method ;
177+ J9ClassLoader *classLoader = J9_CLASS_FROM_METHOD (method)->classLoader ;
178+
179+ void *key = (void *)romMethod;
180+ J9ROMMethodInfo tmp = {0 };
181+
182+ /* Check cache first */
183+ if (!checkROMMethodInfoCache (classLoader, key, &tmp)) {
184+ /* Cache miss or not populated: populate argbits only */
185+ populateROMMethodInfo (walkState, romMethod, key, 0 , false );
186+ } else {
187+ walkState->romMethodInfo = tmp;
188+ }
189+ }
190+
191+ /* Bytecode PC: compute argbits + stackmap + localmap */
192+ void
193+ getROMMethodInfoForBytecodePC (J9StackWalkState *walkState, J9ROMMethod *romMethod, UDATA pc)
194+ {
195+ initializeBasicROMMethodInfo (walkState, romMethod);
196+ if (pc <= J9SF_MAX_SPECIAL_FRAME_TYPE || pc >= (UDATA)J9_BYTECODE_SIZE_FROM_ROM_METHOD (romMethod)) {
197+ return ;
198+ }
199+
200+ J9Method *method = walkState->method ;
201+ J9ClassLoader *classLoader = J9_CLASS_FROM_METHOD (method)->classLoader ;
202+
203+ void *key = (void *)( (uintptr_t )J9_BYTECODE_START_FROM_ROM_METHOD (romMethod) + (uintptr_t )pc );
204+ J9ROMMethodInfo tmp = {0 };
205+
206+ /* Check cache first */
207+ if (!checkROMMethodInfoCache (classLoader, key, &tmp)) {
208+ /* Cache miss or not populated: compute stack/local maps */
209+ populateROMMethodInfo (walkState, romMethod, key, pc, true );
210+ } else {
211+ walkState->romMethodInfo = tmp;
212+ }
213+ }
214+
50215#if 0
216+
217+ void
218+ populateROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod, void *key)
219+ {
220+ initializeBasicROMMethodInfo(walkState, romMethod);
221+
51222 bool found = false;
52223 J9Method *method = walkState->method;
53224 J9ClassLoader *classLoader = J9_CLASS_FROM_METHOD(method)->classLoader;
@@ -74,10 +245,8 @@ populateROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod, void
74245
75246 omrthread_monitor_exit(mapCacheMutex);
76247 }
77- #endif
78248}
79249
80- #if 0
81250
82251/**
83252 * @brief Map cache hash function
0 commit comments