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;