OSDN Git Service

Add tracing of native function calls to Dalvik.
authorJack Veenstra <veenstra@android.com>
Tue, 19 May 2009 21:36:48 +0000 (14:36 -0700)
committerJack Veenstra <veenstra@android.com>
Tue, 19 May 2009 22:52:53 +0000 (15:52 -0700)
Dalvik already traces Java method calls but it doesn't trace JNI calls.
This adds new trace records for JNI calls.

vm/Profile.c

index 6055580..8c731f9 100644 (file)
@@ -635,43 +635,58 @@ void dvmEmitEmulatorTrace(const Method* method, int action)
 {
 #ifdef UPDATE_MAGIC_PAGE
     /*
-     * We want to store the address of the Dalvik bytecodes.  Native and
-     * abstract methods don't have any, so we don't do this for those.
+     * We store the address of the Dalvik bytecodes to the memory-mapped
+     * trace page for normal Java methods.  We also trace calls to native
+     * functions by storing the address of the native function to the
+     * trace page.
+     * Abstract methods don't have any bytecodes, so we don't trace them.
      * (Abstract methods are never called, but in Dalvik they can be
-     * because we do a "late trap" to generate the abstract method
-     * exception.  However, we trap to a native method, so we don't need
-     * an explicit check for abstract here.)
+     * because we do a "late trap" to a native method to generate the
+     * abstract method exception.)
      */
-    if (dvmIsNativeMethod(method))
+    if (dvmIsAbstractMethod(method))
         return;
-    assert(method->insns != NULL);
 
     u4* pMagic = (u4*) gDvm.emulatorTracePage;
-
-    /*
-     * The dexlist output shows the &DexCode.insns offset value, which
-     * is offset from the start of the base DEX header. Method.insns
-     * is the absolute address, effectively offset from the start of
-     * the optimized DEX header. We either need to return the
-     * optimized DEX base file address offset by the right amount, or
-     * take the "real" address and subtract off the size of the
-     * optimized DEX header.
-     *
-     * Would be nice to factor this out at dexlist time, but we can't count
-     * on having access to the correct optimized DEX file.
-     */
     u4 addr;
-#if 0
-    DexFile* pDexFile = method->clazz->pDvmDex->pDexFile;
-    addr = (u4)pDexFile->pOptHeader; /* file starts at "opt" header */
-    addr += dvmGetMethodCode(method)->insnsOff;
-#else
-    const DexOptHeader* pOptHdr = method->clazz->pDvmDex->pDexFile->pOptHeader;
-    addr = (u4) method->insns - pOptHdr->dexOffset;
-#endif
-    assert(METHOD_TRACE_ENTER == 0);
-    assert(METHOD_TRACE_EXIT == 1);
-    assert(METHOD_TRACE_UNROLL == 2);
+
+    if (dvmIsNativeMethod(method)) {
+        /*
+         * The "action" parameter is one of:
+         *   0 = ENTER
+         *   1 = EXIT
+         *   2 = UNROLL
+         * To help the trace tools reconstruct the runtime stack containing
+         * a mix of Java plus native methods, we add 4 to the action if this
+         * is a native method.
+         */
+        action += 4;
+
+        /*
+         * Get the address of the native function.
+         * This isn't the right address -- how do I get it?
+         * Fortunately, the trace tools can get by without the address, but
+         * it would be nice to fix this.
+         */
+         addr = method->nativeFunc;
+    } else {
+        /*
+         * The dexlist output shows the &DexCode.insns offset value, which
+         * is offset from the start of the base DEX header. Method.insns
+         * is the absolute address, effectively offset from the start of
+         * the optimized DEX header. We either need to return the
+         * optimized DEX base file address offset by the right amount, or
+         * take the "real" address and subtract off the size of the
+         * optimized DEX header.
+         *
+         * Would be nice to factor this out at dexlist time, but we can't count
+         * on having access to the correct optimized DEX file.
+         */
+        assert(method->insns != NULL);
+        const DexOptHeader* pOptHdr = method->clazz->pDvmDex->pDexFile->pOptHeader;
+        addr = (u4) method->insns - pOptHdr->dexOffset;
+    }
+
     *(pMagic+action) = addr;
     LOGVV("Set %p = 0x%08x (%s.%s)\n",
         pMagic+action, addr, method->clazz->descriptor, method->name);