Skip to content

Commit db60f8c

Browse files
committed
[GR-45765] Optimize Throwable#fillInStackTrace for JIT compiled code
PullRequest: graal/14670
2 parents bb4a66d + e7f3046 commit db60f8c

File tree

4 files changed

+303
-44
lines changed

4 files changed

+303
-44
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoQueryResult.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ public int getSourceLineNumber() {
353353
* Returns the name and source code location of the method.
354354
*/
355355
public StackTraceElement getSourceReference() {
356+
return getSourceReference(sourceClass, sourceMethodName, sourceLineNumber);
357+
}
358+
359+
public static StackTraceElement getSourceReference(Class<?> sourceClass, String sourceMethodName, int sourceLineNumber) {
356360
if (sourceClass == null) {
357361
return new StackTraceElement("", sourceMethodName, null, sourceLineNumber);
358362
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/BacktraceDecoder.java

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,18 @@
3737
import com.oracle.svm.core.heap.RestrictHeapAccess;
3838
import com.oracle.svm.core.util.VMError;
3939

40+
/**
41+
* Decoder for backtraces computed by {@link BacktraceVisitor} and stored in
42+
* {@link Target_java_lang_Throwable#backtrace}.
43+
*/
4044
public abstract class BacktraceDecoder {
4145

4246
/**
4347
* Visits the backtrace stored in {@code Throwable#backtrace}.
4448
*
4549
* @param backtrace internal backtrace stored in {@link Target_java_lang_Throwable#backtrace}
4650
* @param maxFramesProcessed the maximum number of frames that should be
47-
* {@linkplain #processFrameInfo processed}
51+
* {@linkplain #processSourceReference processed}
4852
* @param maxFramesDecode the maximum number of frames that should be decoded (0 means all)
4953
* @return the number of decoded frames
5054
*/
@@ -53,12 +57,23 @@ protected final int visitBacktrace(Object backtrace, int maxFramesProcessed, int
5357
int framesDecoded = 0;
5458
if (backtrace != null) {
5559
final long[] trace = (long[]) backtrace;
56-
for (long address : trace) {
57-
if (address == 0) {
58-
break;
60+
int backtraceIndex = 0;
61+
while (backtraceIndex < trace.length && trace[backtraceIndex] != 0) {
62+
long entry = trace[backtraceIndex];
63+
if (BacktraceVisitor.isSourceReference(entry)) {
64+
/* Entry is an encoded source reference. */
65+
VMError.guarantee(backtraceIndex + BacktraceVisitor.entriesPerSourceReference() <= trace.length, "Truncated backtrace array");
66+
visitSourceReference(maxFramesProcessed, framesDecoded, trace, backtraceIndex);
67+
/* Always a single frame. */
68+
framesDecoded++;
69+
backtraceIndex += BacktraceVisitor.entriesPerSourceReference();
70+
} else {
71+
/* Entry is a raw code pointer. */
72+
CodePointer ip = WordFactory.pointer(entry);
73+
/* Arbitrary number of Java frames for a single native frame (inlining). */
74+
framesDecoded = visitCodePointer(ip, framesDecoded, maxFramesProcessed, maxFramesDecodeLimit);
75+
backtraceIndex++;
5976
}
60-
CodePointer ip = WordFactory.pointer(address);
61-
framesDecoded = visitCodePointer(ip, framesDecoded, maxFramesProcessed, maxFramesDecodeLimit);
6277
if (framesDecoded == maxFramesDecodeLimit) {
6378
break;
6479
}
@@ -67,6 +82,16 @@ protected final int visitBacktrace(Object backtrace, int maxFramesProcessed, int
6782
return framesDecoded - maxFramesProcessed;
6883
}
6984

85+
private void visitSourceReference(int maxFramesProcessed, int framesDecoded, long[] trace, int backtraceIndex) {
86+
int sourceLineNumber = BacktraceVisitor.readSourceLineNumber(trace, backtraceIndex);
87+
Class<?> sourceClass = BacktraceVisitor.readSourceClass(trace, backtraceIndex);
88+
String sourceMethodName = BacktraceVisitor.readSourceMethodName(trace, backtraceIndex);
89+
90+
if (framesDecoded < maxFramesProcessed) {
91+
processSourceReference(sourceClass, sourceMethodName, sourceLineNumber);
92+
}
93+
}
94+
7095
@Uninterruptible(reason = "Prevent the GC from freeing the CodeInfo object.")
7196
private int visitCodePointer(CodePointer ip, int oldFramesDecoded, int maxFramesProcessed, int maxFramesDecode) {
7297
int framesDecoded = oldFramesDecoded;
@@ -106,7 +131,7 @@ private int visitFrame(CodePointer ip, CodeInfo tetheredCodeInfo, int oldFramesD
106131
continue;
107132
}
108133
if (framesDecoded < maxFramesProcessed) {
109-
processFrameInfo(frameInfo);
134+
processSourceReference(frameInfo.getSourceClass(), frameInfo.getSourceMethodName(), frameInfo.getSourceLineNumber());
110135
}
111136
framesDecoded++;
112137
if (framesDecoded == maxFramesDecode) {
@@ -117,5 +142,5 @@ private int visitFrame(CodePointer ip, CodeInfo tetheredCodeInfo, int oldFramesD
117142
}
118143

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

0 commit comments

Comments
 (0)