summaryrefslogtreecommitdiffstats
path: root/vm/Init.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm/Init.c')
-rw-r--r--vm/Init.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/vm/Init.c b/vm/Init.c
index 4ba10b736..5295f4921 100644
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -20,6 +20,7 @@
#include "Dalvik.h"
#include "test/Test.h"
#include "mterp/Mterp.h"
+#include "Hash.h"
#include <stdlib.h>
#include <stdio.h>
@@ -49,6 +50,11 @@ static bool dvmInitZygote(void);
/* global state */
struct DvmGlobals gDvm;
+/* JIT-specific global state */
+#if defined(WITH_JIT)
+struct DvmJitGlobals gDvmJit;
+#endif
+
/*
* Show usage.
*
@@ -83,8 +89,13 @@ static void dvmUsage(const char* progName)
kMinStackSize / 1024, kMaxStackSize / 1024);
dvmFprintf(stderr, " -Xverify:{none,remote,all}\n");
dvmFprintf(stderr, " -Xrs\n");
+#if defined(WITH_JIT)
+ dvmFprintf(stderr,
+ " -Xint (extended to accept ':portable', ':fast' and ':jit')\n");
+#else
dvmFprintf(stderr,
" -Xint (extended to accept ':portable' and ':fast')\n");
+#endif
dvmFprintf(stderr, "\n");
dvmFprintf(stderr, "These are unique to Dalvik:\n");
dvmFprintf(stderr, " -Xzygote\n");
@@ -98,6 +109,17 @@ static void dvmUsage(const char* progName)
dvmFprintf(stderr, " -Xgc:[no]precise\n");
dvmFprintf(stderr, " -Xgenregmap\n");
dvmFprintf(stderr, " -Xcheckdexsum\n");
+#if defined(WITH_JIT)
+ dvmFprintf(stderr, " -Xincludeselectedop\n");
+ dvmFprintf(stderr, " -Xjitop:hexopvalue[-endvalue]"
+ "[,hexopvalue[-endvalue]]*\n");
+ dvmFprintf(stderr, " -Xincludeselectedmethod\n");
+ dvmFprintf(stderr, " -Xthreshold:decimalvalue\n");
+ dvmFprintf(stderr, " -Xblocking\n");
+ dvmFprintf(stderr, " -Xjitmethod:signture[,signature]* "
+ "(eg Ljava/lang/String\\;replace)\n");
+ dvmFprintf(stderr, " -Xjitverbose\n");
+#endif
dvmFprintf(stderr, "\n");
dvmFprintf(stderr, "Configured with:"
#ifdef WITH_DEBUGGER
@@ -161,6 +183,9 @@ static void dvmUsage(const char* progName)
#elif DVM_RESOLVER_CACHE == DVM_RC_NO_CACHE
" resolver_cache_disabled"
#endif
+#if defined(WITH_JIT)
+ " with_jit"
+#endif
);
#ifdef DVM_SHOW_EXCEPTION
dvmFprintf(stderr, " show_exception=%d", DVM_SHOW_EXCEPTION);
@@ -531,6 +556,97 @@ static void freeAssertionCtrl(void)
free(gDvm.assertionCtrl);
}
+#if defined(WITH_JIT)
+/* Parse -Xjitop to selectively turn on/off certain opcodes for JIT */
+static void processXjitop(const char *opt)
+{
+ if (opt[7] == ':') {
+ const char *startPtr = &opt[8];
+ char *endPtr = NULL;
+
+ do {
+ long startValue, endValue;
+
+ startValue = strtol(startPtr, &endPtr, 16);
+ if (startPtr != endPtr) {
+ /* Just in case value is out of range */
+ startValue &= 0xff;
+
+ if (*endPtr == '-') {
+ endValue = strtol(endPtr+1, &endPtr, 16);
+ endValue &= 0xff;
+ } else {
+ endValue = startValue;
+ }
+
+ for (; startValue <= endValue; startValue++) {
+ LOGW("Dalvik opcode %x is selected for debugging",
+ (unsigned int) startValue);
+ /* Mark the corresponding bit to 1 */
+ gDvmJit.opList[startValue >> 3] |=
+ 1 << (startValue & 0x7);
+ }
+
+ if (*endPtr == 0) {
+ break;
+ }
+
+ startPtr = endPtr + 1;
+
+ continue;
+ } else {
+ if (*endPtr != 0) {
+ dvmFprintf(stderr,
+ "Warning: Unrecognized opcode value substring "
+ "%s\n", endPtr);
+ }
+ break;
+ }
+ } while (1);
+ } else {
+ int i;
+ for (i = 0; i < 32; i++) {
+ gDvmJit.opList[i] = 0xff;
+ }
+ dvmFprintf(stderr, "Warning: select all opcodes\n");
+ }
+}
+
+/* Parse -Xjitmethod to selectively turn on/off certain methods for JIT */
+static void processXjitmethod(const char *opt)
+{
+ char *buf = strdup(&opt[12]);
+ char *start, *end;
+
+ gDvmJit.methodTable = dvmHashTableCreate(8, NULL);
+
+ start = buf;
+ /*
+ * Break comma-separated method signatures and enter them into the hash
+ * table individually.
+ */
+ do {
+ int hashValue;
+
+ end = strchr(start, ',');
+ if (end) {
+ *end = 0;
+ }
+
+ hashValue = dvmComputeUtf8Hash(start);
+
+ dvmHashTableLookup(gDvmJit.methodTable, hashValue,
+ strdup(start),
+ (HashCompareFunc) strcmp, true);
+ if (end) {
+ start = end + 1;
+ } else {
+ break;
+ }
+ } while (1);
+ free(buf);
+}
+#endif
/*
* Process an argument vector full of options. Unlike standard C programs,
@@ -760,6 +876,10 @@ static int dvmProcessOptions(int argc, const char* const argv[],
gDvm.executionMode = kExecutionModeInterpPortable;
else if (strcmp(argv[i] + 6, "fast") == 0)
gDvm.executionMode = kExecutionModeInterpFast;
+#ifdef WITH_JIT
+ else if (strcmp(argv[i] + 6, "jit") == 0)
+ gDvm.executionMode = kExecutionModeJit;
+#endif
else {
dvmFprintf(stderr,
"Warning: Unrecognized interpreter mode %s\n",argv[i]);
@@ -769,6 +889,23 @@ static int dvmProcessOptions(int argc, const char* const argv[],
/* disable JIT -- nothing to do here for now */
}
+#ifdef WITH_JIT
+ } else if (strncmp(argv[i], "-Xjitop", 7) == 0) {
+ processXjitop(argv[i]);
+ } else if (strncmp(argv[i], "-Xjitmethod", 11) == 0) {
+ processXjitmethod(argv[i]);
+ } else if (strncmp(argv[i], "-Xblocking", 10) == 0) {
+ gDvmJit.blockingMode = true;
+ } else if (strncmp(argv[i], "-Xthreshold:", 12) == 0) {
+ gDvmJit.threshold = atoi(argv[i] + 12);
+ } else if (strncmp(argv[i], "-Xincludeselectedop", 19) == 0) {
+ gDvmJit.includeSelectedOp = true;
+ } else if (strncmp(argv[i], "-Xincludeselectedmethod", 23) == 0) {
+ gDvmJit.includeSelectedMethod = true;
+ } else if (strncmp(argv[i], "-Xjitverbose", 12) == 0) {
+ gDvmJit.printMe = true;
+#endif
+
} else if (strncmp(argv[i], "-Xdeadlockpredict:", 18) == 0) {
#ifdef WITH_DEADLOCK_PREDICTION
if (strcmp(argv[i] + 18, "off") == 0)
@@ -867,7 +1004,18 @@ static void setCommandLineDefaults()
* we know we're using the "desktop" build we should probably be
* using "portable" rather than "fast".
*/
+#if defined(WITH_JIT)
+ gDvm.executionMode = kExecutionModeJit;
+ /*
+ * TODO - check system property and insert command-line options in
+ * frameworks/base/core/jni/AndroidRuntime.cpp
+ */
+ gDvmJit.blockingMode = false;
+ gDvmJit.maxTableEntries = 2048;
+ gDvmJit.threshold = 200;
+#else
gDvm.executionMode = kExecutionModeInterpFast;
+#endif
}
@@ -904,6 +1052,9 @@ static void blockSignals()
sigemptyset(&mask);
sigaddset(&mask, SIGQUIT);
sigaddset(&mask, SIGUSR1); // used to initiate heap dump
+#if defined(WITH_JIT) && defined(WITH_JIT_TUNING)
+ sigaddset(&mask, SIGUSR2); // used to investigate JIT internals
+#endif
//sigaddset(&mask, SIGPIPE);
cc = sigprocmask(SIG_BLOCK, &mask, NULL);
assert(cc == 0);
@@ -1195,6 +1346,11 @@ bool dvmInitAfterZygote(void)
(int)(endHeap-startHeap), (int)(endQuit-startQuit),
(int)(endJdwp-startJdwp), (int)(endJdwp-startHeap));
+#ifdef WITH_JIT
+ if (!dvmJitStartup())
+ return false;
+#endif
+
return true;
}
@@ -1389,6 +1545,9 @@ void dvmShutdown(void)
LOGD("VM cleaning up\n");
+#ifdef WITH_JIT
+ dvmJitShutdown();
+#endif
dvmDebuggerShutdown();
dvmReflectShutdown();
#ifdef WITH_PROFILER