Skip to content

Commit

Permalink
Merge pull request #8615 from fjeremic/cache-iteratestacktrace-peek-r…
Browse files Browse the repository at this point in the history
…amclass

Improve performance of iterateStackTrace
  • Loading branch information
DanHeidinga committed May 4, 2020
2 parents d80689c + 0921605 commit 284a67d
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 44 deletions.
2 changes: 1 addition & 1 deletion runtime/j9vm/j7vmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1419,7 +1419,7 @@ typedef struct GetStackTraceElementUserData {

/* Return TRUE to keep iterating, FALSE to halt the walk. */
static UDATA
getStackTraceElementIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader)
getStackTraceElementIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass)
{
GetStackTraceElementUserData * userData = voidUserData;

Expand Down
35 changes: 18 additions & 17 deletions runtime/jcl/common/jclexception.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "vm_api.h"
#include "ut_j9jcl.h"

static UDATA getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader);
static UDATA getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass);

/**
* Saves enough context into the StackTraceElement to allow printing later. For
Expand Down Expand Up @@ -83,7 +83,7 @@ setStackTraceElementSource(J9VMThread* vmThread, j9object_t stackTraceElement, J


static UDATA
getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader)
getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass)
{
J9GetStackTraceUserData * userData = voidUserData;
J9JavaVM * vm = vmThread->javaVM;
Expand Down Expand Up @@ -121,7 +121,6 @@ getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * r
J9UTF8 * utf = NULL;
j9object_t string = NULL;
UDATA j2seVersion = J2SE_VERSION(vm) & J2SE_VERSION_MASK;
J9Class* clazz = NULL;

PUSH_OBJECT_IN_SPECIAL_FRAME(vmThread, element);

Expand All @@ -130,13 +129,15 @@ getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * r
* able to handle the case where the J9Class cannot be found
*/
if (NULL != classLoader) {
clazz = vmFuncs->peekClassHashTable(vmThread, classLoader, J9UTF8_DATA(utfClassName), J9UTF8_LENGTH(utfClassName));
if (NULL != clazz) {
/* clazz can never be an array here as arrays can't define methods so we don't need to
if (NULL == ramClass) {
ramClass = vmFuncs->peekClassHashTable(vmThread, classLoader, J9UTF8_DATA(utfClassName), J9UTF8_LENGTH(utfClassName));
}
if (NULL != ramClass) {
/* ramClass can never be an array here as arrays can't define methods so we don't need to
* take them into account in the code below when writing the interned string back to
* the Class object.
*/
Assert_JCL_false(J9CLASS_IS_ARRAY(clazz));
Assert_JCL_false(J9CLASS_IS_ARRAY(ramClass));
}
}

