Integrate call-graph information into JIT method blacklist.

The new flag is -Xjitcheckcg which will crawl the stack frame of the
translation requesting thread.

Bug: 2368995
diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c
index 014013d..e7973e3 100644
--- a/vm/compiler/Compiler.c
+++ b/vm/compiler/Compiler.c
@@ -87,6 +87,8 @@
     newOrder->result.discardResult =
         (kind == kWorkOrderTraceDebug || kind == kWorkOrderICPatch) ?
         true : false;
+    newOrder->result.requestingThread = dvmThreadSelf();
+
     gDvmJit.compilerWorkEnqueueIndex++;
     if (gDvmJit.compilerWorkEnqueueIndex == COMPILER_WORK_QUEUE_SIZE)
         gDvmJit.compilerWorkEnqueueIndex = 0;
diff --git a/vm/compiler/Compiler.h b/vm/compiler/Compiler.h
index c66d562..71eed5d 100644
--- a/vm/compiler/Compiler.h
+++ b/vm/compiler/Compiler.h
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <Thread.h>
+
 #ifndef _DALVIK_VM_COMPILER
 #define _DALVIK_VM_COMPILER
 
@@ -39,6 +41,7 @@
     void *codeAddress;
     JitInstructionSetType instructionSet;
     bool discardResult;         // Used for debugging divergence and IC patching
+    Thread *requestingThread;   // For debugging purpose
 } JitTranslationInfo;
 
 typedef enum WorkOrderKind {
diff --git a/vm/compiler/Frontend.c b/vm/compiler/Frontend.c
index 12eb9a7..a4a82c9 100644
--- a/vm/compiler/Frontend.c
+++ b/vm/compiler/Frontend.c
@@ -249,6 +249,36 @@
 }
 
 /*
+ * Crawl the stack of the thread that requesed compilation to see if any of the
+ * ancestors are on the blacklist.
+ */
+bool filterMethodByCallGraph(Thread *thread, const char *curMethodName)
+{
+    /* Crawl the Dalvik stack frames and compare the method name*/
+    StackSaveArea *ssaPtr = ((StackSaveArea *) thread->curFrame) - 1;
+    while (ssaPtr != ((StackSaveArea *) NULL) - 1) {
+        const Method *method = ssaPtr->method;
+        if (method) {
+            int hashValue = dvmComputeUtf8Hash(method->name);
+            bool found =
+                dvmHashTableLookup(gDvmJit.methodTable, hashValue,
+                               (char *) method->name,
+                               (HashCompareFunc) strcmp, false) !=
+                NULL;
+            if (found) {
+                LOGD("Method %s (--> %s) found on the JIT %s list",
+                     method->name, curMethodName,
+                     gDvmJit.includeSelectedMethod ? "white" : "black");
+                return true;
+            }
+
+        }
+        ssaPtr = ((StackSaveArea *) ssaPtr->prevFrame) - 1;
+    };
+    return false;
+}
+
+/*
  * Main entry point to start trace compilation. Basic blocks are constructed
  * first and they will be passed to the codegen routines to convert Dalvik
  * bytecode into machine code.
@@ -319,6 +349,16 @@
                                    (char *) desc->method->name,
                                    (HashCompareFunc) strcmp, false) !=
                     NULL;
+
+                /*
+                 * Debug by call-graph is enabled. Check if the debug list
+                 * covers any methods on the VM stack.
+                 */
+                if (methodFound == false && gDvmJit.checkCallGraph == true) {
+                    methodFound =
+                        filterMethodByCallGraph(info->requestingThread,
+                                                desc->method->name);
+                }
             }
         }
 
diff --git a/vm/compiler/codegen/arm/armv5te-vfp/ArchVariant.c b/vm/compiler/codegen/arm/armv5te-vfp/ArchVariant.c
index 2a8bde1..8b97dc6 100644
--- a/vm/compiler/codegen/arm/armv5te-vfp/ArchVariant.c
+++ b/vm/compiler/codegen/arm/armv5te-vfp/ArchVariant.c
@@ -49,7 +49,6 @@
 #undef JIT_TEMPLATE
 
     /* Target-specific configuration */
-    gDvmJit.blockingMode = false;
     gDvmJit.jitTableSize = 1 << 9; // 512
     gDvmJit.jitTableMask = gDvmJit.jitTableSize - 1;
     gDvmJit.threshold = 200;
diff --git a/vm/compiler/codegen/arm/armv5te/ArchVariant.c b/vm/compiler/codegen/arm/armv5te/ArchVariant.c
index 6dff45a..a6d9c88 100644
--- a/vm/compiler/codegen/arm/armv5te/ArchVariant.c
+++ b/vm/compiler/codegen/arm/armv5te/ArchVariant.c
@@ -49,7 +49,6 @@
 #undef JIT_TEMPLATE
 
     /* Target-specific configuration */
-    gDvmJit.blockingMode = false;
     gDvmJit.jitTableSize = 1 << 9; // 512
     gDvmJit.jitTableMask = gDvmJit.jitTableSize - 1;
     gDvmJit.threshold = 200;
diff --git a/vm/compiler/codegen/arm/armv7-a/ArchVariant.c b/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
index 0e4cc2b..326bec7 100644
--- a/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
+++ b/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
@@ -45,7 +45,6 @@
 #undef JIT_TEMPLATE
 
     /* Target-specific configuration */
-    gDvmJit.blockingMode = false;
     gDvmJit.jitTableSize = 1 << 12; // 4096
     gDvmJit.jitTableMask = gDvmJit.jitTableSize - 1;
     gDvmJit.threshold = 40;