Skip to content

Commit

Permalink
Merge pull request #18014 from thallium/continuation_stackwalk
Browse files Browse the repository at this point in the history
Add DDR command continuationstack
  • Loading branch information
keithc-ca committed Sep 1, 2023
2 parents 2cbea41 + 0f0adc6 commit b212f19
Show file tree
Hide file tree
Showing 19 changed files with 562 additions and 400 deletions.
9 changes: 9 additions & 0 deletions debugtools/DDR_VM/src/com/ibm/j9ddr/AuxFieldInfo29.dat
Expand Up @@ -564,6 +564,15 @@ J9ThreadMonitorPool.entries = required
J9ThreadMonitorPool.next = required
J9TranslationBufferSet.romClassBuilder = required
J9UTF8.length = required
J9VMContinuation.arg0EA = UDATA*
J9VMContinuation.decompilationStack = J9JITDecompilationInfo*
J9VMContinuation.i2jState = J9I2JState
J9VMContinuation.j2iFrame = UDATA*
J9VMContinuation.jitGPRs = J9JITGPRSpillArea
J9VMContinuation.literals = J9Method*
J9VMContinuation.oldEntryLocalStorage = J9VMEntryLocalStorage*
J9VMContinuation.pc = U8*
J9VMContinuation.sp = UDATA*
J9VMEntryLocalStorage.i2jState = required
J9VMEntryLocalStorage.jitFPRegisterStorageBase = required
J9VMEntryLocalStorage.jitGlobalStorageBase = required
Expand Down
10 changes: 6 additions & 4 deletions debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/RootScanner.java
Expand Up @@ -110,12 +110,14 @@ protected RootScanner() throws CorruptDataException

