Associate Java source code line number with JIT traces.
Sample output:
D/dalvikvm( 400): TRACEPROFILE 0x426d945c 5192426 [0x4(+32), 810] Lcom/android/unit_tests/PerformanceTests$AddMemberVariableTest;testRun;()V
D/dalvikvm( 400): TRACEPROFILE 0x426d955c 263 [0x2(+1), 809] (omitted)
D/dalvikvm( 400): TRACEPROFILE 0x426d9640 0 [0x53(+1), 344] (omitted)
D/dalvikvm( 400): TRACEPROFILE 0x426d960c 0 [0x72(+1), 271] (omitted)
D/dalvikvm( 400): TRACEPROFILE 0x426d9590 0 [0x74(+5), 272] (omitted)
For the first line:
5192426: execution count of this trace
0x4: starting bytecode offset
+32: number of instructions included in the trace
810: line number corresponding to 0x4 in the file containing the method
Also add WITH_JIT_TUNING for now whenever JIT is enabled.
diff --git a/vm/Android.mk b/vm/Android.mk
index cea83a1..1fbe59b 100644
--- a/vm/Android.mk
+++ b/vm/Android.mk
@@ -191,6 +191,8 @@
ifeq ($(WITH_JIT),true)
# NOTE: Turn on assertion for JIT for now
LOCAL_CFLAGS += -DWITH_DALVIK_ASSERT
+ # NOTE: Also turn on tuning when JIT is enabled for now
+ LOCAL_CFLAGS += -DWITH_JIT_TUNING
LOCAL_CFLAGS += -DWITH_JIT
LOCAL_SRC_FILES += \
../dexdump/OpCodeNames.c \
diff --git a/vm/interp/Jit.c b/vm/interp/Jit.c
index 54d24af..abd6379 100644
--- a/vm/interp/Jit.c
+++ b/vm/interp/Jit.c
@@ -126,6 +126,25 @@
}
#endif
+typedef struct jitProfileAddrToLine {
+ u4 lineNum;
+ u4 bytecodeOffset;
+} jitProfileAddrToLine;
+
+
+/* Callback function to track the bytecode offset/line number relationiship */
+static int addrToLineCb (void *cnxt, u4 bytecodeOffset, u4 lineNum)
+{
+ jitProfileAddrToLine *addrToLine = (jitProfileAddrToLine *) cnxt;
+
+ /* Best match so far for this offset */
+ if (addrToLine->bytecodeOffset >= bytecodeOffset) {
+ addrToLine->lineNum = lineNum;
+ }
+done:
+ return 0;
+}
+
/* Dumps profile info for a single trace */
int dvmCompilerDumpTraceProfile(struct JitEntry *p)
{
@@ -155,12 +174,31 @@
desc = (JitTraceDescription*) ((char*)pCellCounts + sizeof(*pCellCounts));
method = desc->method;
char *methodDesc = dexProtoCopyMethodDescriptor(&method->prototype);
- LOGD("TRACEPROFILE 0x%08x % 10d %s%s;%s [0x%x,%d]", (int)traceBase,
- *pExecutionCount,
- method->clazz->descriptor, method->name, methodDesc,
- desc->trace[0].frag.startOffset,
- desc->trace[0].frag.numInsts);
+ jitProfileAddrToLine addrToLine = {0, desc->trace[0].frag.startOffset};
+
+ /*
+ * We may end up decoding the debug information for the same method
+ * multiple times, but the tradeoff is we don't need to allocate extra
+ * space to store the addr/line mapping. Since this is a debugging feature
+ * and done infrequently so the slower but simpler mechanism should work
+ * just fine.
+ */
+ dexDecodeDebugInfo(method->clazz->pDvmDex->pDexFile,
+ dvmGetMethodCode(method),
+ method->clazz->descriptor,
+ method->prototype.protoIdx,
+ method->accessFlags,
+ addrToLineCb, NULL, &addrToLine);
+
+ LOGD("TRACEPROFILE 0x%08x % 10d [%#x(+%d), %d] %s%s;%s",
+ (int)traceBase,
+ *pExecutionCount,
+ desc->trace[0].frag.startOffset,
+ desc->trace[0].frag.numInsts,
+ addrToLine.lineNum,
+ method->clazz->descriptor, method->name, methodDesc);
free(methodDesc);
+
return *pExecutionCount;
}