Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ public int getSourceLineNumber() {
* Returns the name and source code location of the method.
*/
public StackTraceElement getSourceReference() {
return getSourceReference(sourceClass, sourceMethodName, sourceLineNumber);
}

public static StackTraceElement getSourceReference(Class<?> sourceClass, String sourceMethodName, int sourceLineNumber) {
if (sourceClass == null) {
return new StackTraceElement("", sourceMethodName, null, sourceLineNumber);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,18 @@
import com.oracle.svm.core.heap.RestrictHeapAccess;
import com.oracle.svm.core.util.VMError;

/**
* Decoder for backtraces computed by {@link BacktraceVisitor} and stored in
* {@link Target_java_lang_Throwable#backtrace}.
*/
public abstract class BacktraceDecoder {

/**
* Visits the backtrace stored in {@code Throwable#backtrace}.
*
* @param backtrace internal backtrace stored in {@link Target_java_lang_Throwable#backtrace}
* @param maxFramesProcessed the maximum number of frames that should be
* {@linkplain #processFrameInfo processed}
* {@linkplain #processSourceReference processed}
* @param maxFramesDecode the maximum number of frames that should be decoded (0 means all)
* @return the number of decoded frames
*/
Expand All @@ -53,12 +57,23 @@ protected final int visitBacktrace(Object backtrace, int maxFramesProcessed, int
int framesDecoded = 0;
if (backtrace != null) {
final long[] trace = (long[]) backtrace;
for (long address : trace) {
if (address == 0) {
break;
int backtraceIndex = 0;
while (backtraceIndex < trace.length && trace[backtraceIndex] != 0) {
long entry = trace[backtraceIndex];
if (BacktraceVisitor.isSourceReference(entry)) {
/* Entry is an encoded source reference. */
VMError.guarantee(backtraceIndex + BacktraceVisitor.entriesPerSourceReference() <= trace.length, "Truncated backtrace array");
visitSourceReference(maxFramesProcessed, framesDecoded, trace, backtraceIndex);
/* Always a single frame. */
framesDecoded++;
backtraceIndex += BacktraceVisitor.entriesPerSourceReference();
} else {
/* Entry is a raw code pointer. */
CodePointer ip = WordFactory.pointer(entry);
/* Arbitrary number of Java frames for a single native frame (inlining). */
framesDecoded = visitCodePointer(ip, framesDecoded, maxFramesProcessed, maxFramesDecodeLimit);
backtraceIndex++;
}
CodePointer ip = WordFactory.pointer(address);
framesDecoded = visitCodePointer(ip, framesDecoded, maxFramesProcessed, maxFramesDecodeLimit);
if (framesDecoded == maxFramesDecodeLimit) {
break;
}
Expand All @@ -67,6 +82,16 @@ protected final int visitBacktrace(Object backtrace, int maxFramesProcessed, int
return framesDecoded - maxFramesProcessed;
}

private void visitSourceReference(int maxFramesProcessed, int framesDecoded, long[] trace, int backtraceIndex) {
int sourceLineNumber = BacktraceVisitor.readSourceLineNumber(trace, backtraceIndex);
Class<?> sourceClass = BacktraceVisitor.readSourceClass(trace, backtraceIndex);
String sourceMethodName = BacktraceVisitor.readSourceMethodName(trace, backtraceIndex);

if (framesDecoded < maxFramesProcessed) {
processSourceReference(sourceClass, sourceMethodName, sourceLineNumber);
}
}

@Uninterruptible(reason = "Prevent the GC from freeing the CodeInfo object.")
private int visitCodePointer(CodePointer ip, int oldFramesDecoded, int maxFramesProcessed, int maxFramesDecode) {
int framesDecoded = oldFramesDecoded;
Expand Down Expand Up @@ -106,7 +131,7 @@ private int visitFrame(CodePointer ip, CodeInfo tetheredCodeInfo, int oldFramesD
continue;
}
if (framesDecoded < maxFramesProcessed) {
processFrameInfo(frameInfo);
processSourceReference(frameInfo.getSourceClass(), frameInfo.getSourceMethodName(), frameInfo.getSourceLineNumber());
}
framesDecoded++;
if (framesDecoded == maxFramesDecode) {
Expand All @@ -117,5 +142,5 @@ private int visitFrame(CodePointer ip, CodeInfo tetheredCodeInfo, int oldFramesD
}

@RestrictHeapAccess(access = RestrictHeapAccess.Access.UNRESTRICTED, reason = "Some implementations allocate.")
protected abstract void processFrameInfo(FrameInfoQueryResult frameInfo);
protected abstract void processSourceReference(Class<?> sourceClass, String sourceMethodName, int sourceLineNumber);
}
Loading