private class RootScannerStackWalkerCallbacks implements IStackWalkerCallbacks
{
public FrameCallbackResult frameWalkFunction(J9VMThreadPointer walkThread, WalkState walkState)
@Override
public FrameCallbackResult frameWalkFunction(WalkState walkState)
{
return FrameCallbackResult.KEEP_ITERATING;
}

public void objectSlotWalkFunction(J9VMThreadPointer walkThread, WalkState walkState, PointerPointer objectSlot, VoidPointer stackLocation)
@Override
public void objectSlotWalkFunction(WalkState walkState, PointerPointer objectSlot, VoidPointer stackLocation)
{
try {
J9ObjectPointer object = J9ObjectPointer.cast(objectSlot.at(0));
Expand All @@ -127,8 +129,8 @@ public void objectSlotWalkFunction(J9VMThreadPointer walkThread, WalkState walkS
}
}

public void fieldSlotWalkFunction(J9VMThreadPointer walkThread,
WalkState walkState, ObjectReferencePointer objectSlot,
@Override
public void fieldSlotWalkFunction(WalkState walkState, ObjectReferencePointer objectSlot,
VoidPointer stackLocation)
{
try {
Expand Down
15 changes: 8 additions & 7 deletions debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/StackRoots.java
Expand Up @@ -51,12 +51,14 @@ public class StackRoots

private class StackWalkerCallbacks implements IStackWalkerCallbacks
{
public FrameCallbackResult frameWalkFunction(J9VMThreadPointer walkThread, WalkState walkState)
@Override
public FrameCallbackResult frameWalkFunction(WalkState walkState)
{
return FrameCallbackResult.KEEP_ITERATING;
}

public void objectSlotWalkFunction(J9VMThreadPointer walkThread, WalkState walkState, PointerPointer objectSlot, VoidPointer stackAddress)

@Override
public void objectSlotWalkFunction(WalkState walkState, PointerPointer objectSlot, VoidPointer stackAddress)
{
if (walkState.method.isNull()){
/* adding an object slot iterator causes us to be called for
Expand All @@ -76,10 +78,9 @@ public void objectSlotWalkFunction(J9VMThreadPointer walkThread, WalkState walkS
throw new UnsupportedOperationException("Corrupt objectSlot detected");
}
}


public void fieldSlotWalkFunction(J9VMThreadPointer walkThread,
WalkState walkState, ObjectReferencePointer objectSlot,

@Override
public void fieldSlotWalkFunction(WalkState walkState, ObjectReferencePointer objectSlot,
VoidPointer stackLocation)
{
if (walkState.method.isNull()){
Expand Down
Expand Up @@ -24,7 +24,6 @@
import com.ibm.j9ddr.vm29.pointer.ObjectReferencePointer;
import com.ibm.j9ddr.vm29.pointer.PointerPointer;
import com.ibm.j9ddr.vm29.pointer.VoidPointer;
import com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer;

/**
* Base implementation of IStackWalkerCallbacks that does performs no-ops
Expand All @@ -41,22 +40,22 @@ public class BaseStackWalkerCallbacks implements IStackWalkerCallbacks
/* (non-Javadoc)
* @see com.ibm.j9ddr.vm.j9.stackwalker.IStackWalkerCallbacks#frameWalkFunction(com.ibm.j9ddr.vm.j9.stackwalker.WalkState)
*/
public FrameCallbackResult frameWalkFunction(J9VMThreadPointer walkThread,
WalkState walkState)
@Override
public FrameCallbackResult frameWalkFunction(WalkState walkState)
{
// Deliberately do nothing
return FrameCallbackResult.KEEP_ITERATING;
}

public void objectSlotWalkFunction(J9VMThreadPointer walkThread,
WalkState walkState, PointerPointer objectSlot,
@Override
public void objectSlotWalkFunction(WalkState walkState, PointerPointer objectSlot,
VoidPointer stackLocation)
{
// Deliberately do nothing
}

public void fieldSlotWalkFunction(J9VMThreadPointer walkThread,
WalkState walkState, ObjectReferencePointer objectSlot,
@Override
public void fieldSlotWalkFunction(WalkState walkState, ObjectReferencePointer objectSlot,
VoidPointer stackLocation)
{
// Deliberately do nothing
Expand Down
Expand Up @@ -24,7 +24,6 @@
import com.ibm.j9ddr.vm29.pointer.ObjectReferencePointer;
import com.ibm.j9ddr.vm29.pointer.PointerPointer;
import com.ibm.j9ddr.vm29.pointer.VoidPointer;
import com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer;

/**
* Interface for stack-walker callback routines.
Expand All @@ -35,14 +34,14 @@
public interface IStackWalkerCallbacks
{

public FrameCallbackResult frameWalkFunction(J9VMThreadPointer walkThread, WalkState walkState);
public FrameCallbackResult frameWalkFunction(WalkState walkState);

public void objectSlotWalkFunction(J9VMThreadPointer walkThread, WalkState walkState, PointerPointer objectSlot, VoidPointer stackLocation);
public void objectSlotWalkFunction(WalkState walkState, PointerPointer objectSlot, VoidPointer stackLocation);

/**
* This callback doesn't exist in the native C.
*
* It's purpose in DDR is passing back field slots in stack-allocated objects (which would be incorrectly handled by a PointerPointer)
*/
public void fieldSlotWalkFunction(J9VMThreadPointer walkThread, WalkState walkState, ObjectReferencePointer objectSlot, VoidPointer stackLocation);
public void fieldSlotWalkFunction(WalkState walkState, ObjectReferencePointer objectSlot, VoidPointer stackLocation);
}
Expand Up @@ -62,7 +62,6 @@
import com.ibm.j9ddr.vm29.pointer.generated.J9SFNativeMethodFramePointer;
import com.ibm.j9ddr.vm29.pointer.generated.J9SFSpecialFramePointer;
import com.ibm.j9ddr.vm29.pointer.generated.J9UTF8Pointer;
import com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer;
import com.ibm.j9ddr.vm29.pointer.helper.J9UTF8Helper;
import com.ibm.j9ddr.vm29.structure.J9ITable;
import com.ibm.j9ddr.vm29.structure.J9JITFrame;
Expand Down Expand Up @@ -106,9 +105,9 @@ static void jitPrintRegisterMapArray(WalkState walkState, String description) th
getImpl().jitPrintRegisterMapArray(walkState,description);
}

static J9JITExceptionTablePointer jitGetExceptionTableFromPC(J9VMThreadPointer walkThread, U8Pointer pc) throws CorruptDataException
static J9JITExceptionTablePointer jitGetExceptionTableFromPC(J9JavaVMPointer javaVM, U8Pointer pc) throws CorruptDataException
{
return getImpl().jitGetExceptionTableFromPC(walkThread, pc);
return getImpl().jitGetExceptionTableFromPC(javaVM, pc);
}

private static IJITStackWalker impl;
Expand Down Expand Up @@ -137,7 +136,7 @@ private static interface IJITStackWalker extends IAlgorithm

public void jitPrintRegisterMapArray(WalkState walkState, String description) throws CorruptDataException;

public J9JITExceptionTablePointer jitGetExceptionTableFromPC(J9VMThreadPointer walkThread, U8Pointer pc) throws CorruptDataException;
public J9JITExceptionTablePointer jitGetExceptionTableFromPC(J9JavaVMPointer javaVM, U8Pointer pc) throws CorruptDataException;
}

/**
Expand Down Expand Up @@ -214,7 +213,7 @@ public FrameCallbackResult jitWalkStackFrames(WalkState walkState)
walkState.outgoingArgCount = walkState.argCount;

if (((walkState.flags & J9_STACKWALK_SKIP_INLINES) == 0) && getJitInlinedCallInfo(walkState.jitInfo).notNull()) {
jitGetMapsFromPC(walkState.walkThread.javaVM(), walkState.jitInfo, UDATA.cast(walkState.pc), maps);
jitGetMapsFromPC(walkState.javaVM, walkState.jitInfo, UDATA.cast(walkState.pc), maps);
if (maps.inlineMap.notNull()) {
VoidPointer inlinedCallSite = getFirstInlinedCallSite(walkState.jitInfo, VoidPointer.cast(maps.inlineMap));
walkState.arg0EA = UDATAPointer.NULL;
Expand All @@ -238,7 +237,7 @@ public FrameCallbackResult jitWalkStackFrames(WalkState walkState)
}
}
} else if ((walkState.flags & J9_STACKWALK_RECORD_BYTECODE_PC_OFFSET) != 0) {
jitGetMapsFromPC(walkState.walkThread.javaVM(), walkState.jitInfo, UDATA.cast(walkState.pc),maps);
jitGetMapsFromPC(walkState.javaVM, walkState.jitInfo, UDATA.cast(walkState.pc), maps);
}

SET_A0_CP_METHOD(walkState);
Expand Down Expand Up @@ -278,7 +277,7 @@ public FrameCallbackResult jitWalkStackFrames(WalkState walkState)

/* JIT pair with no mapping indicates a bytecoded frame */
failedPC = walkState.pc;
returnTable = PointerPointer.cast(walkState.walkThread.javaVM().jitConfig().i2jReturnTable());
returnTable = PointerPointer.cast(walkState.javaVM.jitConfig().i2jReturnTable());
if (returnTable.notNull()) {
for (i = 0; i < J9SW_JIT_RETURN_TABLE_SIZE; ++i) {
if (failedPC.eq(U8Pointer.cast(returnTable.at(i)))) break;
Expand Down Expand Up @@ -309,11 +308,11 @@ private J9JITExceptionTablePointer jitGetExceptionTable(
{
/* this is done with a macro in C */
if (! J9BuildFlags.jit_fullSpeedDebug) {
return jitGetExceptionTableFromPC(walkState.walkThread, walkState.pc);
return jitGetExceptionTableFromPC(walkState.javaVM, walkState.pc);
}

J9JITDecompilationInfoPointer stack;
J9JITExceptionTablePointer result = jitGetExceptionTableFromPC(walkState.walkThread, walkState.pc);
J9JITExceptionTablePointer result = jitGetExceptionTableFromPC(walkState.javaVM, walkState.pc);

walkState.decompilationRecord = J9JITDecompilationInfoPointer.NULL;
if (result.notNull()) return result;
Expand All @@ -333,7 +332,7 @@ private J9JITExceptionTablePointer jitGetExceptionTable(
}
walkState.decompilationRecord = walkState.decompilationStack;
walkState.decompilationStack = walkState.decompilationStack.next();
return jitGetExceptionTableFromPC(walkState.walkThread,walkState.pc);
return jitGetExceptionTableFromPC(walkState.javaVM, walkState.pc);
}

stack = walkState.decompilationStack;
Expand All @@ -348,9 +347,9 @@ private J9JITExceptionTablePointer jitGetExceptionTable(
}

public J9JITExceptionTablePointer jitGetExceptionTableFromPC(
J9VMThreadPointer walkThread, U8Pointer pc) throws CorruptDataException
J9JavaVMPointer javaVM, U8Pointer pc) throws CorruptDataException
{
J9JITConfigPointer jitConfig = walkThread.javaVM().jitConfig();
J9JITConfigPointer jitConfig = javaVM.jitConfig();

if (jitConfig.isNull()) {
return J9JITExceptionTablePointer.NULL;
Expand Down Expand Up @@ -419,7 +418,7 @@ private void jitWalkResolveMethodFrame(WalkState walkState) throws CorruptDataEx
ramMethod = J9MethodPointer.cast(iTableOffset).untag(J9_ITABLE_OFFSET_TAG_BITS);
} else if (0 != (iTableOffset & J9_ITABLE_OFFSET_VIRTUAL)) {
long vTableOffset = iTableOffset & ~J9_ITABLE_OFFSET_TAG_BITS;
J9JavaVMPointer vm = walkState.walkThread.javaVM();
J9JavaVMPointer vm = walkState.javaVM;
// C code uses Object from the VM constant pool, but that's not easily
// accessible to DDR. Any class will do.
J9ClassPointer clazz = vm.booleanArrayClass();
Expand Down Expand Up @@ -646,7 +645,7 @@ private char jitNextSigChar(String signatureString) throws CorruptDataException

private U64Pointer jitFPRParmAddress(WalkState walkState, UDATA fpParmNumber) throws CorruptDataException
{
U64Pointer base = U64Pointer.cast(walkState.walkedEntryLocalStorage.jitFPRegisterStorageBase());
U64Pointer base = U64Pointer.cast(walkState.jitFPRegisterStorageBase);

if (J9BuildFlags.arch_s390) {
/* 390 uses FPR0/2/4/6 for arguments, so double fpParmNumber to get the right register */
Expand All @@ -664,7 +663,7 @@ private U64Pointer jitFPRParmAddress(WalkState walkState, UDATA fpParmNumber) th
* save slots for JIT FPRs, so if vector registers are enabled, the save location for a
* JIT FPR is (base + (16 * 64) + (128 * FPRNumber)), or (base + (64 * (16 + (2 * FPRNumber)))).
*/
if (0 != (walkState.walkThread.javaVM().extendedRuntimeFlags().longValue() & J9_EXTENDED_RUNTIME_USE_VECTOR_REGISTERS)) {
if (0 != (walkState.javaVM.extendedRuntimeFlags().longValue() & J9_EXTENDED_RUNTIME_USE_VECTOR_REGISTERS)) {
fpParmNumber = fpParmNumber.add(fpParmNumber).add(16);
}
}
Expand Down Expand Up @@ -983,7 +982,7 @@ private FrameCallbackResult walkTransitionFrame(WalkState walkState) throws Corr
private void jitAddSpilledRegistersForResolve(WalkState walkState) throws CorruptDataException
{
try {
UDATAPointer slotCursor = walkState.walkedEntryLocalStorage.jitGlobalStorageBase();
UDATAPointer slotCursor = walkState.jitGlobalStorageBase;
int mapCursor = 0;
int i;

Expand All @@ -1000,7 +999,7 @@ private void jitAddSpilledRegistersForResolve(WalkState walkState) throws Corrup

private void jitAddSpilledRegistersForINL(WalkState walkState) throws CorruptDataException
{
UDATAPointer slotCursor = walkState.walkedEntryLocalStorage.jitGlobalStorageBase();
UDATAPointer slotCursor = walkState.jitGlobalStorageBase;
int i;

for (i = 0; i < J9SW_JIT_CALLEE_PRESERVED_SIZE; ++i) {
Expand Down Expand Up @@ -1079,7 +1078,7 @@ private void jitWalkFrame(WalkState walkState, boolean walkLocals, VoidPointer s
WALK_METHOD_CLASS(walkState);

if (stackMap.isNull()) {
stackMap = getStackMapFromJitPC(walkState.walkThread.javaVM(), walkState.jitInfo, UDATA.cast(walkState.pc));
stackMap = getStackMapFromJitPC(walkState.javaVM, walkState.jitInfo, UDATA.cast(walkState.pc));
if (stackMap.isNull()) {
throw new AddressedCorruptDataException(walkState.jitInfo.getAddress(),"Unable to locate JIT stack map");
}
Expand All @@ -1095,7 +1094,7 @@ private void jitWalkFrame(WalkState walkState, boolean walkLocals, VoidPointer s
mapBytesRemaining = new UDATA(getJitNumberOfMapBytes(gcStackAtlas));

jitDescriptionCursor = getJitStackSlots(walkState.jitInfo, stackMap);
stackAllocMapCursor = U8Pointer.cast(getStackAllocMapFromJitPC(walkState.walkThread.javaVM(), walkState.jitInfo, UDATA.cast(walkState.pc), stackMap));
stackAllocMapCursor = U8Pointer.cast(getStackAllocMapFromJitPC(walkState.javaVM, walkState.jitInfo, UDATA.cast(walkState.pc), stackMap));
stackAllocMapBits = new U8(0);

walkState.slotType = (int)J9_STACKWALK_SLOT_TYPE_METHOD_LOCAL;
Expand Down Expand Up @@ -1217,7 +1216,7 @@ stack frame (once for parms and once for autos).
swPrintf(walkState, 4, "\t\t\tF-Slot[{0}] = {1}", slot.getHexAddress(), slot.at(0).getHexAddress());

if (walkState.callBacks != null) {
walkState.callBacks.fieldSlotWalkFunction(walkState.walkThread, walkState, slot, VoidPointer.cast(slot));
walkState.callBacks.fieldSlotWalkFunction(walkState, slot, VoidPointer.cast(slot));
}

}
Expand Down Expand Up @@ -1278,7 +1277,7 @@ private void jitWalkRegisterMap(WalkState walkState, VoidPointer stackMap, J9JIT
swPrintf(walkState, 4, "\t\tJIT-RegisterMap-O-Slot[{0}] = {1} ({2})",
targetObject.getHexAddress(),
oldObject.getHexAddress(), jitRegisterNames[mapCursor]);
walkState.callBacks.objectSlotWalkFunction(walkState.walkThread, walkState, targetObject, VoidPointer.cast(targetObject));
walkState.callBacks.objectSlotWalkFunction(walkState, targetObject, VoidPointer.cast(targetObject));

newObject = targetObject.isNull() ? J9ObjectPointer.NULL : J9ObjectPointer.cast(targetObject.at(0));

Expand Down
Expand Up @@ -1234,7 +1234,7 @@ that does the stack check failure check (can result in GC). Avoid
oldPinningArrayAddress.getHexAddress(),
walkState.bp.getHexAddress(),
offsetOfFirstInternalPtr);
walkState.callBacks.objectSlotWalkFunction(walkState.walkThread, walkState, currPinningArrayCursor, VoidPointer.cast(currPinningArrayCursor));
walkState.callBacks.objectSlotWalkFunction(walkState, currPinningArrayCursor, VoidPointer.cast(currPinningArrayCursor));
newPinningArrayAddress = J9ObjectPointer.cast( currPinningArrayCursor.at(0) );
displacement = new IDATA( UDATA.cast(newPinningArrayAddress).sub(UDATA.cast(oldPinningArrayAddress)));
walkState.slotIndex++;
Expand Down

0 comments on commit b212f19

Please sign in to comment.