X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=vm%2FInit.cpp;h=2c81f67f98d7997027a247644b30d7def7de97e1;hb=8723464b85290c1b348bf3e29d06e6d0a291fd4c;hp=6601dffcd4ebf3263306a197299089c03da1729e;hpb=0e25ea3c4bc998c51b1a90f8e2f004b4db5f1095;p=android-x86%2Fdalvik.git diff --git a/vm/Init.cpp b/vm/Init.cpp index 6601dffcd..2c81f67f9 100644 --- a/vm/Init.cpp +++ b/vm/Init.cpp @@ -28,6 +28,9 @@ #include #include #include +#ifdef HAVE_ANDROID_OS +#include +#endif #include "Dalvik.h" #include "test/Test.h" @@ -118,8 +121,6 @@ static void usage(const char* progName) dvmFprintf(stderr, " -Xzygote\n"); dvmFprintf(stderr, " -Xdexopt:{none,verified,all,full}\n"); dvmFprintf(stderr, " -Xnoquithandler\n"); - dvmFprintf(stderr, - " -Xjnigreflimit:N (must be multiple of 100, >= 200)\n"); dvmFprintf(stderr, " -Xjniopts:{warnonly,forcecopy}\n"); dvmFprintf(stderr, " -Xjnitrace:substring (eg NativeClass or nativeMethod)\n"); dvmFprintf(stderr, " -Xstacktracefile:\n"); @@ -138,6 +139,7 @@ static void usage(const char* progName) "[,hexopvalue[-endvalue]]*\n"); dvmFprintf(stderr, " -Xincludeselectedmethod\n"); dvmFprintf(stderr, " -Xjitthreshold:decimalvalue\n"); + dvmFprintf(stderr, " -Xjitcodecachesize:decimalvalueofkbytes\n"); dvmFprintf(stderr, " -Xjitblocking\n"); dvmFprintf(stderr, " -Xjitmethod:signature[,signature]* " "(eg Ljava/lang/String\\;replace)\n"); @@ -938,6 +940,8 @@ static int processOptions(int argc, const char* const argv[], dvmFprintf(stderr, "Invalid -XX:HeapMaxFree option '%s'\n", argv[i]); return -1; } + } else if (strcmp(argv[i], "-XX:LowMemoryMode") == 0) { + gDvm.lowMemoryMode = true; } else if (strncmp(argv[i], "-XX:HeapTargetUtilization=", 26) == 0) { const char* start = argv[i] + 26; const char* end = start; @@ -1073,13 +1077,7 @@ static int processOptions(int argc, const char* const argv[], return -1; } } else if (strncmp(argv[i], "-Xjnigreflimit:", 15) == 0) { - int lim = atoi(argv[i] + 15); - if (lim < 200 || (lim % 100) != 0) { - dvmFprintf(stderr, "Bad value for -Xjnigreflimit: '%s'\n", - argv[i]+15); - return -1; - } - gDvm.jniGrefLimit = lim; + // Ignored for backwards compatibility. } else if (strncmp(argv[i], "-Xjnitrace:", 11) == 0) { gDvm.jniTrace = strdup(argv[i] + 11); } else if (strcmp(argv[i], "-Xlog-stdio") == 0) { @@ -1123,6 +1121,11 @@ static int processOptions(int argc, const char* const argv[], gDvmJit.blockingMode = true; } else if (strncmp(argv[i], "-Xjitthreshold:", 15) == 0) { gDvmJit.threshold = atoi(argv[i] + 15); + } else if (strncmp(argv[i], "-Xjitcodecachesize:", 19) == 0) { + gDvmJit.codeCacheSize = atoi(argv[i] + 19) * 1024; + if (gDvmJit.codeCacheSize == 0) { + gDvm.executionMode = kExecutionModeInterpFast; + } } else if (strncmp(argv[i], "-Xincludeselectedop", 19) == 0) { gDvmJit.includeSelectedOp = true; } else if (strncmp(argv[i], "-Xincludeselectedmethod", 23) == 0) { @@ -1238,6 +1241,7 @@ static void setCommandLineDefaults() gDvm.heapStartingSize = 2 * 1024 * 1024; // Spec says 16MB; too big for us. gDvm.heapMaximumSize = 16 * 1024 * 1024; // Spec says 75% physical mem gDvm.heapGrowthLimit = 0; // 0 means no growth limit + gDvm.lowMemoryMode = false; gDvm.stackSize = kDefaultStackSize; gDvm.mainThreadStackSize = kDefaultStackSize; // When the heap is less than the maximum or growth limited size, @@ -1278,6 +1282,7 @@ static void setCommandLineDefaults() gDvmJit.includeSelectedOffset = false; gDvmJit.methodTable = NULL; gDvmJit.classTable = NULL; + gDvmJit.codeCacheSize = DEFAULT_CODE_CACHE_SIZE; gDvm.constInit = false; gDvm.commonInit = false; @@ -1334,7 +1339,7 @@ static void blockSignals() #if defined(WITH_JIT) && defined(WITH_JIT_TUNING) sigaddset(&mask, SIGUSR2); // used to investigate JIT internals #endif - //sigaddset(&mask, SIGPIPE); + sigaddset(&mask, SIGPIPE); cc = sigprocmask(SIG_BLOCK, &mask, NULL); assert(cc == 0); @@ -1622,6 +1627,20 @@ static bool registerSystemNatives(JNIEnv* pEnv) // First set up JniConstants, which is used by libcore. JniConstants::init(pEnv); + // Set up our single JNI method. + // TODO: factor this out if we add more. + jclass c = pEnv->FindClass("java/lang/Class"); + if (c == NULL) { + dvmAbort(); + } + JNIEXPORT jobject JNICALL Java_java_lang_Class_getDex(JNIEnv* env, jclass javaClass); + const JNINativeMethod Java_java_lang_Class[] = { + { "getDex", "()Lcom/android/dex/Dex;", (void*) Java_java_lang_Class_getDex }, + }; + if (pEnv->RegisterNatives(c, Java_java_lang_Class, 1) != JNI_OK) { + dvmAbort(); + } + // Most JNI libraries can just use System.loadLibrary, but you can't // if you're the library that implements System.loadLibrary! loadJniLibrary("javacore"); @@ -1633,6 +1652,33 @@ static bool registerSystemNatives(JNIEnv* pEnv) return true; } +/* + * Copied and modified slightly from system/core/toolbox/mount.c + */ +static std::string getMountsDevDir(const char *arg) +{ + char mount_dev[256]; + char mount_dir[256]; + int match; + + FILE *fp = fopen("/proc/self/mounts", "r"); + if (fp == NULL) { + ALOGE("Could not open /proc/self/mounts: %s", strerror(errno)); + return ""; + } + + while ((match = fscanf(fp, "%255s %255s %*s %*s %*d %*d\n", mount_dev, mount_dir)) != EOF) { + mount_dev[255] = 0; + mount_dir[255] = 0; + if (match == 2 && (strcmp(arg, mount_dir) == 0)) { + fclose(fp); + return mount_dev; + } + } + + fclose(fp); + return ""; +} /* * Do zygote-mode-only initialization. @@ -1668,6 +1714,37 @@ static bool initZygote() } } + // Mark /system as NOSUID | NODEV + const char* android_root = getenv("ANDROID_ROOT"); + + if (android_root == NULL) { + SLOGE("environment variable ANDROID_ROOT does not exist?!?!"); + return -1; + } + + std::string mountDev(getMountsDevDir(android_root)); + if (mountDev.empty()) { + SLOGE("Unable to find mount point for %s", android_root); + return -1; + } + + if (mount(mountDev.c_str(), android_root, "none", + MS_REMOUNT | MS_NOSUID | MS_NODEV | MS_RDONLY | MS_BIND, NULL) == -1) { + SLOGE("Remount of %s failed: %s", android_root, strerror(errno)); + return -1; + } + +#ifdef HAVE_ANDROID_OS + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { + // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return + // EINVAL. Don't die on such kernels. + if (errno != EINVAL) { + SLOGE("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno)); + return -1; + } + } +#endif + return true; }