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;
 }