diff --git a/runtime/codert_vm/jswalk.c b/runtime/codert_vm/jswalk.c index efbfe38f71e..1c46b7afd20 100644 --- a/runtime/codert_vm/jswalk.c +++ b/runtime/codert_vm/jswalk.c @@ -172,6 +172,9 @@ UDATA jitWalkStackFrames(J9StackWalkState *walkState) walkState->dropToCurrentFrame = jitDropToCurrentFrame; while ((walkState->jitInfo = jitGetExceptionTable(walkState)) != NULL) { +#if defined(J9MAPCACHE_DEBUG) + memset(&walkState->romMethodInfo, 0, sizeof(walkState->romMethodInfo)); +#endif /* J9MAPCACHE_DEBUG */ walkState->stackMap = NULL; walkState->inlineMap = NULL; walkState->bp = walkState->unwindSP + getJitTotalFrameSize(walkState->jitInfo); @@ -212,6 +215,8 @@ UDATA jitWalkStackFrames(J9StackWalkState *walkState) lswRecord(walkState, LSW_TYPE_METHOD, walkState->method); lswRecord(walkState, LSW_TYPE_JIT_FRAME_INFO, walkState); #endif + initializeBasicROMMethodInfo(walkState, J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)); + if ((rc = walkFrame(walkState)) != J9_STACKWALK_KEEP_ITERATING) { return rc; } @@ -250,6 +255,7 @@ UDATA jitWalkStackFrames(J9StackWalkState *walkState) #ifdef J9VM_INTERP_LINEAR_STACKWALK_TRACING lswRecord(walkState, LSW_TYPE_JIT_FRAME_INFO, walkState); #endif + initializeBasicROMMethodInfo(walkState, J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)); if ((rc = walkFrame(walkState)) != J9_STACKWALK_KEEP_ITERATING) { return rc; } @@ -1977,6 +1983,9 @@ jitWalkOSRFrame(J9StackWalkState *walkState, J9OSRFrame *osrFrame) UDATA *localSlots = ((UDATA*)(osrFrame + 1)) + maxStack; UDATA *nextFrame = localSlots + numberOfLocals; J9MonitorEnterRecord *enterRecord = osrFrame->monitorEnterRecords; + J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method); + + initializeBasicROMMethodInfo(walkState, romMethod); #ifdef J9VM_INTERP_STACKWALK_TRACING { @@ -1987,6 +1996,7 @@ jitWalkOSRFrame(J9StackWalkState *walkState, J9OSRFrame *osrFrame) walkState->method = stateMethod; } #endif + walkBytecodeFrameSlots(walkState, method, offsetPC, localSlots - 1, pendingStackHeight, nextFrame - 1, numberOfLocals, TRUE); diff --git a/runtime/oti/j9modifiers_api.h b/runtime/oti/j9modifiers_api.h index 086af962ed0..01042173b34 100644 --- a/runtime/oti/j9modifiers_api.h +++ b/runtime/oti/j9modifiers_api.h @@ -116,8 +116,9 @@ /* Composite Flag checks */ #define J9ROMCLASS_IS_PRIMITIVE_OR_ARRAY(romClass) _J9ROMCLASS_SUNMODIFIER_IS_ANY_SET((romClass), J9AccClassArray | J9AccClassInternalPrimitiveType) -#define J9ROMMETHOD_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(romMethod) \ - ((((romMethod)->modifiers) & (J9AccMethodObjectConstructor | J9AccEmptyMethod)) == J9AccMethodObjectConstructor) +#define J9ROMMETHOD_MODIFIERS_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(modifiers) \ + (((modifiers) & (J9AccMethodObjectConstructor | J9AccEmptyMethod)) == J9AccMethodObjectConstructor) +#define J9ROMMETHOD_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(romMethod) J9ROMMETHOD_MODIFIERS_IS_NON_EMPTY_OBJECT_CONSTRUCTOR((romMethod)->modifiers) /* Class instances are allocated via the new bytecode */ #define J9ROMCLASS_ALLOCATES_VIA_NEW(romClass) \ diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index 1e2bd38d14e..3506204d9e1 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -1147,12 +1147,32 @@ typedef struct J9CudaGlobals { jmethodID runnable_run; } J9CudaGlobals; -#define J9_MAP_CACHE_SLOTS 2 - -typedef struct J9MapCacheEntry { +/* Cache slot sizes must all be multiples of 2 */ +#define J9_STACKMAP_CACHE_SLOTS 2 +#define J9_LOCALMAP_CACHE_SLOTS 2 +#define J9_ARGBITS_CACHE_SLOTS 2 + +/* Flag values for J9ROMMethodInfo */ +#define J9MAPCACHE_STACKMAP_CACHED 1 +#define J9MAPCACHE_LOCALMAP_CACHED 2 +#define J9MAPCACHE_ARGBITS_CACHED 4 +#define J9MAPCACHE_METHOD_IS_CONSTRUCTOR 8 +#define J9MAPCACHE_VALID 128 + +/* J9ROMMethodInfo must be a multiple of 8 bytes in size */ +typedef struct J9ROMMethodInfo { void *key; - U_32 bits[J9_MAP_CACHE_SLOTS]; -} J9MapCacheEntry; + U_32 stackmap[J9_STACKMAP_CACHE_SLOTS]; + U_32 localmap[J9_ARGBITS_CACHE_SLOTS]; + U_32 argbits[J9_ARGBITS_CACHE_SLOTS]; + U_32 modifiers; + U_16 tempCount; + U_8 argCount; + U_8 flags; +#if !defined(J9VM_ENV_DATA64) + U_32 padTo64; +#endif /* !defined(J9VM_ENV_DATA64) */ +} J9ROMMethodInfo; #if defined(J9VM_OPT_SHARED_CLASSES) @@ -2808,6 +2828,7 @@ typedef struct J9StackWalkState { void* stackMap; void* inlineMap; UDATA loopBreaker; + J9ROMMethodInfo romMethodInfo; /* 64-bit aligned */ /* The size of J9StackWalkState must be a multiple of 8 because it is inlined into * J9VMThread where alignment assumotions are being made. */ @@ -3740,9 +3761,7 @@ typedef struct J9ClassLoader { UDATA initClassPathEntryCount; UDATA asyncGetCallTraceUsed; omrthread_monitor_t mapCacheMutex; - struct J9HashTable* localmapCache; - struct J9HashTable* argsbitsCache; - struct J9HashTable* stackmapCache; + struct J9HashTable* romMethodInfoCache; #if defined(J9VM_OPT_JFR) J9HashTable *typeIDs; #endif /* defined(J9VM_OPT_JFR) */ diff --git a/runtime/oti/stackmap_api.h b/runtime/oti/stackmap_api.h index e242adb89e3..d52ac004b8a 100644 --- a/runtime/oti/stackmap_api.h +++ b/runtime/oti/stackmap_api.h @@ -196,30 +196,15 @@ j9stackmap_StackBitsForPC(J9PortLibrary * portLib, UDATA pc, J9ROMClass * romCla UDATA * (* getBuffer) (void * userData), void (* releaseBuffer) (void * userData)); +/* ---------------- mapcache.cpp ---------------- */ -/* ------------------- mapcache.cpp ----------------- */ - -/* These are cache wrapper functions with the same parameters as the j9localmap_ versions, - * with VM and J9ClassLoader added on the end. - */ - -IDATA -j9cached_StackBitsForPC(UDATA pc, J9ROMClass * romClass, J9ROMMethod * romMethod, - U_32 * resultArrayBase, UDATA resultArraySize, - void * userData, - UDATA * (* getBuffer) (void * userData), - void (* releaseBuffer) (void * userData), - J9JavaVM *vm, J9ClassLoader *classLoader); - +/** +* @brief +* @param walkState +* @param romMethod +*/ void -j9cached_ArgBitsForPC0(J9ROMClass *romClass, J9ROMMethod *romMethod, U_32 *resultArrayBase, J9JavaVM *vm, J9ClassLoader *classLoader); - -IDATA -j9cached_LocalBitsForPC(J9ROMClass * romClass, J9ROMMethod * romMethod, UDATA pc, U_32 * resultArrayBase, - void * userData, - UDATA * (* getBuffer) (void * userData), - void (* releaseBuffer) (void * userData), - J9JavaVM *vm, J9ClassLoader * classLoader); +initializeBasicROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod); #ifdef __cplusplus } diff --git a/runtime/stackmap/mapcache.cpp b/runtime/stackmap/mapcache.cpp index bdc312bfec8..5b9a477db1a 100644 --- a/runtime/stackmap/mapcache.cpp +++ b/runtime/stackmap/mapcache.cpp @@ -25,6 +25,60 @@ extern "C" { +void +initializeBasicROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod) +{ + J9ROMMethodInfo *romMethodInfo = &walkState->romMethodInfo; + memset(romMethodInfo, 0, sizeof(*romMethodInfo)); + romMethodInfo->argCount = romMethod->argCount; + romMethodInfo->tempCount = romMethod->tempCount; + romMethodInfo->modifiers = romMethod->modifiers; +#if defined(J9MAPCACHE_DEBUG) + romMethodInfo->flags = J9MAPCACHE_VALID; +#endif /* J9MAPCACHE_DEBUG */ + if (!(romMethod->modifiers & J9AccStatic)) { + if (J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod))[0] == '<') { + romMethodInfo->flags |= J9MAPCACHE_METHOD_IS_CONSTRUCTOR; + } + } +} + +void +populateROMMethodInfo(J9StackWalkState *walkState, J9ROMMethod *romMethod, void *key) +{ + initializeBasicROMMethodInfo(walkState, romMethod); +#if 0 + bool found = false; + J9Method *method = walkState->method; + J9ClassLoader *classLoader = J9_CLASS_FROM_METHOD(method)->classLoader; + omrthread_monitor_t mapCacheMutex = classLoader->mapCacheMutex; + + /* If the mapCacheMutex exists, the caching feature is enabled */ + if (NULL != mapCacheMutex) { + omrthread_monitor_enter(mapCacheMutex); + J9HashTable *mapCache = classLoader->romMethodInfoCache; + + /* If the cache exists, check it for this key */ + if (NULL != mapCache) { + J9ROMMethodInfo exemplar = { 0 }; + exemplar.key = key; + J9ROMMethodInfo *entry = (J9ROMMethodInfo*)hashTableFind(mapCache, &exemplar); + + if (NULL != entry) { + /* Cache hit - copy the info */ + *romMethodInfo = *entry; + } else { + /* Cache miss - populate the info and cache it */ + } + } + + omrthread_monitor_exit(mapCacheMutex); + } +#endif +} + +#if 0 + /** * @brief Map cache hash function * @param key J9MapCacheEntry pointer @@ -83,7 +137,7 @@ checkCache(J9JavaVM *vm, J9ClassLoader *classLoader, void *key, J9HashTable *map J9MapCacheEntry *entry = (J9MapCacheEntry*)hashTableFind(mapCache, &exemplar); if (NULL != entry) { - memcpy(resultArrayBase, entry->bits, sizeof(U_32) * mapWords); + memcpy(resultArrayBase, &entry->data.bits, sizeof(U_32) * mapWords); found = true; } } @@ -135,7 +189,7 @@ updateCache(J9JavaVM *vm, J9ClassLoader *classLoader, void *key, J9HashTable **c if (NULL != mapCache) { J9MapCacheEntry entry = { 0 }; entry.key = key; - memcpy(entry.bits, resultArrayBase, sizeof(U_32) * mapWords); + memcpy(&entry.data.bits, resultArrayBase, sizeof(U_32) * mapWords); hashTableAdd(mapCache, &entry); } @@ -201,4 +255,7 @@ j9cached_LocalBitsForPC(J9ROMClass * romClass, J9ROMMethod * romMethod, UDATA pc return rc; } +#endif + + } /* extern "C" */ diff --git a/runtime/vm/classallocation.c b/runtime/vm/classallocation.c index eb341a77b30..006f7dabeba 100644 --- a/runtime/vm/classallocation.c +++ b/runtime/vm/classallocation.c @@ -67,17 +67,9 @@ U_32 classPropagationTable[CLASS_PROPAGATION_TABLE_SIZE] = { void freeMapCaches(J9ClassLoader *classLoader) { - if (NULL != classLoader->localmapCache) { - hashTableFree(classLoader->localmapCache); - classLoader->localmapCache = NULL; - } - if (NULL != classLoader->argsbitsCache) { - hashTableFree(classLoader->argsbitsCache); - classLoader->argsbitsCache = NULL; - } - if (NULL != classLoader->stackmapCache) { - hashTableFree(classLoader->stackmapCache); - classLoader->stackmapCache = NULL; + if (NULL != classLoader->romMethodInfoCache) { + hashTableFree(classLoader->romMethodInfoCache); + classLoader->romMethodInfoCache = NULL; } } diff --git a/runtime/vm/swalk.c b/runtime/vm/swalk.c index f29d5025dea..ef28d58217e 100644 --- a/runtime/vm/swalk.c +++ b/runtime/vm/swalk.c @@ -55,6 +55,13 @@ #include +#if defined(J9MAPCACHE_DEBUG) +#define ENSURE_ROM_METHOD_INFO_VALID(romMethodInfo) \ + if (J9_ARE_NO_BITS_SET(romMethodInfo->flags, J9MAPCACHE_VALID)) *(UDATA*)-1=-1 +#else /* J9MAPCACHE_DEBUG */ +#define ENSURE_ROM_METHOD_INFO_VALID(romMethodInfo) +#endif /* J9MAPCACHE_DEBUG */ + #if (defined(J9VM_INTERP_STACKWALK_TRACING)) static void printFrameType (J9StackWalkState * walkState, char * frameType); @@ -309,6 +316,11 @@ UDATA walkStackFrames(J9VMThread *currentThread, J9StackWalkState *walkState) walkState->outgoingArgCount = walkState->argCount; walkState->bytecodePCOffset = -1; +#if defined(J9MAPCACHE_DEBUG) + memset(&walkState->romMethodInfo, 0, sizeof(walkState->romMethodInfo)); +#endif /* J9MAPCACHE_DEBUG */ + + #ifdef J9VM_INTERP_LINEAR_STACKWALK_TRACING lswFrameNew(vm, walkState, (UDATA)walkState->pc); #endif @@ -489,16 +501,14 @@ UDATA walkFrame(J9StackWalkState * walkState) } if (walkState->flags & J9_STACKWALK_HIDE_EXCEPTION_FRAMES) { - J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method); - - if (!(romMethod->modifiers & J9AccStatic)) { - if (J9UTF8_DATA(J9ROMMETHOD_NAME(romMethod))[0] == '<') { - if (*walkState->arg0EA == (UDATA) walkState->restartException) { - return J9_STACKWALK_KEEP_ITERATING; - } + J9ROMMethodInfo *romMethodInfo = &walkState->romMethodInfo; + ENSURE_ROM_METHOD_INFO_VALID(romMethodInfo); + if (J9_ARE_ANY_BITS_SET(romMethodInfo->flags, J9MAPCACHE_METHOD_IS_CONSTRUCTOR)) { + if (*walkState->arg0EA == (UDATA) walkState->restartException) { + return J9_STACKWALK_KEEP_ITERATING; } - walkState->flags &= ~J9_STACKWALK_HIDE_EXCEPTION_FRAMES; } + walkState->flags &= ~J9_STACKWALK_HIDE_EXCEPTION_FRAMES; } } @@ -709,6 +719,9 @@ walkMethodFrame(J9StackWalkState * walkState) walkState->frameFlags = methodFrame->specialFrameFlags; MARK_SLOT_AS_OBJECT(walkState, (j9object_t*) &(methodFrame->specialFrameFlags)); walkState->method = methodFrame->method; + if (NULL != walkState->method) { + initializeBasicROMMethodInfo(walkState, J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)); + } walkState->unwindSP = (UDATA *) methodFrame; #ifdef J9VM_INTERP_LINEAR_STACKWALK_TRACING @@ -745,22 +758,31 @@ walkMethodFrame(J9StackWalkState * walkState) } if (walkState->method) { J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method); + J9ROMMethodInfo *romMethodInfo = &walkState->romMethodInfo; + + initializeBasicROMMethodInfo(walkState, romMethod); walkState->constantPool = UNTAGGED_METHOD_CP(walkState->method); - walkState->argCount = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod); + walkState->argCount = romMethodInfo->argCount; if (walkState->flags & J9_STACKWALK_ITERATE_O_SLOTS) { WALK_METHOD_CLASS(walkState); if (walkState->argCount) { /* Max size as argCount always <= 255 */ - U_32 result[8]; + U_32 inlineResult[8]; + U_32 *result = inlineResult; J9Class *methodClass = UNTAGGED_METHOD_CP(walkState->method)->ramClass; #ifdef J9VM_INTERP_STACKWALK_TRACING swPrintf(walkState, 4, "\tUsing signature mapper\n"); #endif - j9cached_ArgBitsForPC0(methodClass->romClass, romMethod, result, walkState->javaVM, methodClass->classLoader); + + if (J9_ARE_ANY_BITS_SET(romMethodInfo->flags, J9MAPCACHE_ARGBITS_CACHED)) { + result = romMethodInfo->argbits; + } else { + j9localmap_ArgBitsForPC0(methodClass->romClass, romMethod, result); + } #ifdef J9VM_INTERP_STACKWALK_TRACING swPrintf(walkState, 4, "\tArguments starting at %p for %d slots\n", walkState->arg0EA, walkState->argCount); @@ -812,7 +834,7 @@ walkMethodTypeFrame(J9StackWalkState * walkState) MARK_SLOT_AS_OBJECT(walkState, (j9object_t*) &(methodTypeFrame->specialFrameFlags)); MARK_SLOT_AS_OBJECT(walkState, (j9object_t*) &(methodTypeFrame->argStackSlots)); MARK_SLOT_AS_OBJECT(walkState, (j9object_t*) &(methodTypeFrame->descriptionIntCount)); - walkState->method = NULL; + NULL; walkState->unwindSP = (UDATA *) methodTypeFrame; #ifdef J9VM_INTERP_LINEAR_STACKWALK_TRACING @@ -879,21 +901,20 @@ walkBytecodeFrameSlots(J9StackWalkState *walkState, J9Method *method, UDATA offs { J9JavaVM *vm = walkState->javaVM; PORT_ACCESS_FROM_JAVAVM(vm); + J9ROMMethodInfo *romMethodInfo = &walkState->romMethodInfo; UDATA *bp = localBase - numberOfLocals; - J9Class *ramClass = J9_CLASS_FROM_METHOD(method); - J9ROMClass *romClass = ramClass->romClass; - J9ROMMethod *romMethod = getOriginalROMMethod(method); - U_32 smallResult = 0; - U_32 *result = &smallResult; U_32 *globalBuffer = NULL; UDATA numberOfMappedLocals = numberOfLocals; + U_32 modifiers = romMethodInfo->modifiers; + U_32 flags = romMethodInfo->flags; + + ENSURE_ROM_METHOD_INFO_VALID(romMethodInfo); #ifdef J9VM_INTERP_STACKWALK_TRACING swPrintf(walkState, 3, "\tBytecode index = %d\n", offsetPC); #endif - - if (romMethod->modifiers & J9AccSynchronized) { + if (modifiers & J9AccSynchronized) { #ifdef J9VM_INTERP_STACKWALK_TRACING swPrintf(walkState, 4, "\tSync object for synchronized method\n"); #endif @@ -901,7 +922,7 @@ walkBytecodeFrameSlots(J9StackWalkState *walkState, J9Method *method, UDATA offs walkState->slotIndex = -1; WALK_NAMED_O_SLOT((j9object_t*) (bp + 1), "Sync O-Slot"); numberOfMappedLocals -= 1; - } else if (J9ROMMETHOD_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(romMethod)) { + } else if (J9ROMMETHOD_MODIFIERS_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(modifiers)) { /* Non-empty java.lang.Object. has one hidden temp to hold a copy of the receiver */ #ifdef J9VM_INTERP_STACKWALK_TRACING swPrintf(walkState, 4, "\tReceiver object for java.lang.Object.\n"); @@ -912,40 +933,57 @@ walkBytecodeFrameSlots(J9StackWalkState *walkState, J9Method *method, UDATA offs numberOfMappedLocals -= 1; } - if ((numberOfMappedLocals > 32) || (pendingStackHeight > 32)) { - UDATA maxCount = (numberOfMappedLocals > pendingStackHeight) ? numberOfMappedLocals : pendingStackHeight; - result = j9mem_allocate_memory(((maxCount + 31) >> 5) * sizeof(U_32), OMRMEM_CATEGORY_VM); - if (NULL == result) { - globalBuffer = j9mapmemory_GetResultsBuffer(vm); - result = globalBuffer; + { + J9ROMClass *romClass = J9_CLASS_FROM_METHOD(method)->romClass; + J9ROMMethod *romMethod = getOriginalROMMethod(method); + U_32 smallResult = 0; + U_32 *result = &smallResult; + BOOLEAN freeBuffer = FALSE; + + if ((numberOfMappedLocals > 32) || (pendingStackHeight > 32)) { + UDATA maxCount = (numberOfMappedLocals > pendingStackHeight) ? numberOfMappedLocals : pendingStackHeight; + result = j9mem_allocate_memory(((maxCount + 31) >> 5) * sizeof(U_32), OMRMEM_CATEGORY_VM); + if (NULL == result) { + globalBuffer = j9mapmemory_GetResultsBuffer(vm); + result = globalBuffer; + } + freeBuffer = TRUE; } - } - if (0 != numberOfMappedLocals) { - getLocalsMap(walkState, romClass, romMethod, offsetPC, result, numberOfMappedLocals, alwaysLocalMap); + if (0 != numberOfMappedLocals) { + if (J9_ARE_ANY_BITS_SET(flags, J9MAPCACHE_LOCALMAP_CACHED)) { + result = romMethodInfo->localmap; + } else { + getLocalsMap(walkState, romClass, romMethod, offsetPC, result, numberOfMappedLocals, alwaysLocalMap); + } #ifdef J9VM_INTERP_STACKWALK_TRACING - swPrintf(walkState, 4, "\tLocals starting at %p for %d slots\n", localBase, numberOfMappedLocals); + swPrintf(walkState, 4, "\tLocals starting at %p for %d slots\n", localBase, numberOfMappedLocals); #endif - walkState->slotType = J9_STACKWALK_SLOT_TYPE_METHOD_LOCAL; - walkState->slotIndex = 0; - walkDescribedPushes(walkState, localBase, numberOfMappedLocals, result, romMethod->argCount); - } + walkState->slotType = J9_STACKWALK_SLOT_TYPE_METHOD_LOCAL; + walkState->slotIndex = 0; + walkDescribedPushes(walkState, localBase, numberOfMappedLocals, result, romMethodInfo->argCount); + } - if (0 != pendingStackHeight) { - getStackMap(walkState, romClass, romMethod, offsetPC, pendingStackHeight, result); + if (0 != pendingStackHeight) { + if (J9_ARE_ANY_BITS_SET(flags, J9MAPCACHE_STACKMAP_CACHED)) { + result = romMethodInfo->stackmap; + } else { + getStackMap(walkState, romClass, romMethod, offsetPC, pendingStackHeight, result); + } #ifdef J9VM_INTERP_STACKWALK_TRACING - swPrintf(walkState, 4, "\tPending stack starting at %p for %d slots\n", pendingBase, pendingStackHeight); + swPrintf(walkState, 4, "\tPending stack starting at %p for %d slots\n", pendingBase, pendingStackHeight); #endif - walkState->slotType = J9_STACKWALK_SLOT_TYPE_PENDING; - walkState->slotIndex = 0; - walkDescribedPushes(walkState, pendingBase, pendingStackHeight, result, 0); - } + walkState->slotType = J9_STACKWALK_SLOT_TYPE_PENDING; + walkState->slotIndex = 0; + walkDescribedPushes(walkState, pendingBase, pendingStackHeight, result, 0); + } - if (result != &smallResult) { - if (NULL == globalBuffer) { - j9mem_free_memory(result); - } else { - j9mapmemory_ReleaseResultsBuffer(vm); + if (freeBuffer) { + if (NULL == globalBuffer) { + j9mem_free_memory(result); + } else { + j9mapmemory_ReleaseResultsBuffer(vm); + } } } } @@ -985,6 +1023,9 @@ walkBytecodeFrame(J9StackWalkState * walkState) #endif /* defined(J9VM_OPT_METHOD_HANDLE) */ UDATA argTempCount = 0; J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method); + J9ROMMethodInfo *romMethodInfo = &walkState->romMethodInfo; + + initializeBasicROMMethodInfo(walkState, romMethod); walkState->constantPool = UNTAGGED_METHOD_CP(walkState->method); @@ -999,16 +1040,16 @@ walkBytecodeFrame(J9StackWalkState * walkState) walkState->bytecodePCOffset = walkState->pc - (U_8 *) J9_BYTECODE_START_FROM_RAM_METHOD(walkState->method); #endif /* defined(J9VM_OPT_METHOD_HANDLE) */ - walkState->argCount = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod); - argTempCount = J9_TEMP_COUNT_FROM_ROM_METHOD(romMethod) + walkState->argCount; + walkState->argCount = romMethodInfo->argCount; + argTempCount = romMethodInfo->tempCount + walkState->argCount; walkState->bp = walkState->arg0EA - argTempCount; - if (romMethod->modifiers & J9AccSynchronized) { + if (romMethodInfo->modifiers & J9AccSynchronized) { #ifdef J9VM_INTERP_LINEAR_STACKWALK_TRACING lswRecordSlot(walkState, walkState->bp, LSW_TYPE_O_SLOT, "Sync Object"); #endif argTempCount += 1; walkState->bp -= 1; - } else if (J9ROMMETHOD_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(romMethod)) { + } else if (((romMethodInfo->modifiers) & (J9AccMethodObjectConstructor | J9AccEmptyMethod)) == J9AccMethodObjectConstructor) { /* Non-empty java.lang.Object. has one hidden temp to hold a copy of the receiver */ #ifdef J9VM_INTERP_LINEAR_STACKWALK_TRACING lswRecordSlot(walkState, walkState->bp, LSW_TYPE_O_SLOT, "Receiver Object"); @@ -1035,8 +1076,8 @@ walkBytecodeFrame(J9StackWalkState * walkState) if (walkState->flags & J9_STACKWALK_ITERATE_O_SLOTS) { WALK_METHOD_CLASS(walkState); - walkBytecodeFrameSlots(walkState, walkState->method, walkState->bytecodePCOffset, - walkState->unwindSP - 1, walkState->unwindSP - walkState->walkSP, + walkBytecodeFrameSlots(walkState, walkState->method, + walkState->bytecodePCOffset, walkState->unwindSP - 1, walkState->unwindSP - walkState->walkSP, walkState->arg0EA, argTempCount, FALSE); } } @@ -1190,6 +1231,9 @@ static void walkJITJNICalloutFrame(J9StackWalkState * walkState) walkState->frameFlags = methodFrame->specialFrameFlags; MARK_SLOT_AS_OBJECT(walkState, (j9object_t*) &(methodFrame->specialFrameFlags)); walkState->method = methodFrame->method; + if (NULL != walkState->method) { + initializeBasicROMMethodInfo(walkState, J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)); + } walkState->constantPool = UNTAGGED_METHOD_CP(walkState->method); #ifdef J9VM_INTERP_STACKWALK_TRACING printFrameType(walkState, "JIT JNI call-out"); @@ -1500,8 +1544,11 @@ static void getLocalsMap(J9StackWalkState * walkState, J9ROMClass * romClass, J9ROMMethod * romMethod, UDATA offsetPC, U_32 * result, UDATA argTempCount, UDATA alwaysLocalMap) { PORT_ACCESS_FROM_WALKSTATE(walkState); - IDATA errorCode; J9JavaVM *vm = walkState->walkThread->javaVM; + J9ROMMethodInfo *romMethodInfo = &walkState->romMethodInfo; + UDATA copySize = ((argTempCount + 31) / 32) * sizeof(U_32); + + ENSURE_ROM_METHOD_INFO_VALID(romMethodInfo); if (!alwaysLocalMap) { /* Detect method entry vs simply executing at PC 0. If the bytecode frame is invisible (method monitor enter or @@ -1520,9 +1567,16 @@ getLocalsMap(J9StackWalkState * walkState, J9ROMClass * romClass, J9ROMMethod * #endif /* j9localmap_ArgBitsForPC0 only deals with args, so zero out the result array to make sure the temps are non-object */ + memset(result, 0, copySize); + if (J9_ARE_ANY_BITS_SET(romMethodInfo->flags, J9MAPCACHE_ARGBITS_CACHED)) { + if (copySize > sizeof(romMethodInfo->argbits)) { + copySize = sizeof(romMethodInfo->argbits); + } + memcpy(result, romMethodInfo->argbits, copySize); + } else { + j9localmap_ArgBitsForPC0(romClass, romMethod, result); + } - memset(result, 0, ((argTempCount + 31) / 32) * sizeof(U_32)); - j9cached_ArgBitsForPC0(romClass, romMethod, result, walkState->javaVM, UNTAGGED_METHOD_CP(walkState->method)->ramClass->classLoader); return; } } @@ -1530,17 +1584,22 @@ getLocalsMap(J9StackWalkState * walkState, J9ROMClass * romClass, J9ROMMethod * #ifdef J9VM_INTERP_STACKWALK_TRACING swPrintf(walkState, 4, "\tUsing local mapper\n"); #endif - errorCode = j9cached_LocalBitsForPC(romClass, romMethod, offsetPC, result, vm, j9mapmemory_GetBuffer, j9mapmemory_ReleaseBuffer, vm, J9_CLASS_FROM_METHOD(walkState->method)->classLoader); - if (errorCode < 0) { - if (J9_ARE_NO_BITS_SET(walkState->flags, J9_STACKWALK_NO_ERROR_REPORT)) { - /* Local map failed, result = %p - aborting VM - needs new message TBD */ - j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_VM_STACK_MAP_FAILED, errorCode); + if (J9_ARE_ANY_BITS_SET(romMethodInfo->flags, J9MAPCACHE_LOCALMAP_CACHED)) { + memcpy(result, romMethodInfo->localmap, copySize); + } else { + IDATA errorCode = vm->localMapFunction(vm->portLibrary, romClass, romMethod, offsetPC, result, vm, j9mapmemory_GetBuffer, j9mapmemory_ReleaseBuffer); + + if (errorCode < 0) { + if (J9_ARE_NO_BITS_SET(walkState->flags, J9_STACKWALK_NO_ERROR_REPORT)) { + /* Local map failed, result = %p - aborting VM - needs new message TBD */ + j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_VM_STACK_MAP_FAILED, errorCode); #if defined(J9VM_INTERP_STACKWALK_TRACING) - Assert_VRB_stackMapFailed(); + Assert_VRB_stackMapFailed(); #else /* J9VM_INTERP_STACKWALK_TRACING */ - Assert_VM_stackMapFailed(); + Assert_VM_stackMapFailed(); #endif /* J9VM_INTERP_STACKWALK_TRACING */ + } } } @@ -1554,7 +1613,7 @@ getStackMap(J9StackWalkState * walkState, J9ROMClass * romClass, J9ROMMethod * r PORT_ACCESS_FROM_WALKSTATE(walkState); IDATA errorCode; - errorCode = j9cached_StackBitsForPC(offsetPC, romClass, romMethod, result, pushCount, walkState->javaVM, j9mapmemory_GetBuffer, j9mapmemory_ReleaseBuffer, walkState->javaVM, UNTAGGED_METHOD_CP(walkState->method)->ramClass->classLoader); + errorCode = j9stackmap_StackBitsForPC(PORTLIB, offsetPC, romClass, romMethod, result, pushCount, walkState->javaVM, j9mapmemory_GetBuffer, j9mapmemory_ReleaseBuffer); if (errorCode < 0) { if (J9_ARE_NO_BITS_SET(walkState->flags, J9_STACKWALK_NO_ERROR_REPORT)) { /* Local map failed, result = %p - aborting VM */