OSDN Git Service

merge in klp-release history after reset to klp-dev
[android-x86/dalvik.git] / vm / Init.cpp
index 90d1d3a..f1762c9 100644 (file)
@@ -28,6 +28,9 @@
 #include <linux/fs.h>
 #include <cutils/fs.h>
 #include <unistd.h>
+#ifdef HAVE_ANDROID_OS
+#include <sys/prctl.h>
+#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:<filename>\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.
@@ -1662,12 +1708,43 @@ static bool initZygote()
     const char* target_base = getenv("EMULATED_STORAGE_TARGET");
     if (target_base != NULL) {
         if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV,
-                "uid=0,gid=1028,mode=0050") == -1) {
+                "uid=0,gid=1028,mode=0751") == -1) {
             SLOGE("Failed to mount tmpfs to %s: %s", target_base, strerror(errno));
             return -1;
         }
     }
 
+    // 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;
 }
 
@@ -2082,17 +2159,6 @@ void dvmAbort()
      */
     dvmPrintNativeBackTrace();
 
-    /*
-     * If we call abort(), all threads in the process receives a SIBABRT.
-     * debuggerd dumps the stack trace of the main thread, whether or not
-     * that was the thread that failed.
-     *
-     * By stuffing a value into a bogus address, we cause a segmentation
-     * fault in the current thread, and get a useful log from debuggerd.
-     * We can also trivially tell the difference between a VM crash and
-     * a deliberate abort by looking at the fault address.
-     */
-    *((char*)0xdeadd00d) = result;
     abort();
 
     /* notreached */