Add support for oat files in /data/art-cache
Also implement Zygote_nativeForkAndSpecialize
Change-Id: I7dfb257b2897279a4cdac4b1ca194c1ac84eb047
diff --git a/Android.mk b/Android.mk
index 282dd3b..b909c98 100644
--- a/Android.mk
+++ b/Android.mk
@@ -122,29 +122,37 @@
########################################################################
# oat_process test targets
+# $(1): jar or apk name
+define art-cache-oat
+ $(ART_CACHE_OUT)/$(subst /,@,$(patsubst %.apk,%.oat,$(patsubst %.jar,%.oat,$(1))))
+endef
+
+ART_CACHE_OATS :=
# $(1): name
-define build-art-framework-oat
- $(call build-art-oat,$(1),$(TARGET_BOOT_OAT),$(TARGET_BOOT_DEX))
+define build-art-cache-oat
+ $(call build-art-oat,$(PRODUCT_OUT)/$(1),$(call art-cache-oat,$(1)),$(TARGET_BOOT_IMG))
+ ART_CACHE_OATS += $(call art-cache-oat,$(1))
endef
.PHONY: test-art-target-oat-process
test-art-target-oat-process: test-art-target-oat-process-am # test-art-target-oat-process-Calculator
-$(eval $(call build-art-framework-oat,$(TARGET_OUT_JAVA_LIBRARIES)/am.jar))
+$(eval $(call build-art-cache-oat,system/framework/am.jar))
+$(eval $(call build-art-cache-oat,system/app/Calculator.apk))
+$(eval $(call build-art-cache-oat,system/app/SettingsProvider.apk))
+$(eval $(call build-art-cache-oat,system/app/SystemUI.apk))
.PHONY: test-art-target-oat-process-am
-test-art-target-oat-process-am: $(TARGET_OUT_JAVA_LIBRARIES)/am.oat test-art-target-sync
+test-art-target-oat-process-am: $(call art-cache-oat,system/framework/am.jar) test-art-target-sync
adb remount
adb sync
adb shell sh -c "export CLASSPATH=/system/framework/am.jar && oat_processd /system/bin/app_process -Ximage:$(ART_CACHE_DIR)/boot.art /system/bin com.android.commands.am.Am start http://android.com && touch $(ART_TEST_DIR)/test-art-target-process-am"
$(hide) (adb pull $(ART_TEST_DIR)/test-art-target-process-am /tmp/ && echo test-art-target-process-am PASSED) || echo test-art-target-process-am FAILED
$(hide) rm /tmp/test-art-target-process-am
-$(eval $(call build-art-framework-oat,$(TARGET_OUT_APPS)/Calculator.apk))
-
.PHONY: test-art-target-oat-process-Calculator
# Note that using this instead of "adb shell am start" make sure that the /data/art-cache is up-to-date
-test-art-target-oat-process-Calculator: $(TARGET_OUT_APPS)/Calculator.oat $(TARGET_OUT_JAVA_LIBRARIES)/am.oat test-art-target-sync
+test-art-target-oat-process-Calculator: $(call art-cache-oat,system/app/Calculator.oat) $(call art-cache-oat,system/framework/am.jar) test-art-target-sync
mkdir -p $(ART_CACHE_OUT)
unzip $(TARGET_OUT_APPS)/Calculator.apk classes.dex -d $(TARGET_OUT_DATA)/art-cache
mv $(TARGET_OUT_DATA)/art-cache/classes.dex $(ART_CACHE_OUT)/system@app@Calculator.apk@classes.dex.`unzip -lv $(TARGET_OUT_APPS)/Calculator.apk classes.dex | grep classes.dex | sed -E 's/.* ([0-9a-f]+) classes.dex/\1/'` # note this is extracting the crc32 that is needed as the file extension
@@ -175,14 +183,14 @@
# zygote-art-target-sync will just push a new art in place of dvm
.PHONY: zygote-artd-target-sync
-zygote-artd-target-sync: $(ART_TARGET_DEPENDENCIES)
+zygote-artd-target-sync: $(ART_TARGET_DEPENDENCIES) $(TARGET_BOOT_OAT) $(ART_CACHE_OATS)
cp $(TARGET_OUT_SHARED_LIBRARIES)/libartd.so $(TARGET_OUT_SHARED_LIBRARIES)/libdvm.so
cp $(TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)/libartd.so $(TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)/libdvm.so
adb remount
adb sync
.PHONY: zygote-artd
-zygote-artd: $(TARGET_BOOT_OAT) zygote-artd-target-sync
+zygote-artd: zygote-artd-target-sync
sed 's/--start-system-server/--start-system-server --no-preload/' < system/core/rootdir/init.rc > $(ANDROID_PRODUCT_OUT)/root/init.rc
rm -f $(ANDROID_PRODUCT_OUT)/boot.img
unset ONE_SHOT_MAKEFILE && $(MAKE) showcommands bootimage
diff --git a/build/Android.oattest.mk b/build/Android.oattest.mk
index 8125df1..27a4646 100644
--- a/build/Android.oattest.mk
+++ b/build/Android.oattest.mk
@@ -35,13 +35,13 @@
########################################################################
# $(1): input jar or apk filename
-# $(2): boot oat
-# $(3): boot dex files
+# $(2): output oat filename
+# $(3): boot image
define build-art-oat
# TODO: change DEX2OATD (and perhaps $(2) boot oat) to order-only prerequisite when output is stable
-$(patsubst %.apk,%.oat,$(patsubst %.jar,%.oat,$(1))): $(1) $(2) $(DEX2OAT)
+$(2): $(1) $(3) $(DEX2OAT)
@echo "target dex2oat: $$@ ($$<)"
- $(hide) $(DEX2OAT) -Xms16m -Xmx16m --boot-image=$(patsubst %.oat,%.art,$(2)) $(addprefix --dex-file=,$$<) --oat=$$@ --host-prefix=$(PRODUCT_OUT)
+ $(hide) $(DEX2OAT) -Xms16m -Xmx16m --boot-image=$(3) $(addprefix --dex-file=,$$<) --oat=$$@ --host-prefix=$(PRODUCT_OUT)
endef
########################################################################
@@ -49,7 +49,7 @@
# $(1): directory
define build-art-test-oat
- $(call build-art-oat,$(ART_TEST_OUT)/art-test-dex-$(1).jar,$(TARGET_CORE_OAT),$(TARGET_CORE_DEX))
+ $(call build-art-oat,$(ART_TEST_OUT)/art-test-dex-$(1).jar,$(ART_TEST_OUT)/art-test-dex-$(1).oat,$(TARGET_CORE_IMG))
ART_TEST_OAT_FILES += $(ART_TEST_OUT)/art-test-dex-$(1).oat
endef
$(foreach dir,$(TEST_DEX_DIRECTORIES), $(eval $(call build-art-test-oat,$(dir))))
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_