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");
"[,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");
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;
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) {
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) {
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,
gDvmJit.includeSelectedOffset = false;
gDvmJit.methodTable = NULL;
gDvmJit.classTable = NULL;
+ gDvmJit.codeCacheSize = DEFAULT_CODE_CACHE_SIZE;
gDvm.constInit = false;
gDvm.commonInit = false;
#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);
// 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");
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;
}
#ifdef HAVE_ANDROID_OS
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
- if (errno == EINVAL) {
- SLOGW("PR_SET_NO_NEW_PRIVS failed. "
- "Is your kernel compiled correctly?: %s", strerror(errno));
- // Don't return -1 here, since it's expected that not all
- // kernels will support this option.
- } else {
- SLOGW("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
+ // 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;
}
}
*/
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 */