3737import com .oracle .svm .core .heap .RestrictHeapAccess ;
3838import 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+ */
4044public 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