Expand Down Expand Up @@ -169,8 +170,8 @@ getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * r
/* Fetch the J9Module from the j.l.Class->j.l.Module field if we have a class.
* Otherwise the more painful package-based lookup must be performed
*/
if (clazz != NULL) {
j9object_t moduleObject = J9VMJAVALANGCLASS_MODULE(vmThread, clazz->classObject);
if (ramClass != NULL) {
j9object_t moduleObject = J9VMJAVALANGCLASS_MODULE(vmThread, ramClass->classObject);
module = J9OBJECT_ADDRESS_LOAD(vmThread, moduleObject, vm->modulePointerOffset);
} else {
UDATA length = packageNameLength(romClass);
Expand All @@ -189,8 +190,8 @@ getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * r
/* Fill in method class */
string = NULL;
{
if (NULL != clazz) {
string = J9VMJAVALANGCLASS_CLASSNAMESTRING(vmThread, J9VM_J9CLASS_TO_HEAPCLASS(clazz));
if (NULL != ramClass) {
string = J9VMJAVALANGCLASS_CLASSNAMESTRING(vmThread, J9VM_J9CLASS_TO_HEAPCLASS(ramClass));
}
if (NULL == string) {
UDATA flags = J9_STR_XLAT | J9_STR_TENURE | J9_STR_INTERN;
Expand All @@ -203,9 +204,9 @@ getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * r
/* exception is pending from the call */
goto done;
} else {
if (NULL != clazz) {
if (NULL != ramClass) {
/* Class name was interned so it's safe to write it back to the Class Object */
J9VMJAVALANGCLASS_SET_CLASSNAMESTRING(vmThread, J9VM_J9CLASS_TO_HEAPCLASS(clazz), string);
J9VMJAVALANGCLASS_SET_CLASSNAMESTRING(vmThread, J9VM_J9CLASS_TO_HEAPCLASS(ramClass), string);
}
}
}
Expand Down Expand Up @@ -235,8 +236,8 @@ getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * r
* This avoids additional allocations during stack trace generation
*/
string = NULL;
if (clazz != NULL) {
string = J9VMJAVALANGCLASS_FILENAMESTRING(vmThread, J9VM_J9CLASS_TO_HEAPCLASS(clazz));
if (ramClass != NULL) {
string = J9VMJAVALANGCLASS_FILENAMESTRING(vmThread, J9VM_J9CLASS_TO_HEAPCLASS(ramClass));
}
if (string == NULL) {
if (fileName != NULL) {
Expand All @@ -261,9 +262,9 @@ getStackTraceIterator(J9VMThread * vmThread, void * voidUserData, J9ROMClass * r
}
}
Assert_JCL_notNull(string);
if (clazz != NULL) {
if (ramClass != NULL) {
/* Update the cached fileNameString on the class so subsequent calls will find it */
J9VMJAVALANGCLASS_SET_FILENAMESTRING(vmThread, J9VM_J9CLASS_TO_HEAPCLASS(clazz), string);
J9VMJAVALANGCLASS_SET_FILENAMESTRING(vmThread, J9VM_J9CLASS_TO_HEAPCLASS(ramClass), string);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4347,7 +4347,7 @@ typedef struct J9InternalVMFunctions {
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
void ( *cleanUpClassLoader)(struct J9VMThread *vmThread, struct J9ClassLoader* classLoader) ;
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
UDATA ( *iterateStackTrace)(struct J9VMThread * vmThread, j9object_t* exception, UDATA (*callback) (struct J9VMThread * vmThread, void * userData, struct J9ROMClass * romClass, struct J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, struct J9ClassLoader* classLoader), void * userData, UDATA pruneConstructors) ;
UDATA ( *iterateStackTrace)(struct J9VMThread * vmThread, j9object_t* exception, UDATA (*callback) (struct J9VMThread * vmThread, void * userData, struct J9ROMClass * romClass, struct J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, struct J9ClassLoader* classLoader, struct J9Class* ramClass), void * userData, UDATA pruneConstructors) ;
void ( *internalReleaseVMAccessNoMutex)(struct J9VMThread * vmThread) ;
struct J9HookInterface** ( *getVMHookInterface)(struct J9JavaVM* vm) ;
IDATA ( *internalAttachCurrentThread)(struct J9JavaVM * vm, struct J9VMThread ** p_env, struct J9JavaVMAttachArgs * thr_args, UDATA threadType, void * osThread) ;
Expand Down
5 changes: 3 additions & 2 deletions runtime/oti/vm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -551,13 +551,14 @@ internalExceptionDescribe(J9VMThread *vmThread);
* @param userData
* @param method
* @param fileName
* @param lineNumber)
* @param lineNumber
* @param ramClass)
* @param userData
* @param pruneConstructors
* @return UDATA
*/
UDATA
iterateStackTrace(J9VMThread * vmThread, j9object_t* exception, UDATA (*callback) (J9VMThread * vmThread, void * userData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader), void * userData, UDATA pruneConstructors);
iterateStackTrace(J9VMThread * vmThread, j9object_t* exception, UDATA (*callback) (J9VMThread * vmThread, void * userData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass), void * userData, UDATA pruneConstructors);


/* ---------------- exceptionsupport.c ---------------- */
Expand Down
6 changes: 3 additions & 3 deletions runtime/rasdump/javadump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@

/* Callback Function prototypes */
UDATA writeFrameCallBack (J9VMThread* vmThread, J9StackWalkState* state);
UDATA writeExceptionFrameCallBack (J9VMThread* vmThread, void* userData, J9ROMClass* romClass, J9ROMMethod* romMethod, J9UTF8* sourceFile, UDATA lineNumber, J9ClassLoader* classLoader);
UDATA writeExceptionFrameCallBack (J9VMThread* vmThread, void* userData, J9ROMClass* romClass, J9ROMMethod* romMethod, J9UTF8* sourceFile, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass);
void writeLoaderCallBack (void* classLoader, void* userData);
void writeLibrariesCallBack (void* classLoader, void* userData);
void writeClassesCallBack (void* classLoader, void* userData);
Expand Down Expand Up @@ -224,7 +224,7 @@ private :

/* Allow the callback functions access */
friend UDATA writeFrameCallBack (J9VMThread* vmThread, J9StackWalkState* state);
friend UDATA writeExceptionFrameCallBack (J9VMThread* vmThread, void* userData, J9ROMClass* romClass, J9ROMMethod* romMethod, J9UTF8* sourceFile, UDATA lineNumber, J9ClassLoader* classLoader);
friend UDATA writeExceptionFrameCallBack (J9VMThread* vmThread, void* userData, J9ROMClass* romClass, J9ROMMethod* romMethod, J9UTF8* sourceFile, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass);
friend void writeLoaderCallBack (void* classLoader, void* userData);
friend void writeLibrariesCallBack (void* classLoader, void* userData);
friend void writeClassesCallBack (void* classLoader, void* userData);
Expand Down Expand Up @@ -5374,7 +5374,7 @@ writeFrameCallBack(J9VMThread* vmThread, J9StackWalkState* state)
}

UDATA
writeExceptionFrameCallBack(J9VMThread* vmThread, void* userData, J9ROMClass* romClass, J9ROMMethod* romMethod, J9UTF8* sourceFile, UDATA lineNumber, J9ClassLoader* classLoader)
writeExceptionFrameCallBack(J9VMThread* vmThread, void* userData, J9ROMClass* romClass, J9ROMMethod* romMethod, J9UTF8* sourceFile, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass)
{
JavaCoreDumpWriter *jcdw = (JavaCoreDumpWriter *)((J9StackWalkState*)userData)->userData1;
return jcdw->writeExceptionFrame(userData, romClass, romMethod, sourceFile, lineNumber);
Expand Down
4 changes: 2 additions & 2 deletions runtime/rasdump/trigger.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2019 IBM Corp. and others
* Copyright (c) 1991, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -126,7 +126,7 @@ struct ExceptionStackFrame
};

static UDATA
countExceptionStackFrame(J9VMThread *vmThread, void *userData, J9ROMClass *romClass, J9ROMMethod *romMethod, J9UTF8 *fileName, UDATA lineNumber, J9ClassLoader* classLoader)
countExceptionStackFrame(J9VMThread *vmThread, void *userData, J9ROMClass *romClass, J9ROMMethod *romMethod, J9UTF8 *fileName, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass)
{
struct ExceptionStackFrame *frame = (struct ExceptionStackFrame *) userData;

Expand Down
10 changes: 5 additions & 5 deletions runtime/shared_common/include/SCQueryFunctions.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2019 IBM Corp. and others
* Copyright (c) 2001, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -36,7 +36,7 @@ extern "C"
#if defined (J9VM_SHRTEST) && defined (J9SHR_CACHELET_SUPPORT)
/*This function is not used from shrtest -Xrealtime */
#else
static BOOLEAN
static VMINLINE BOOLEAN
j9shr_Query_IsCacheFull(J9JavaVM *vm)
{
BOOLEAN retval = TRUE;
Expand Down Expand Up @@ -70,7 +70,7 @@ j9shr_Query_IsCacheFull(J9JavaVM *vm)
#if defined (J9VM_SHRTEST) && defined (J9SHR_CACHELET_SUPPORT)
/*This function is not used from shrtest -Xrealtime */
#else
static BOOLEAN
static VMINLINE BOOLEAN
j9shr_Query_IsAddressInCache(J9JavaVM *vm, void *address, UDATA length)
{
BOOLEAN retval = FALSE;
Expand All @@ -93,7 +93,7 @@ j9shr_Query_IsAddressInCache(J9JavaVM *vm, void *address, UDATA length)
* @return TRUE if the the address range is in the readWrite cache. False otherwise.
**/

static BOOLEAN
static VMINLINE BOOLEAN
j9shr_Query_IsAddressInReadWriteCache(J9JavaVM *vm, void *address, UDATA length)
{
BOOLEAN retval = FALSE;
Expand All @@ -108,7 +108,7 @@ j9shr_Query_IsAddressInReadWriteCache(J9JavaVM *vm, void *address, UDATA length)
#endif

#if !defined (J9VM_SHRTEST)
static void
static VMINLINE void
j9shr_Query_PopulatePreinitConfigDefaults(J9JavaVM *vm, J9SharedClassPreinitConfig *updatedWithDefaults)
{
if ((NULL != vm) && (NULL != vm->sharedClassConfig)) {
Expand Down
58 changes: 45 additions & 13 deletions runtime/vm/exceptiondescribe.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2019 IBM Corp. and others
* Copyright (c) 1991, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -33,8 +33,9 @@
#include "objhelp.h"
#include "vm_internal.h"
#include "jvminit.h"
#include "SCQueryFunctions.h"

typedef UDATA (*callback_func_t) (J9VMThread * vmThread, void * userData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader);
typedef UDATA (*callback_func_t) (J9VMThread * vmThread, void * userData, J9ROMClass * romClass, J9ROMMethod * romMethod, J9UTF8 * fileName, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass);

static void printExceptionInThread (J9VMThread* vmThread);
static UDATA isSubclassOfThreadDeath (J9VMThread *vmThread, j9object_t exception);
Expand Down Expand Up @@ -99,7 +100,7 @@ printExceptionMessage(J9VMThread* vmThread, j9object_t exception) {

/* assumes VM access */
static UDATA
printStackTraceEntry(J9VMThread * vmThread, void * voidUserData, J9ROMClass *romClass, J9ROMMethod * romMethod, J9UTF8 * sourceFile, UDATA lineNumber, J9ClassLoader* classLoader) {
printStackTraceEntry(J9VMThread * vmThread, void * voidUserData, J9ROMClass *romClass, J9ROMMethod * romMethod, J9UTF8 * sourceFile, UDATA lineNumber, J9ClassLoader* classLoader, J9Class* ramClass) {
const char* format;
J9JavaVM *vm = vmThread->javaVM;
J9InternalVMFunctions * vmFuncs = vm->internalVMFunctions;
Expand Down Expand Up @@ -280,6 +281,7 @@ iterateStackTrace(J9VMThread * vmThread, j9object_t* exception, callback_func_t
UDATA lineNumber = 0;
J9UTF8 * fileName = NULL;
J9ClassLoader *classLoader = NULL;
J9Class *ramClass = NULL;
#ifdef J9VM_INTERP_NATIVE_SUPPORT
J9JITExceptionTable * metaData = NULL;
UDATA inlineDepth = 0;
Expand Down Expand Up @@ -308,7 +310,6 @@ iterateStackTrace(J9VMThread * vmThread, j9object_t* exception, callback_func_t
#ifdef J9VM_INTERP_NATIVE_SUPPORT
if (metaData) {
J9Method *ramMethod;
J9Class *ramClass;
UDATA isSameReceiver;
inlinedEntry:
/* Check for metadata unload */
Expand Down Expand Up @@ -343,11 +344,46 @@ iterateStackTrace(J9VMThread * vmThread, j9object_t* exception, callback_func_t
pruneConstructors = FALSE;
#endif
romClass = findROMClassFromPC(vmThread, methodPC, &classLoader);
if(romClass) {
romMethod = findROMMethodInROMClass(vmThread, romClass, methodPC);
if (romMethod != NULL) {
methodPC -= (UDATA) J9_BYTECODE_START_FROM_ROM_METHOD(romMethod);
if (NULL != romClass) {
J9UTF8 const *utfClassName = J9ROMCLASS_CLASSNAME(romClass);

ramClass = peekClassHashTable(vmThread, classLoader, J9UTF8_DATA(utfClassName), J9UTF8_LENGTH(utfClassName));
if (ramClass == NULL) {
if (j9shr_Query_IsAddressInCache(vm, romClass, romClass->romSize)) {
/* Probe the application loader to determine if it has the J9Class for the current class.
* This secondary probe is required as all ROMClasses from the SCC appear to be owned
* by the bootstrap classloader.
*/
ramClass = peekClassHashTable(vmThread, vm->applicationClassLoader, J9UTF8_DATA(utfClassName), J9UTF8_LENGTH(utfClassName));
}
}

while (NULL != ramClass) {
U_32 i = 0;
J9Method *methods = ramClass->ramMethods;
for (i = 0; i < romClass->romMethodCount; ++i) {
J9ROMMethod *possibleMethod = J9_ROM_METHOD_FROM_RAM_METHOD(&methods[i]);

/* Note that we cannot use `J9_BYTECODE_START_FROM_ROM_METHOD` here because native method PCs
* point to the start of the J9ROMMethod data structure
*/
if ((methodPC >= (UDATA)possibleMethod) && (methodPC < (UDATA)J9_BYTECODE_END_FROM_ROM_METHOD(possibleMethod))) {
romMethod = possibleMethod;
methodPC -= (UDATA)J9_BYTECODE_START_FROM_ROM_METHOD(romMethod);
goto foundROMMethod;
}
}

ramClass = ramClass->replacedClass;
}

if (NULL == romMethod) {
romMethod = findROMMethodInROMClass(vmThread, romClass, methodPC);
if (NULL != romMethod) {
methodPC -= (UDATA)J9_BYTECODE_START_FROM_ROM_METHOD(romMethod);
}
}
foundROMMethod: ;
}
#ifdef J9VM_INTERP_NATIVE_SUPPORT
}
Expand All @@ -363,7 +399,7 @@ iterateStackTrace(J9VMThread * vmThread, j9object_t* exception, callback_func_t
/* Call the callback with the information */

if (callback != NULL) {
callbackResult = callback(vmThread, userData, romClass, romMethod, fileName, lineNumber, classLoader);
callbackResult = callback(vmThread, userData, romClass, romMethod, fileName, lineNumber, classLoader, ramClass);
}

#ifdef J9VM_OPT_DEBUG_INFO_SERVER
Expand Down Expand Up @@ -535,7 +571,3 @@ isSubclassOfThreadDeath(J9VMThread *vmThread, j9object_t exception)

return FALSE;
}




0 comments on commit 284a67d

Please sign in to comment.