Add support for oat files in /data/art-cache
Also implement Zygote_nativeForkAndSpecialize
Change-Id: I7dfb257b2897279a4cdac4b1ca194c1ac84eb047
diff --git a/src/class_linker.cc b/src/class_linker.cc
index adabe97..6ad6543 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -551,9 +551,9 @@
std::string oat_filename;
oat_filename += runtime->GetHostPrefix();
oat_filename += oat_location->ToModifiedUtf8();
- OatFile* oat_file = OatFile::Open(std::string(oat_filename), "", image_header.GetOatBaseAddr());
+ OatFile* oat_file = OatFile::Open(oat_filename, "", image_header.GetOatBaseAddr());
if (oat_file == NULL) {
- LOG(ERROR) << "Failed to open oat file " << oat_filename << " referenced from image";
+ LOG(ERROR) << "Failed to open oat file " << oat_filename << " referenced from image.";
return NULL;
}
uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();
@@ -596,8 +596,22 @@
const OatFile* oat_file = OatFile::Open(location, "", NULL);
if (oat_file == NULL) {
- LOG(ERROR) << "Failed to open oat file " << location;
- return NULL;
+ if (location.empty() || location[0] != '/') {
+ LOG(ERROR) << "Failed to open oat file from " << location;
+ return NULL;
+ }
+ // not found in /foo/bar/baz.oat? try /data/art-cache/foo@bar@baz.oat
+ std::string art_cache = GetArtCacheOrDie();
+ std::string cache_file(location, 1); // skip leading slash
+ std::replace(cache_file.begin(), cache_file.end(), '/', '@');
+ std::string cache_location = art_cache + "/" + cache_file;
+ oat_file = OatFile::Open(cache_location, "", NULL);
+ if (oat_file == NULL) {
+ LOG(ERROR) << "Failed to open oat file from " << location << " or " << cache_location << ".";
+ return NULL;
+ }
+
+
}
return oat_file;
}
diff --git a/src/dalvik_system_Zygote.cc b/src/dalvik_system_Zygote.cc
index 2e715c7..7c0b6a6 100644
--- a/src/dalvik_system_Zygote.cc
+++ b/src/dalvik_system_Zygote.cc
@@ -277,6 +277,11 @@
return pid;
}
+jint Zygote_nativeForkAndSpecialize(JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
+ jint debugFlags, jobjectArray rlimits) {
+ return forkAndSpecializeCommon(env, uid, gid, gids, debugFlags, rlimits, 0, 0);
+}
+
jint Zygote_nativeForkSystemServer(JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debugFlags, jobjectArray rlimits,
jlong permittedCapabilities, jlong effectiveCapabilities) {
@@ -301,7 +306,7 @@
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Zygote, nativeExecShell, "(Ljava/lang/String;)V"),
//NATIVE_METHOD(Zygote, nativeFork, "()I"),
- //NATIVE_METHOD(Zygote, nativeForkAndSpecialize, "(II[II[[I)I"),
+ NATIVE_METHOD(Zygote, nativeForkAndSpecialize, "(II[II[[I)I"),
NATIVE_METHOD(Zygote, nativeForkSystemServer, "(II[II[[IJJ)I"),
};
diff --git a/src/dex_file.cc b/src/dex_file.cc
index a84c316..fa6d9d5 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -9,7 +9,6 @@
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/stat.h>
-#include <sys/types.h>
#include <map>
@@ -208,35 +207,8 @@
cache_file.append(kClassesDex);
// Example cache_file = parent@dir@foo.jar@classes.dex
- const char* data_root = getenv("ANDROID_DATA");
- if (data_root == NULL) {
- if (OS::DirectoryExists("/data")) {
- data_root = "/data";
- } else {
- data_root = "/tmp";
- }
- }
- if (!OS::DirectoryExists(data_root)) {
- LOG(ERROR) << "Failed to find ANDROID_DATA directory " << data_root;
- return NULL;
- }
-
- std::string art_cache = StringPrintf("%s/art-cache", data_root);
-
- if (!OS::DirectoryExists(art_cache.c_str())) {
- if (StringPiece(art_cache).starts_with("/tmp/")) {
- int result = mkdir(art_cache.c_str(), 0700);
- if (result != 0) {
- LOG(FATAL) << "Failed to create art-cache directory " << art_cache;
- return NULL;
- }
- } else {
- LOG(FATAL) << "Failed to find art-cache directory " << art_cache;
- return NULL;
- }
- }
-
- std::string cache_path_tmp = StringPrintf("%s/%s", art_cache.c_str(), cache_file.c_str());
+ std::string art_cache = GetArtCacheOrDie();
+ std::string cache_path_tmp = art_cache + "/" + cache_file;
// Example cache_path_tmp = /data/art-cache/parent@dir@foo.jar@classes.dex
UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(filename));
diff --git a/src/utils.cc b/src/utils.cc
index 3017807..bc51c2a 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -4,6 +4,7 @@
#include "utils.h"
#include <pthread.h>
+#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
@@ -482,6 +483,37 @@
#endif
}
+std::string GetArtCacheOrDie() {
+ const char* data_root = getenv("ANDROID_DATA");
+ if (data_root == NULL) {
+ if (OS::DirectoryExists("/data")) {
+ data_root = "/data";
+ } else {
+ data_root = "/tmp";
+ }
+ }
+ if (!OS::DirectoryExists(data_root)) {
+ LOG(FATAL) << "Failed to find ANDROID_DATA directory " << data_root;
+ return "";
+ }
+
+ std::string art_cache = StringPrintf("%s/art-cache", data_root);
+
+ if (!OS::DirectoryExists(art_cache.c_str())) {
+ if (StringPiece(art_cache).starts_with("/tmp/")) {
+ int result = mkdir(art_cache.c_str(), 0700);
+ if (result != 0) {
+ LOG(FATAL) << "Failed to create art-cache directory " << art_cache;
+ return "";
+ }
+ } else {
+ LOG(FATAL) << "Failed to find art-cache directory " << art_cache;
+ return "";
+ }
+ }
+ return art_cache;
+}
+
} // namespace art
// Neither bionic nor glibc exposes gettid(2).
diff --git a/src/utils.h b/src/utils.h
index 228925d..7778918 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -212,6 +212,9 @@
// implementation-defined limit.
void SetThreadName(const char* name);
+// Returns the art-cache location or dies trying
+std::string GetArtCacheOrDie();
+
} // namespace art
#endif // ART_SRC_UTILS_H_