diff options
Diffstat (limited to 'vm/Init.c')
-rw-r--r-- | vm/Init.c | 159 |
1 files changed, 159 insertions, 0 deletions
@@ -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 |