user build support for art (2 of 3)
Change-Id: I4696fee58e43db48540e2442c4235fc4bb02d9e3
diff --git a/Android.mk b/Android.mk
index 9f425c8..b648d54 100644
--- a/Android.mk
+++ b/Android.mk
@@ -129,7 +129,7 @@
ART_CACHE_OATS :=
# $(1): name
define build-art-cache-oat
- $(call build-art-oat,$(PRODUCT_OUT)/$(1),$(call art-cache-oat,$(1)),$(TARGET_BOOT_IMG))
+ $(call build-art-oat,$(PRODUCT_OUT)/$(1),/$(1),$(call art-cache-oat,$(1)),$(TARGET_BOOT_IMG))
ART_CACHE_OATS += $(call art-cache-oat,$(1))
endef
@@ -144,7 +144,7 @@
$(eval $(call build-art-cache-oat,$(subst $(PRODUCT_OUT)/,,$(file)))))
.PHONY: oat-target-sync
-oat-target-sync: $(ART_TARGET_DEPENDENCIES) $(TARGET_BOOT_OAT) $(ART_CACHE_OATS)
+oat-target-sync: $(ART_TARGET_DEPENDENCIES) $(TARGET_BOOT_OAT_OUT) $(ART_CACHE_OATS)
adb remount
adb sync
@@ -155,17 +155,17 @@
dump-oat: dump-oat-core dump-oat-boot dump-oat-Calculator
.PHONY: dump-oat-core
-dump-oat-core: $(TARGET_CORE_OAT) $(OATDUMP)
- $(OATDUMP) --image=$(TARGET_CORE_IMG) --host-prefix=$(PRODUCT_OUT) --output=/tmp/core.oatdump.txt
+dump-oat-core: $(TARGET_CORE_OAT_OUT) $(OATDUMP)
+ $(OATDUMP) --image=$(TARGET_CORE_IMG_OUT) --host-prefix=$(PRODUCT_OUT) --output=/tmp/core.oatdump.txt
@echo Output in /tmp/core.oatdump.txt
.PHONY: dump-oat-boot
-dump-oat-boot: $(TARGET_BOOT_OAT) $(OATDUMP)
- $(OATDUMP) --image=$(TARGET_BOOT_IMG) --host-prefix=$(PRODUCT_OUT) --output=/tmp/boot.oatdump.txt
+dump-oat-boot: $(TARGET_BOOT_OAT_OUT) $(OATDUMP)
+ $(OATDUMP) --image=$(TARGET_BOOT_IMG_OUT) --host-prefix=$(PRODUCT_OUT) --output=/tmp/boot.oatdump.txt
@echo Output in /tmp/boot.oatdump.txt
.PHONY: dump-oat-Calculator
-dump-oat-Calculator: $(call art-cache-oat,system/app/Calculator.apk) $(TARGET_BOOT_OAT) $(OATDUMP)
+dump-oat-Calculator: $(call art-cache-oat,system/app/Calculator.apk) $(TARGET_BOOT_OAT_OUT) $(OATDUMP)
$(OATDUMP) --oat-file=$< --boot-image=$(TARGET_BOOT_IMG) --host-prefix=$(PRODUCT_OUT) --output=/tmp/Calculator.oatdump.txt
@echo Output in /tmp/Calculator.oatdump.txt
@@ -176,14 +176,26 @@
.PHONY: clean-oat
clean-oat:
+ rm -f $(ART_NATIVETEST_OUT)/*.oat
+ rm -f $(ART_NATIVETEST_OUT)/*.art
rm -f $(ART_TEST_OUT)/*.oat
rm -f $(ART_TEST_OUT)/*.art
rm -f $(ART_CACHE_OUT)/*.oat
rm -f $(ART_CACHE_OUT)/*.art
+ rm -f $(HOST_OUT_JAVA_LIBRARIES)/*.oat
+ rm -f $(HOST_OUT_JAVA_LIBRARIES)/*.art
+ rm -f $(TARGET_OUT_JAVA_LIBRARIES)/*.oat
+ rm -f $(TARGET_OUT_JAVA_LIBRARIES)/*.art
+ rm -f $(TARGET_OUT_APPS)/*.oat
+ adb shell rm $(ART_NATIVETEST_DIR)/*.oat
+ adb shell rm $(ART_NATIVETEST_DIR)/*.art
adb shell rm $(ART_TEST_DIR)/*.oat
adb shell rm $(ART_TEST_DIR)/*.art
adb shell rm $(ART_CACHE_DIR)/*.oat
adb shell rm $(ART_CACHE_DIR)/*.art
+ adb shell rm $(DEXPREOPT_BOOT_JAR_DIR)/*.oat
+ adb shell rm $(DEXPREOPT_BOOT_JAR_DIR)/*.art
+ adb shell rm system/app/*.oat
########################################################################
# cpplint target
diff --git a/build/Android.common.mk b/build/Android.common.mk
index c7bfbe5..853c4d2 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -31,6 +31,11 @@
ART_CACHE_OUT := $(TARGET_OUT_DATA)/art-cache
# $(1): pathname
+define art-cache-dir
+$(ART_CACHE_DIR)/$(subst /,@,$(1))
+endef
+
+# $(1): pathname
define art-cache-out
$(ART_CACHE_OUT)/$(subst /,@,$(1))
endef
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index 4f1bb2d..4f8ff2b 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -39,50 +39,59 @@
HOST_CORE_JARS := core-hostdex
TARGET_CORE_JARS := core
-HOST_CORE_DEX := $(foreach jar,$(HOST_CORE_JARS), $(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
-TARGET_CORE_DEX := $(foreach jar,$(TARGET_CORE_JARS),$(TARGET_OUT_JAVA_LIBRARIES)/$(jar).jar)
+HOST_CORE_DEX_LOCATIONS := $(foreach jar,$(HOST_CORE_JARS), $(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
+TARGET_CORE_DEX_LOCATIONS := $(foreach jar,$(TARGET_CORE_JARS),/$(DEXPREOPT_BOOT_JAR_DIR)/$(jar).jar)
+
+HOST_CORE_DEX_FILES := $(foreach jar,$(HOST_CORE_JARS), $(call intermediates-dir-for,JAVA_LIBRARIES,$(jar),t,COMMON)/javalib.jar)
+TARGET_CORE_DEX_FILES := $(foreach jar,$(TARGET_CORE_JARS),$(call intermediates-dir-for,JAVA_LIBRARIES,$(jar), ,COMMON)/javalib.jar)
HOST_CORE_OAT := $(HOST_OUT_JAVA_LIBRARIES)/core.oat
-TARGET_CORE_OAT := $(ART_TEST_OUT)/core.oat
+TARGET_CORE_OAT := $(ART_TEST_DIR)/core.oat
-HOST_CORE_IMG := $(HOST_OUT_JAVA_LIBRARIES)/core.art
-TARGET_CORE_IMG := $(ART_TEST_OUT)/core.art
+HOST_CORE_OAT_OUT := $(HOST_OUT_JAVA_LIBRARIES)/core.oat
+TARGET_CORE_OAT_OUT := $(ART_TEST_OUT)/core.oat
-$(HOST_CORE_OAT): $(HOST_CORE_DEX) $(DEX2OAT_DEPENDENCY)
+HOST_CORE_IMG_OUT := $(HOST_OUT_JAVA_LIBRARIES)/core.art
+TARGET_CORE_IMG_OUT := $(ART_TEST_OUT)/core.art
+
+$(HOST_CORE_OAT_OUT): $(HOST_CORE_DEX_FILES) $(DEX2OAT_DEPENDENCY)
@echo "host dex2oat: $@ ($?)"
@mkdir -p $(dir $@)
- $(hide) $(DEX2OAT) --runtime-arg -Xms16m --runtime-arg -Xmx16m --image-classes=$(PRELOADED_CLASSES) $(addprefix --dex-file=,$(filter-out $(DEX2OAT),$^)) --oat-file=$@ --image=$(HOST_CORE_IMG) --base=$(IMG_HOST_BASE_ADDRESS)
+ $(hide) $(DEX2OAT) --runtime-arg -Xms16m --runtime-arg -Xmx16m --image-classes=$(PRELOADED_CLASSES) $(addprefix --dex-file=,$(HOST_CORE_DEX_FILES)) $(addprefix --dex-location=,$(HOST_CORE_DEX_LOCATIONS)) --oat-file=$@ --oat-location=$(HOST_CORE_OAT) --image=$(HOST_CORE_IMG_OUT) --base=$(IMG_HOST_BASE_ADDRESS)
-$(TARGET_CORE_OAT): $(TARGET_CORE_DEX) $(DEX2OAT_DEPENDENCY)
+$(TARGET_CORE_OAT_OUT): $(TARGET_CORE_DEX) $(DEX2OAT_DEPENDENCY)
@echo "target dex2oat: $@ ($?)"
@mkdir -p $(dir $@)
- $(hide) $(DEX2OAT) --runtime-arg -Xms16m --runtime-arg -Xmx16m --image-classes=$(PRELOADED_CLASSES) $(addprefix --dex-file=,$(filter-out $(DEX2OAT),$^)) --oat-file=$@ --image=$(TARGET_CORE_IMG) --base=$(IMG_TARGET_BASE_ADDRESS) --host-prefix=$(PRODUCT_OUT)
+ $(hide) $(DEX2OAT) --runtime-arg -Xms16m --runtime-arg -Xmx16m --image-classes=$(PRELOADED_CLASSES) $(addprefix --dex-file=,$(TARGET_CORE_DEX_FILES)) $(addprefix --dex-location=,$(TARGET_CORE_DEX_LOCATIONS)) --oat-file=$@ --oat-location=$(TARGET_CORE_OAT) --image=$(TARGET_CORE_IMG_OUT) --base=$(IMG_TARGET_BASE_ADDRESS) --host-prefix=$(PRODUCT_OUT)
-$(HOST_CORE_IMG): $(HOST_CORE_OAT)
+$(HOST_CORE_IMG_OUT): $(HOST_CORE_OAT_OUT)
-$(TARGET_CORE_IMG): $(TARGET_CORE_OAT)
+$(TARGET_CORE_IMG_OUT): $(TARGET_CORE_OAT_OUT)
########################################################################
# The full system boot classpath
TARGET_BOOT_JARS := $(subst :, ,$(DEXPREOPT_BOOT_JARS))
-TARGET_BOOT_DEX := $(foreach jar,$(TARGET_BOOT_JARS),$(TARGET_OUT_JAVA_LIBRARIES)/$(jar).jar)
+TARGET_BOOT_DEX_LOCATIONS := $(foreach jar,$(TARGET_BOOT_JARS),/$(DEXPREOPT_BOOT_JAR_DIR)/$(jar).jar)
+TARGET_BOOT_DEX_FILES := $(foreach jar,$(TARGET_BOOT_JARS),$(call intermediates-dir-for,JAVA_LIBRARIES,$(jar),,COMMON)/javalib.jar)
ifeq ($(TARGET_PRODUCT),$(filter $(TARGET_PRODUCT),trygon))
- TARGET_BOOT_OAT := $(call art-cache-out,$(DEXPREOPT_BOOT_JAR_DIR)/boot.oat)
- TARGET_BOOT_IMG := $(call art-cache-out,$(DEXPREOPT_BOOT_JAR_DIR)/boot.art)
+ TARGET_BOOT_OAT := $(call art-cache-dir,$(DEXPREOPT_BOOT_JAR_DIR)/boot.oat)
+ TARGET_BOOT_OAT_OUT := $(call art-cache-out,$(DEXPREOPT_BOOT_JAR_DIR)/boot.oat)
+ TARGET_BOOT_IMG_OUT := $(call art-cache-out,$(DEXPREOPT_BOOT_JAR_DIR)/boot.art)
else
- TARGET_BOOT_OAT := $(TARGET_OUT_JAVA_LIBRARIES)/boot.oat
- TARGET_BOOT_IMG := $(TARGET_OUT_JAVA_LIBRARIES)/boot.art
+ TARGET_BOOT_OAT := /$(DEXPREOPT_BOOT_JAR_DIR)/boot.oat
+ TARGET_BOOT_OAT_OUT := $(TARGET_OUT_JAVA_LIBRARIES)/boot.oat
+ TARGET_BOOT_IMG_OUT := $(TARGET_OUT_JAVA_LIBRARIES)/boot.art
endif
-$(TARGET_BOOT_OAT): $(TARGET_BOOT_DEX) $(DEX2OAT_DEPENDENCY)
+$(TARGET_BOOT_OAT_OUT): $(TARGET_BOOT_DEX_FILES) $(DEX2OAT_DEPENDENCY)
@echo "target dex2oat: $@ ($?)"
@mkdir -p $(dir $@)
- $(hide) $(DEX2OAT) --runtime-arg -Xms256m --runtime-arg -Xmx256m --image-classes=$(PRELOADED_CLASSES) $(addprefix --dex-file=,$(filter-out $(DEX2OAT),$^)) --oat-file=$@ --image=$(TARGET_BOOT_IMG) --base=$(IMG_TARGET_BASE_ADDRESS) --host-prefix=$(PRODUCT_OUT)
+ $(hide) $(DEX2OAT) --runtime-arg -Xms256m --runtime-arg -Xmx256m --image-classes=$(PRELOADED_CLASSES) $(addprefix --dex-file=,$(TARGET_BOOT_DEX_FILES)) $(addprefix --dex-location=,$(TARGET_BOOT_DEX_LOCATIONS)) --oat-file=$@ --oat-location=$(TARGET_BOOT_OAT) --image=$(TARGET_BOOT_IMG_OUT) --base=$(IMG_TARGET_BASE_ADDRESS) --host-prefix=$(PRODUCT_OUT)
-$(TARGET_BOOT_IMG): $(TARGET_BOOT_OAT)
+$(TARGET_BOOT_IMG_OUT): $(TARGET_BOOT_OAT_OUT)
include $(CLEAR_VARS)
LOCAL_MODULE := boot.art
LOCAL_MODULE_TAGS := optional
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_BOOT_IMG)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_BOOT_IMG_OUT)
include $(BUILD_PHONY_PACKAGE)
diff --git a/build/Android.oattest.mk b/build/Android.oattest.mk
index 49700f2..7e630c7 100644
--- a/build/Android.oattest.mk
+++ b/build/Android.oattest.mk
@@ -38,13 +38,14 @@
########################################################################
# $(1): input jar or apk filename
-# $(2): output oat filename
-# $(3): boot image
+# $(2): input jar or apk target location
+# $(3): output oat filename
+# $(4): boot image
define build-art-oat
-$(2): $(1) $(3) $(DEX2OAT_DEPENDENCY)
+$(3): $(1) $(4) $(DEX2OAT_DEPENDENCY)
@echo "target dex2oat: $$@ ($$?)"
@mkdir -p $$(dir $$@)
- $(hide) $(DEX2OAT) --runtime-arg -Xms64m --runtime-arg -Xmx64m --boot-image=$(3) $(addprefix --dex-file=,$$<) --oat-file=$$@ --host-prefix=$(PRODUCT_OUT)
+ $(hide) $(DEX2OAT) --runtime-arg -Xms64m --runtime-arg -Xmx64m --boot-image=$(4) --dex-file=$(1) --dex-location=$(2) --oat-file=$$@ --host-prefix=$(PRODUCT_OUT)
endef
########################################################################
@@ -52,10 +53,12 @@
# $(1): directory
define build-art-test-oat
- $(call build-art-oat,$(ART_TEST_OUT)/oat-test-dex-$(1).jar,$(ART_TEST_OUT)/oat-test-dex-$(1).jar.oat,$(TARGET_CORE_IMG))
+ $(call build-art-oat,$(call intermediates-dir-for,JAVA_LIBRARIES,oat-test-dex-$(dir),,COMMON)/javalib.jar,$(ART_TEST_DIR)/oat-test-dex-$(1).jar,$(ART_TEST_OUT)/oat-test-dex-$(1).jar.oat,$(TARGET_CORE_IMG_OUT))
ART_TEST_OAT_FILES += $(ART_TEST_OUT)/oat-test-dex-$(1).jar.oat
endef
-$(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval $(call build-art-test-oat,$(dir))))
+ifneq (user,$(TARGET_BUILD_VARIANT))
+ $(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval $(call build-art-test-oat,$(dir))))
+endif
########################################################################
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 952bacf..d8bf664 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -209,14 +209,15 @@
"[Ljava/lang/StackTraceElement;",
};
-ClassLinker* ClassLinker::Create(const std::string& boot_class_path, InternTable* intern_table) {
+ClassLinker* ClassLinker::CreateFromCompiler(const std::vector<const DexFile*>& boot_class_path,
+ InternTable* intern_table) {
CHECK_NE(boot_class_path.size(), 0U);
UniquePtr<ClassLinker> class_linker(new ClassLinker(intern_table));
- class_linker->Init(boot_class_path);
+ class_linker->InitFromCompiler(boot_class_path);
return class_linker.release();
}
-ClassLinker* ClassLinker::Create(InternTable* intern_table) {
+ClassLinker* ClassLinker::CreateFromImage(InternTable* intern_table) {
UniquePtr<ClassLinker> class_linker(new ClassLinker(intern_table));
class_linker->InitFromImage();
return class_linker.release();
@@ -232,22 +233,9 @@
CHECK_EQ(arraysize(class_roots_descriptors_), size_t(kClassRootsMax));
}
-void CreateClassPath(const std::string& class_path,
- std::vector<const DexFile*>& class_path_vector) {
- std::vector<std::string> parsed;
- Split(class_path, ':', parsed);
- for (size_t i = 0; i < parsed.size(); ++i) {
- const DexFile* dex_file = DexFile::Open(parsed[i], Runtime::Current()->GetHostPrefix());
- if (dex_file == NULL) {
- LOG(WARNING) << "Failed to open dex file " << parsed[i];
- } else {
- class_path_vector.push_back(dex_file);
- }
- }
-}
-
-void ClassLinker::Init(const std::string& boot_class_path) {
- VLOG(startup) << "ClassLinker::InitFrom entering boot_class_path=" << boot_class_path;
+void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class_path) {
+ VLOG(startup) << "ClassLinker::Init";
+ CHECK(Runtime::Current()->IsCompiler());
CHECK(!init_done_);
@@ -321,11 +309,9 @@
// setup boot_class_path_ and register class_path now that we can
// use AllocObjectArray to create DexCache instances
- std::vector<const DexFile*> boot_class_path_vector;
- CreateClassPath(boot_class_path, boot_class_path_vector);
- CHECK_NE(0U, boot_class_path_vector.size());
- for (size_t i = 0; i != boot_class_path_vector.size(); ++i) {
- const DexFile* dex_file = boot_class_path_vector[i];
+ CHECK_NE(0U, boot_class_path.size());
+ for (size_t i = 0; i != boot_class_path.size(); ++i) {
+ const DexFile* dex_file = boot_class_path[i];
CHECK(dex_file != NULL);
AppendToBootClassPath(*dex_file);
}
@@ -481,7 +467,7 @@
FinishInit();
- VLOG(startup) << "ClassLinker::InitFrom exiting";
+ VLOG(startup) << "ClassLinker::InitFromCompiler exiting";
}
void ClassLinker::FinishInit() {
@@ -575,7 +561,7 @@
#endif
const char* dex2oat = dex2oat_string.c_str();
- const char* class_path = Runtime::Current()->GetClassPath().c_str();
+ const char* class_path = Runtime::Current()->GetClassPathString().c_str();
std::string boot_image_option_string("--boot-image=");
boot_image_option_string += Heap::GetSpaces()[0]->AsImageSpace()->GetImageFilename();
@@ -589,9 +575,9 @@
StringAppendF(&oat_fd_option_string, "%d", oat_fd);
const char* oat_fd_option = oat_fd_option_string.c_str();
- std::string oat_name_option_string("--oat-name=");
- oat_name_option_string += oat_cache_filename;
- const char* oat_name_option = oat_name_option_string.c_str();
+ std::string oat_location_option_string("--oat-location=");
+ oat_location_option_string += oat_cache_filename;
+ const char* oat_location_option = oat_location_option_string.c_str();
// fork and exec dex2oat
pid_t pid = fork();
@@ -609,7 +595,7 @@
<< " " << boot_image_option
<< " " << dex_file_option
<< " " << oat_fd_option
- << " " << oat_name_option;
+ << " " << oat_location_option;
execl(dex2oat, dex2oat,
"--runtime-arg", "-Xms64m",
@@ -619,7 +605,7 @@
boot_image_option,
dex_file_option,
oat_fd_option,
- oat_name_option,
+ oat_location_option,
NULL);
PLOG(FATAL) << "execl(" << dex2oat << ") failed";
@@ -660,7 +646,7 @@
std::string oat_filename;
oat_filename += runtime->GetHostPrefix();
oat_filename += oat_location->ToModifiedUtf8();
- OatFile* oat_file = OatFile::Open(oat_filename, "", image_header.GetOatBegin());
+ OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, image_header.GetOatBegin());
VLOG(startup) << "ClassLinker::OpenOat entering oat_filename=" << oat_filename;
if (oat_file == NULL) {
LOG(ERROR) << "Failed to open oat file " << oat_filename << " referenced from image.";
@@ -680,18 +666,15 @@
}
const OatFile* ClassLinker::FindOpenedOatFileForDexFile(const DexFile& dex_file) {
- return FindOpenedOatFileFromDexLocation(dex_file.GetLocation(),
- dex_file.GetLocationChecksum());
+ return FindOpenedOatFileFromDexLocation(dex_file.GetLocation());
}
-const OatFile* ClassLinker::FindOpenedOatFileFromDexLocation(const std::string& dex_location,
- uint32_t dex_location_checksum) {
+const OatFile* ClassLinker::FindOpenedOatFileFromDexLocation(const std::string& dex_location) {
for (size_t i = 0; i < oat_files_.size(); i++) {
const OatFile* oat_file = oat_files_[i];
DCHECK(oat_file != NULL);
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location, false);
- if (oat_dex_file != NULL
- && oat_dex_file->GetDexFileLocationChecksum() == dex_location_checksum) {
+ if (oat_dex_file != NULL) {
return oat_file;
}
}
@@ -747,7 +730,7 @@
static const DexFile* FindDexFileInOatLocation(const std::string& dex_location,
uint32_t dex_location_checksum,
const std::string& oat_location) {
- UniquePtr<OatFile> oat_file(OatFile::Open(oat_location, "", NULL));
+ UniquePtr<OatFile> oat_file(OatFile::Open(oat_location, oat_location, NULL));
if (oat_file.get() == NULL) {
return NULL;
}
@@ -811,22 +794,31 @@
const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::string& dex_location) {
MutexLock mu(dex_lock_);
- uint32_t dex_location_checksum;
- if (!DexFile::GetChecksum(dex_location, dex_location_checksum)) {
- LOG(WARNING) << "Failed to compute checksum: " << dex_location;
- return NULL;
- }
-
- const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location, dex_location_checksum);
+ const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location);
if (open_oat_file != NULL) {
return open_oat_file->GetOatDexFile(dex_location)->OpenDexFile();
}
- // Look for an existing file first next to dex and in art-cache
+ // Look for an existing file next to dex, assuming its up-to-date if found
std::string oat_filename(OatFile::DexFilenameToOatFilename(dex_location));
- const OatFile* oat_file(FindOatFileFromOatLocation(oat_filename));
+ const OatFile* oat_file = FindOatFileFromOatLocation(oat_filename);
if (oat_file != NULL) {
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location);
+ CHECK(oat_dex_file != NULL) << oat_filename << " " << dex_location;
+ return oat_dex_file->OpenDexFile();
+ }
+ // Look for an existing file in the art-cache, validating the result if found
+ // not found in /foo/bar/baz.oat? try /data/art-cache/foo@bar@baz.oat
+ std::string cache_location(GetArtCacheFilenameOrDie(oat_filename));
+ oat_file = FindOatFileFromOatLocation(cache_location);
+ if (oat_file != NULL) {
+ uint32_t dex_location_checksum;
+ if (!DexFile::GetChecksum(dex_location, dex_location_checksum)) {
+ LOG(WARNING) << "Failed to compute checksum: " << dex_location;
+ return NULL;
+ }
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location);
+ CHECK(oat_dex_file != NULL) << oat_filename << " " << dex_location;
if (dex_location_checksum == oat_dex_file->GetDexFileLocationChecksum()) {
return oat_file->GetOatDexFile(dex_location)->OpenDexFile();
}
@@ -838,6 +830,8 @@
PLOG(FATAL) << "Couldn't remove obsolete .oat file " << oat_file->GetLocation();
}
}
+ LOG(INFO) << "Failed to open oat file from " << oat_filename << " or " << cache_location << ".";
+
// Try to generate oat file if it wasn't found or was obsolete.
std::string oat_cache_filename(GetArtCacheFilenameOrDie(oat_filename));
return FindOrCreateOatFileForDexLocation(dex_location, oat_cache_filename);
@@ -861,26 +855,10 @@
return oat_file;
}
- oat_file = OatFile::Open(oat_location, "", NULL);
+ oat_file = OatFile::Open(oat_location, oat_location, NULL);
if (oat_file == NULL) {
- if (oat_location.empty() || oat_location[0] != '/') {
- LOG(ERROR) << "Failed to open oat file from " << oat_location;
- return NULL;
- }
-
- // not found in /foo/bar/baz.oat? try /data/art-cache/foo@bar@baz.oat
- std::string cache_location(GetArtCacheFilenameOrDie(oat_location));
- oat_file = FindOpenedOatFileFromOatLocation(cache_location);
- if (oat_file != NULL) {
- return oat_file;
- }
- oat_file = OatFile::Open(cache_location, "", NULL);
- if (oat_file == NULL) {
- LOG(INFO) << "Failed to open oat file from " << oat_location << " or " << cache_location << ".";
- return NULL;
- }
+ return NULL;
}
-
CHECK(oat_file != NULL) << oat_location;
RegisterOatFileLocked(*oat_file);
return oat_file;
diff --git a/src/class_linker.h b/src/class_linker.h
index f6b7c15..d90ac1d 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -44,10 +44,11 @@
class ClassLinker {
public:
// Creates the class linker by boot strapping from dex files.
- static ClassLinker* Create(const std::string& boot_class_path, InternTable* intern_table);
+ static ClassLinker* CreateFromCompiler(const std::vector<const DexFile*>& boot_class_path,
+ InternTable* intern_table);
- // Creates the class linker from one or more images.
- static ClassLinker* Create(InternTable* intern_table);
+ // Creates the class linker from an image.
+ static ClassLinker* CreateFromImage(InternTable* intern_table);
~ClassLinker();
@@ -291,7 +292,7 @@
explicit ClassLinker(InternTable*);
// Initialize class linker by bootstraping from dex files
- void Init(const std::string& boot_class_path);
+ void InitFromCompiler(const std::vector<const DexFile*>& boot_class_path);
// Initialize class linker from one or more images.
void InitFromImage();
@@ -397,8 +398,7 @@
}
const OatFile* FindOpenedOatFileForDexFile(const DexFile& dex_file);
- const OatFile* FindOpenedOatFileFromDexLocation(const std::string& dex_location,
- uint32_t dex_location_checksum);
+ const OatFile* FindOpenedOatFileFromDexLocation(const std::string& dex_location);
const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location);
Method* CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class);
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 9f63c5e..7741d4d 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -739,7 +739,7 @@
}
TEST_F(ClassLinkerTest, LibCore) {
- AssertDexFile(java_lang_dex_file_.get(), NULL);
+ AssertDexFile(java_lang_dex_file_, NULL);
}
// The first reference array element must be a multiple of 8 bytes from the
diff --git a/src/common_test.h b/src/common_test.h
index 4457cec..f7b9fec 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -125,7 +125,7 @@
file.reset();
// read dex file
- const DexFile* dex_file = DexFile::Open(location, "");
+ const DexFile* dex_file = DexFile::Open(location, location);
CHECK(dex_file != NULL);
return dex_file;
}
@@ -137,7 +137,7 @@
filename_ += "/TmpFile-XXXXXX";
fd_ = mkstemp(&filename_[0]);
CHECK_NE(-1, fd_);
- file_.reset(OS::FileFromFd(GetFilename(), fd_));
+ file_.reset(OS::FileFromFd(GetFilename().c_str(), fd_));
}
~ScratchFile() {
@@ -147,8 +147,8 @@
CHECK_EQ(0, close_result);
}
- const char* GetFilename() const {
- return filename_.c_str();
+ const std::string& GetFilename() const {
+ return filename_;
}
File* GetFile() const {
@@ -301,18 +301,15 @@
int mkdir_result = mkdir(art_cache_.c_str(), 0700);
ASSERT_EQ(mkdir_result, 0);
- java_lang_dex_file_.reset(DexFile::Open(GetLibCoreDexFileName(), ""));
-
- std::string boot_class_path;
- boot_class_path += "-Xbootclasspath:";
- boot_class_path += GetLibCoreDexFileName();
+ java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
+ boot_class_path_.push_back(java_lang_dex_file_);
std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kInitialSize / MB));
std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kMaximumSize / MB));
Runtime::Options options;
options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
- options.push_back(std::make_pair(boot_class_path.c_str(), reinterpret_cast<void*>(NULL)));
+ options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
@@ -409,7 +406,7 @@
filename += "/data/nativetest/art/art-test-dex-";
filename += name;
filename += ".jar";
- const DexFile* dex_file = DexFile::Open(filename, "");
+ const DexFile* dex_file = DexFile::Open(filename, filename);
CHECK(dex_file != NULL) << "Failed to open " << filename;
opened_dex_files_.push_back(dex_file);
return dex_file;
@@ -476,7 +473,7 @@
bool is_host_;
std::string android_data_;
std::string art_cache_;
- UniquePtr<const DexFile> java_lang_dex_file_;
+ const DexFile* java_lang_dex_file_; // owned by runtime_
std::vector<const DexFile*> boot_class_path_;
UniquePtr<Runtime> runtime_;
// Owned by the runtime
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 76a39a4..a7c2691 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -88,7 +88,7 @@
CompileAll(NULL);
// All libcore references should resolve
- const DexFile* dex = java_lang_dex_file_.get();
+ const DexFile* dex = java_lang_dex_file_;
DexCache* dex_cache = class_linker_->FindDexCache(*dex);
EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings());
for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
@@ -139,6 +139,7 @@
}
TEST_F(CompilerTest, AbstractMethodErrorStub) {
+ CompileVirtualMethod(NULL, "java.lang.Class", "isFinalizable", "()Z");
CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
SirtRef<ClassLoader> class_loader(LoadDex("AbstractMethod"));
diff --git a/src/dalvik_system_DexFile.cc b/src/dalvik_system_DexFile.cc
index 713639f..f6568a7 100644
--- a/src/dalvik_system_DexFile.cc
+++ b/src/dalvik_system_DexFile.cc
@@ -185,13 +185,18 @@
}
}
- uint32_t location_checksum;
- if (!DexFile::GetChecksum(filename.c_str(), location_checksum)) {
- return JNI_TRUE;
+ // If we have an oat file next to the dex file, assume up-to-date.
+ // A user build looks like this, and it will have no classes.dex in
+ // the input for checksum validation.
+ std::string oat_filename(OatFile::DexFilenameToOatFilename(filename.c_str()));
+ const OatFile* oat_file = class_linker->FindOatFileFromOatLocation(oat_filename);
+ if (oat_file != NULL && oat_file->GetOatDexFile(filename.c_str()) != NULL) {
+ return JNI_FALSE;
}
- std::string oat_filename(OatFile::DexFilenameToOatFilename(filename.c_str()));
- const OatFile* oat_file(class_linker->FindOatFileFromOatLocation(oat_filename));
+ // Check if we have an oat file in the cache
+ std::string cache_location(GetArtCacheFilenameOrDie(oat_filename));
+ oat_file = class_linker->FindOatFileFromOatLocation(cache_location);
if (oat_file == NULL) {
return JNI_TRUE;
}
@@ -201,6 +206,11 @@
return JNI_TRUE;
}
+ uint32_t location_checksum;
+ if (!DexFile::GetChecksum(filename.c_str(), location_checksum)) {
+ return JNI_TRUE;
+ }
+
if (location_checksum != oat_dex_file->GetDexFileLocationChecksum()) {
return JNI_TRUE;
}
diff --git a/src/dalvik_system_VMRuntime.cc b/src/dalvik_system_VMRuntime.cc
index b953248..6f9480d 100644
--- a/src/dalvik_system_VMRuntime.cc
+++ b/src/dalvik_system_VMRuntime.cc
@@ -109,11 +109,11 @@
}
jstring VMRuntime_bootClassPath(JNIEnv* env, jobject) {
- return env->NewStringUTF(DefaultToDot(Runtime::Current()->GetBootClassPath()));
+ return env->NewStringUTF(DefaultToDot(Runtime::Current()->GetBootClassPathString()));
}
jstring VMRuntime_classPath(JNIEnv* env, jobject) {
- return env->NewStringUTF(DefaultToDot(Runtime::Current()->GetClassPath()));
+ return env->NewStringUTF(DefaultToDot(Runtime::Current()->GetClassPathString()));
}
jstring VMRuntime_vmVersion(JNIEnv* env, jobject) {
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index a27b76e..40e27a9 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -32,6 +32,7 @@
#include "object_utils.h"
#include "os.h"
#include "runtime.h"
+#include "stl_util.h"
#include "stringpiece.h"
#include "timing_logger.h"
#include "zip_archive.h"
@@ -52,18 +53,18 @@
" Example: --zip-fd=5\n"
"\n");
fprintf(stderr,
- " --zip-name=<zip-name>: specifies a symbolic name for the file corresponding\n"
+ " --zip-location=<zip-location>: specifies a symbolic name for the file corresponding\n"
" to the file descriptor specified by --zip-fd.\n"
- " Example: --zip-name=/system/app/Calculator.apk\n"
+ " Example: --zip-location=/system/app/Calculator.apk\n"
"\n");
fprintf(stderr,
" --oat-file=<file.oat>: specifies the required oat filename.\n"
" Example: --oat-file=/system/framework/boot.oat\n"
"\n");
fprintf(stderr,
- " --oat-name=<oat-name>: specifies a symbolic name for the file corresponding\n"
+ " --oat-location=<oat-name>: specifies a symbolic name for the file corresponding\n"
" to the file descriptor specified by --oat-fd.\n"
- " Example: --oat-name=/data/art-cache/system@app@Calculator.apk.oat\n"
+ " Example: --oat-location=/data/art-cache/system@app@Calculator.apk.oat\n"
"\n");
fprintf(stderr,
" --image=<file.art>: specifies the output image filename.\n"
@@ -191,7 +192,7 @@
if (!boot_image_option.empty()) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
std::vector<const DexFile*> class_path_files(dex_files);
- OpenClassPathFiles(runtime_->GetClassPath(), class_path_files);
+ OpenClassPathFiles(runtime_->GetClassPathString(), class_path_files);
for (size_t i = 0; i < class_path_files.size(); i++) {
class_linker->RegisterDexFile(*class_path_files[i]);
}
@@ -208,11 +209,11 @@
return true;
}
- bool CreateImageFile(const char* image_filename,
+ bool CreateImageFile(const std::string& image_filename,
uintptr_t image_base,
const std::set<std::string>* image_classes,
const std::string& oat_filename,
- const std::string& host_prefix) {
+ const std::string& oat_location) {
// If we have an existing boot image, position new space after its oat file
if (Heap::GetSpaces().size() > 1) {
ImageSpace* last_image_space = NULL;
@@ -230,7 +231,7 @@
}
ImageWriter image_writer(image_classes);
- if (!image_writer.Write(image_filename, image_base, oat_filename, host_prefix)) {
+ if (!image_writer.Write(image_filename, image_base, oat_filename, oat_location)) {
LOG(ERROR) << "Failed to create image file " << image_filename;
return false;
}
@@ -342,7 +343,7 @@
if (DexFilesContains(dex_files, parsed[i])) {
continue;
}
- const DexFile* dex_file = DexFile::Open(parsed[i], Runtime::Current()->GetHostPrefix());
+ const DexFile* dex_file = DexFile::Open(parsed[i], parsed[i]);
if (dex_file == NULL) {
LOG(WARNING) << "Failed to open dex file " << parsed[i];
} else {
@@ -381,11 +382,12 @@
}
void OpenDexFiles(const std::vector<const char*>& dex_filenames,
- std::vector<const DexFile*>& dex_files,
- const std::string& strip_location_prefix) {
+ const std::vector<const char*>& dex_locations,
+ std::vector<const DexFile*>& dex_files) {
for (size_t i = 0; i < dex_filenames.size(); i++) {
const char* dex_filename = dex_filenames[i];
- const DexFile* dex_file = DexFile::Open(dex_filename, strip_location_prefix);
+ const char* dex_location = dex_locations[i];
+ const DexFile* dex_file = DexFile::Open(dex_filename, dex_location);
if (dex_file == NULL) {
LOG(WARNING) << "could not open .dex from file " << dex_filename;
} else {
@@ -406,13 +408,14 @@
}
std::vector<const char*> dex_filenames;
+ std::vector<const char*> dex_locations;
int zip_fd = -1;
- std::string zip_name;
+ std::string zip_location;
std::string oat_filename;
+ std::string oat_location;
int oat_fd = -1;
- std::string oat_name;
- const char* image_filename = NULL;
const char* image_classes_filename = NULL;
+ std::string image_filename;
std::string boot_image_filename;
uintptr_t image_base = 0;
std::string host_prefix;
@@ -427,14 +430,16 @@
}
if (option.starts_with("--dex-file=")) {
dex_filenames.push_back(option.substr(strlen("--dex-file=")).data());
+ } else if (option.starts_with("--dex-location=")) {
+ dex_locations.push_back(option.substr(strlen("--dex-location=")).data());
} else if (option.starts_with("--zip-fd=")) {
const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data();
if (!ParseInt(zip_fd_str, &zip_fd)) {
fprintf(stderr, "could not parse --zip-fd argument '%s' as an integer\n", zip_fd_str);
usage();
}
- } else if (option.starts_with("--zip-name=")) {
- zip_name = option.substr(strlen("--zip-name=")).data();
+ } else if (option.starts_with("--zip-location=")) {
+ zip_location = option.substr(strlen("--zip-location=")).data();
} else if (option.starts_with("--oat-file=")) {
oat_filename = option.substr(strlen("--oat-file=")).data();
} else if (option.starts_with("--oat-fd=")) {
@@ -449,8 +454,8 @@
fprintf(stderr, "could not parse -j argument '%s' as an integer\n", thread_count_str);
usage();
}
- } else if (option.starts_with("--oat-name=")) {
- oat_name = option.substr(strlen("--oat-name=")).data();
+ } else if (option.starts_with("--oat-location=")) {
+ oat_location = option.substr(strlen("--oat-location=")).data();
} else if (option.starts_with("--image=")) {
image_filename = option.substr(strlen("--image=")).data();
} else if (option.starts_with("--image-classes=")) {
@@ -497,17 +502,7 @@
return EXIT_FAILURE;
}
- if (!oat_filename.empty() && !oat_name.empty()) {
- fprintf(stderr, "--oat-file should not be used with --oat-name\n");
- return EXIT_FAILURE;
- }
-
- if (oat_fd != -1 && oat_name.empty()) {
- fprintf(stderr, "--oat-name should be supplied with --oat-fd\n");
- return EXIT_FAILURE;
- }
-
- if (oat_fd != -1 && image_filename != NULL) {
+ if (oat_fd != -1 && !image_filename.empty()) {
fprintf(stderr, "--oat-fd should not be used with --image\n");
return EXIT_FAILURE;
}
@@ -519,7 +514,7 @@
}
}
- bool image = (image_filename != NULL);
+ bool image = (!image_filename.empty());
if (!image && boot_image_filename.empty()) {
if (host_prefix.empty()) {
boot_image_filename += GetAndroidRoot();
@@ -530,7 +525,11 @@
boot_image_filename += "/framework/boot.art";
}
std::string boot_image_option;
- if (boot_image_filename != NULL) {
+ if (!boot_image_filename.empty()) {
+ if (!OS::FileExists(boot_image_filename.c_str())) {
+ fprintf(stderr, "Failed to find boot image file %s\n", boot_image_filename.c_str());
+ return EXIT_FAILURE;
+ }
boot_image_option += "-Ximage:";
boot_image_option += boot_image_filename;
}
@@ -555,13 +554,22 @@
return EXIT_FAILURE;
}
- if (!dex_filenames.empty() && !zip_name.empty()) {
- fprintf(stderr, "--dex-file should not be used with --zip-name\n");
+ if (!dex_filenames.empty() && !zip_location.empty()) {
+ fprintf(stderr, "--dex-file should not be used with --zip-location\n");
return EXIT_FAILURE;
}
- if (zip_fd != -1 && zip_name.empty()) {
- fprintf(stderr, "--zip-name should be supplied with --zip-fd\n");
+ if (dex_locations.empty()) {
+ for (size_t i = 0; i < dex_filenames.size(); i++) {
+ dex_locations.push_back(dex_filenames[i]);
+ }
+ } else if (dex_locations.size() != dex_filenames.size()) {
+ fprintf(stderr, "--dex-location arguments do not match --dex-file arguments\n");
+ return EXIT_FAILURE;
+ }
+
+ if (zip_fd != -1 && zip_location.empty()) {
+ fprintf(stderr, "--zip-location should be supplied with --zip-fd\n");
return EXIT_FAILURE;
}
@@ -576,28 +584,25 @@
UniquePtr<File> oat_file;
if (!oat_filename.empty()) {
oat_file.reset(OS::OpenFile(oat_filename.c_str(), true));
- oat_name = oat_filename;
+ if (oat_location.empty()) {
+ oat_location = oat_filename;
+ }
} else {
- oat_file.reset(OS::FileFromFd(oat_name.c_str(), oat_fd));
+ oat_file.reset(OS::FileFromFd(oat_location.c_str(), oat_fd));
}
if (oat_file.get() == NULL) {
- PLOG(ERROR) << "Unable to create oat file: " << oat_name;
+ PLOG(ERROR) << "Unable to create oat file: " << oat_location;
return EXIT_FAILURE;
}
- LOG(INFO) << "dex2oat: " << oat_name;
+ LOG(INFO) << "dex2oat: " << oat_location;
Runtime::Options options;
options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
- std::string boot_class_path_string;
+ std::vector<const DexFile*> boot_class_path;
if (boot_image_option.empty()) {
- boot_class_path_string += "-Xbootclasspath:";
- for (size_t i = 0; i < dex_filenames.size()-1; i++) {
- boot_class_path_string += dex_filenames[i];
- boot_class_path_string += ":";
- }
- boot_class_path_string += dex_filenames[dex_filenames.size()-1];
- options.push_back(std::make_pair(boot_class_path_string.c_str(), reinterpret_cast<void*>(NULL)));
+ OpenDexFiles(dex_filenames, dex_locations, boot_class_path);
+ options.push_back(std::make_pair("bootclasspath", &boot_class_path));
} else {
options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL)));
}
@@ -627,17 +632,17 @@
if (dex_filenames.empty()) {
UniquePtr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd));
if (zip_archive.get() == NULL) {
- LOG(ERROR) << "Failed to zip from file descriptor for " << zip_name;
+ LOG(ERROR) << "Failed to zip from file descriptor for " << zip_location;
return EXIT_FAILURE;
}
- const DexFile* dex_file = DexFile::Open(*zip_archive.get(), zip_name);
+ const DexFile* dex_file = DexFile::Open(*zip_archive.get(), zip_location);
if (dex_file == NULL) {
- LOG(ERROR) << "Failed to open dex from file descriptor for zip file: " << zip_name;
+ LOG(ERROR) << "Failed to open dex from file descriptor for zip file: " << zip_location;
return EXIT_FAILURE;
}
dex_files.push_back(dex_file);
} else {
- OpenDexFiles(dex_filenames, dex_files, host_prefix);
+ OpenDexFiles(dex_filenames, dex_locations, dex_files);
}
}
@@ -646,12 +651,12 @@
oat_file.get(),
image,
image_classes.get())) {
- LOG(ERROR) << "Failed to create oat file: " << oat_name;
+ LOG(ERROR) << "Failed to create oat file: " << oat_location;
return EXIT_FAILURE;
}
if (!image) {
- LOG(INFO) << "Oat file written successfully: " << oat_name;
+ LOG(INFO) << "Oat file written successfully: " << oat_location;
return EXIT_SUCCESS;
}
@@ -659,7 +664,7 @@
image_base,
image_classes.get(),
oat_filename,
- host_prefix)) {
+ oat_location)) {
return EXIT_FAILURE;
}
diff --git a/src/dex_cache_test.cc b/src/dex_cache_test.cc
index ce79de1..c8dbc7c 100644
--- a/src/dex_cache_test.cc
+++ b/src/dex_cache_test.cc
@@ -27,7 +27,7 @@
class DexCacheTest : public CommonTest {};
TEST_F(DexCacheTest, Open) {
- SirtRef<DexCache> dex_cache(class_linker_->AllocDexCache(*java_lang_dex_file_.get()));
+ SirtRef<DexCache> dex_cache(class_linker_->AllocDexCache(*java_lang_dex_file_));
ASSERT_TRUE(dex_cache.get() != NULL);
EXPECT_EQ(java_lang_dex_file_->NumStringIds(), dex_cache->NumStrings());
diff --git a/src/dex_file.cc b/src/dex_file.cc
index c574d89..2a59ee3 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -85,14 +85,14 @@
}
const DexFile* DexFile::Open(const std::string& filename,
- const std::string& strip_location_prefix) {
+ const std::string& location) {
if (IsValidZipFilename(filename)) {
- return DexFile::OpenZip(filename, strip_location_prefix);
+ return DexFile::OpenZip(filename, location);
}
if (!IsValidDexFilename(filename)) {
LOG(WARNING) << "Attempting to open dex file with unknown extension '" << filename << "'";
}
- return DexFile::OpenFile(filename, strip_location_prefix, true);
+ return DexFile::OpenFile(filename, location, true);
}
void DexFile::ChangePermissions(int prot) const {
@@ -101,25 +101,10 @@
}
}
-const std::string StripLocationPrefix(const std::string& original_location,
- const std::string& strip_location_prefix) {
- StringPiece location = original_location;
- if (!location.starts_with(strip_location_prefix)) {
- LOG(ERROR) << location << " does not start with " << strip_location_prefix;
- return "";
- }
- location.remove_prefix(strip_location_prefix.size());
- return location.ToString();
-}
-
const DexFile* DexFile::OpenFile(const std::string& filename,
- const std::string& strip_location_prefix,
+ const std::string& location,
bool verify) {
- std::string location(StripLocationPrefix(filename, strip_location_prefix));
- if (location.empty()) {
- return NULL;
- }
-
+ CHECK(!location.empty()) << filename;
int fd = open(filename.c_str(), O_RDONLY); // TODO: scoped_fd
if (fd == -1) {
PLOG(ERROR) << "open(\"" << filename << "\", O_RDONLY) failed";
@@ -170,12 +155,7 @@
// Open classes.dex from within a .zip, .jar, .apk, ...
const DexFile* DexFile::OpenZip(const std::string& filename,
- const std::string& strip_location_prefix) {
- std::string location(StripLocationPrefix(filename, strip_location_prefix));
- if (location.empty()) {
- return NULL;
- }
-
+ const std::string& location) {
UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(filename));
if (zip_archive.get() == NULL) {
LOG(ERROR) << "Failed to open " << filename << " when looking for classes.dex";
@@ -185,6 +165,7 @@
}
const DexFile* DexFile::Open(const ZipArchive& zip_archive, const std::string& location) {
+ CHECK(!location.empty());
UniquePtr<ZipEntry> zip_entry(zip_archive.Find(kClassesDex));
if (zip_entry.get() == NULL) {
LOG(ERROR) << "Failed to find classes.dex within " << location;
diff --git a/src/dex_file.h b/src/dex_file.h
index 5d63408..1f87bca 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -322,7 +322,7 @@
// Opens .dex file, guessing the container format based on file extension
static const DexFile* Open(const std::string& filename,
- const std::string& strip_location_prefix);
+ const std::string& location);
// Opens .dex file, backed by existing memory
static const DexFile* Open(const uint8_t* base, size_t size,
@@ -773,12 +773,12 @@
// Opens a .dex file
static const DexFile* OpenFile(const std::string& filename,
- const std::string& strip_location_prefix,
+ const std::string& location,
bool verify);
// Opens a dex file from within a .jar, .zip, or .apk file
static const DexFile* OpenZip(const std::string& filename,
- const std::string& strip_location_prefix);
+ const std::string& location);
// Opens a .dex file at the given address backed by a MemMap
static const DexFile* OpenMemory(const std::string& location,
diff --git a/src/dex_verifier_test.cc b/src/dex_verifier_test.cc
index 51fb1bc..9106b76 100644
--- a/src/dex_verifier_test.cc
+++ b/src/dex_verifier_test.cc
@@ -50,7 +50,7 @@
};
TEST_F(DexVerifierTest, LibCore) {
- VerifyDexFile(java_lang_dex_file_.get(), NULL);
+ VerifyDexFile(java_lang_dex_file_, NULL);
}
TEST_F(DexVerifierTest, IntMath) {
diff --git a/src/heap.cc b/src/heap.cc
index 3a3ee5a..ad20f9c 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -84,7 +84,7 @@
}
bool GenerateImage(const std::string image_file_name) {
- const std::string boot_class_path_string = Runtime::Current()->GetBootClassPath();
+ const std::string boot_class_path_string(Runtime::Current()->GetBootClassPathString());
std::vector<std::string> boot_class_path;
Split(boot_class_path_string, ':', boot_class_path);
diff --git a/src/image_test.cc b/src/image_test.cc
index 97d37c5..fb87a49 100644
--- a/src/image_test.cc
+++ b/src/image_test.cc
@@ -33,7 +33,7 @@
TEST_F(ImageTest, WriteRead) {
ScratchFile tmp_oat;
std::vector<const DexFile*> dex_files;
- dex_files.push_back(java_lang_dex_file_.get());
+ dex_files.push_back(java_lang_dex_file_);
bool success_oat = OatWriter::Create(tmp_oat.GetFile(), NULL, dex_files, *compiler_.get());
ASSERT_TRUE(success_oat);
@@ -49,11 +49,11 @@
ScratchFile tmp_image;
const uintptr_t requested_image_base = 0x60000000;
bool success_image = writer.Write(tmp_image.GetFilename(), requested_image_base,
- std::string(tmp_oat.GetFilename()), "");
+ tmp_oat.GetFilename(), tmp_oat.GetFilename());
ASSERT_TRUE(success_image);
{
- UniquePtr<File> file(OS::OpenFile(tmp_image.GetFilename(), false));
+ UniquePtr<File> file(OS::OpenFile(tmp_image.GetFilename().c_str(), false));
ASSERT_TRUE(file.get() != NULL);
ImageHeader image_header;
file->ReadFully(&image_header, sizeof(image_header));
@@ -68,12 +68,9 @@
// tear down old runtime before making a new one, clearing out misc state
delete runtime_.release();
+ java_lang_dex_file_ = NULL;
- // don't reuse java_lang_dex_file_ so we make sure we don't get
- // lucky by pointers that happen to work referencing the earlier
- // dex.
- delete java_lang_dex_file_.release();
- UniquePtr<const DexFile> dex(DexFile::Open(GetLibCoreDexFileName(), ""));
+ UniquePtr<const DexFile> dex(DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName()));
ASSERT_TRUE(dex.get() != NULL);
Runtime::Options options;
diff --git a/src/image_writer.cc b/src/image_writer.cc
index f92989d..ffe4ec3 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -41,11 +41,11 @@
std::map<const Object*, size_t> ImageWriter::offsets_;
-bool ImageWriter::Write(const char* image_filename,
+bool ImageWriter::Write(const std::string& image_filename,
uintptr_t image_begin,
const std::string& oat_filename,
- const std::string& strip_location_prefix) {
- CHECK(image_filename != NULL);
+ const std::string& oat_location) {
+ CHECK(!image_filename.empty());
CHECK_NE(image_begin, 0U);
image_begin_ = reinterpret_cast<byte*>(image_begin);
@@ -65,7 +65,7 @@
}
}
- oat_file_.reset(OatFile::Open(oat_filename, strip_location_prefix, NULL));
+ oat_file_.reset(OatFile::Open(oat_filename, oat_location, NULL));
if (oat_file_.get() == NULL) {
LOG(ERROR) << "Failed to open oat file " << oat_filename;
return false;
@@ -85,7 +85,7 @@
CalculateNewObjectOffsets();
CopyAndFixupObjects();
- UniquePtr<File> file(OS::OpenFile(image_filename, true));
+ UniquePtr<File> file(OS::OpenFile(image_filename.c_str(), true));
if (file.get() == NULL) {
LOG(ERROR) << "Failed to open image file " << image_filename;
return false;
diff --git a/src/image_writer.h b/src/image_writer.h
index 5e0ed01..74a3f94 100644
--- a/src/image_writer.h
+++ b/src/image_writer.h
@@ -43,10 +43,10 @@
~ImageWriter() {}
- bool Write(const char* image_filename,
+ bool Write(const std::string& image_filename,
uintptr_t image_begin,
const std::string& oat_filename,
- const std::string& strip_location_prefix);
+ const std::string& oat_location);
private:
bool AllocMemory();
diff --git a/src/oat_file.cc b/src/oat_file.cc
index cf8bafe..26314b1 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -32,19 +32,14 @@
}
OatFile* OatFile::Open(const std::string& filename,
- const std::string& strip_location_prefix,
+ const std::string& location,
byte* requested_base) {
- StringPiece location(filename);
- if (!location.starts_with(strip_location_prefix)) {
- LOG(ERROR) << filename << " does not start with " << strip_location_prefix;
- return NULL;
- }
- location.remove_prefix(strip_location_prefix.size());
+ CHECK(!location.empty()) << filename;
UniquePtr<File> file(OS::OpenFile(filename.c_str(), false));
if (file.get() == NULL) {
return false;
}
- return Open(*file.get(), location.ToString(), requested_base);
+ return Open(*file.get(), location, requested_base);
}
OatFile* OatFile::Open(File& file,
@@ -58,7 +53,9 @@
return oat_file.release();
}
-OatFile::OatFile(const std::string& filename) : location_(filename) {}
+OatFile::OatFile(const std::string& location) : location_(location) {
+ CHECK(!location_.empty());
+}
OatFile::~OatFile() {
STLDeleteValues(&oat_dex_files_);
diff --git a/src/oat_file.h b/src/oat_file.h
index 2895d74..83560e8 100644
--- a/src/oat_file.h
+++ b/src/oat_file.h
@@ -36,7 +36,7 @@
// Open an oat file. Returns NULL on failure. Requested base can
// optionally be used to request where the file should be loaded.
static OatFile* Open(const std::string& filename,
- const std::string& strip_location_prefix,
+ const std::string& location,
byte* requested_base);
// Open an oat file from an already opened File with the given location.
diff --git a/src/oat_test.cc b/src/oat_test.cc
index 7c837d4..b27595e 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -40,23 +40,23 @@
if (compile) { // OatWriter strips the code, regenerate to compare
compiler_->CompileAll(class_loader.get(), class_linker->GetBootClassPath());
}
- UniquePtr<OatFile> oat_file(OatFile::Open(std::string(tmp.GetFilename()), "", NULL));
+ UniquePtr<OatFile> oat_file(OatFile::Open(tmp.GetFilename(), tmp.GetFilename(), NULL));
ASSERT_TRUE(oat_file.get() != NULL);
const OatHeader& oat_header = oat_file->GetOatHeader();
ASSERT_EQ(1U, oat_header.GetDexFileCount());
- const DexFile& dex_file = *java_lang_dex_file_.get();
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
- CHECK_EQ(dex_file.GetLocationChecksum(), oat_dex_file->GetDexFileLocationChecksum());
- for (size_t i = 0; i < dex_file.NumClassDefs(); i++) {
- const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
- const byte* class_data = dex_file.GetClassData(class_def);
+ const DexFile* dex_file = java_lang_dex_file_;
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file->GetLocation());
+ CHECK_EQ(dex_file->GetLocationChecksum(), oat_dex_file->GetDexFileLocationChecksum());
+ for (size_t i = 0; i < dex_file->NumClassDefs(); i++) {
+ const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
+ const byte* class_data = dex_file->GetClassData(class_def);
size_t num_virtual_methods =0;
if (class_data != NULL) {
- ClassDataItemIterator it(dex_file, class_data);
+ ClassDataItemIterator it(*dex_file, class_data);
num_virtual_methods = it.NumVirtualMethods();
}
- const char* descriptor = dex_file.GetClassDescriptor(class_def);
+ const char* descriptor = dex_file->GetClassDescriptor(class_def);
UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(i));
@@ -67,7 +67,7 @@
Method* method = klass->GetDirectMethod(i);
const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index);
const CompiledMethod* compiled_method =
- compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
+ compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file,
method->GetDexMethodIndex()));
if (compiled_method == NULL) {
@@ -94,7 +94,7 @@
Method* method = klass->GetVirtualMethod(i);
const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index);
const CompiledMethod* compiled_method =
- compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
+ compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file,
method->GetDexMethodIndex()));
if (compiled_method == NULL) {
diff --git a/src/oatdump.cc b/src/oatdump.cc
index 4ea2af1..1b54b24 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -81,7 +81,6 @@
class OatDump {
public:
static void Dump(const std::string& oat_filename,
- const std::string& host_prefix,
std::ostream& os,
const OatFile& oat_file) {
const OatHeader& oat_header = oat_file.GetOatHeader();
@@ -110,26 +109,19 @@
for (size_t i = 0; i < oat_dex_files.size(); i++) {
const OatFile::OatDexFile* oat_dex_file = oat_dex_files[i];
CHECK(oat_dex_file != NULL);
- DumpOatDexFile(host_prefix, os, oat_file, *oat_dex_file);
+ DumpOatDexFile(os, oat_file, *oat_dex_file);
}
}
private:
- static void DumpOatDexFile(const std::string& host_prefix,
- std::ostream& os,
+ static void DumpOatDexFile(std::ostream& os,
const OatFile& oat_file,
const OatFile::OatDexFile& oat_dex_file) {
os << "OAT DEX FILE:\n";
- std::string dex_file_location(oat_dex_file.GetDexFileLocation());
- os << "location: " << dex_file_location;
- if (!host_prefix.empty()) {
- dex_file_location = host_prefix + dex_file_location;
- os << " (" << dex_file_location << ")";
- }
- os << "\n";
+ os << StringPrintf("location: %s\n", oat_dex_file.GetDexFileLocation().c_str());
os << StringPrintf("checksum: %08x\n", oat_dex_file.GetDexFileLocationChecksum());
- const DexFile* dex_file = DexFile::Open(dex_file_location, "");
- if (dex_file == NULL) {
+ UniquePtr<const DexFile> dex_file(oat_dex_file.OpenDexFile());
+ if (dex_file.get() == NULL) {
os << "NOT FOUND\n\n";
return;
}
@@ -140,7 +132,7 @@
CHECK(oat_class.get() != NULL);
os << StringPrintf("%zd: %s (type_idx=%d) (", class_def_index, descriptor, class_def.class_idx_)
<< oat_class->GetStatus() << ")\n";
- DumpOatClass(os, oat_file, *oat_class.get(), *dex_file, class_def);
+ DumpOatClass(os, oat_file, *oat_class.get(), *(dex_file.get()), class_def);
}
os << std::flush;
@@ -291,7 +283,7 @@
os << "\n";
os << std::flush;
- OatDump::Dump(oat_location, host_prefix, os, *oat_file);
+ OatDump::Dump(oat_location, os, *oat_file);
}
private:
@@ -561,12 +553,12 @@
}
if (oat_filename != NULL) {
- const OatFile* oat_file = OatFile::Open(oat_filename, "", NULL);
+ const OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, NULL);
if (oat_file == NULL) {
fprintf(stderr, "Failed to open oat file from %s\n", oat_filename);
return EXIT_FAILURE;
}
- OatDump::Dump(oat_filename, host_prefix, *os, *oat_file);
+ OatDump::Dump(oat_filename, *os, *oat_file);
return EXIT_SUCCESS;
}
diff --git a/src/runtime.cc b/src/runtime.cc
index 31b6539..537aadb 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -261,13 +261,13 @@
Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, bool ignore_unrecognized) {
UniquePtr<ParsedOptions> parsed(new ParsedOptions());
- const char* boot_class_path = getenv("BOOTCLASSPATH");
- if (boot_class_path != NULL) {
- parsed->boot_class_path_ = boot_class_path;
+ const char* boot_class_path_string = getenv("BOOTCLASSPATH");
+ if (boot_class_path_string != NULL) {
+ parsed->boot_class_path_string_ = boot_class_path_string;
}
- const char* class_path = getenv("CLASSPATH");
- if (class_path != NULL) {
- parsed->class_path_ = class_path;
+ const char* class_path_string = getenv("CLASSPATH");
+ if (class_path_string != NULL) {
+ parsed->class_path_string_ = class_path_string;
}
#ifdef NDEBUG
// -Xcheck:jni is off by default for regular builds...
@@ -299,7 +299,7 @@
LOG(INFO) << "option[" << i << "]=" << option;
}
if (StartsWith(option, "-Xbootclasspath:")) {
- parsed->boot_class_path_ = option.substr(strlen("-Xbootclasspath:"));
+ parsed->boot_class_path_string_ = option.substr(strlen("-Xbootclasspath:")).data();
} else if (option == "-classpath" || option == "-cp") {
// TODO: support -Djava.class.path
i++;
@@ -308,9 +308,13 @@
LOG(FATAL) << "Missing required class path value for " << option;
return NULL;
}
- parsed->class_path_ = options[i].first;
+ const StringPiece& value = options[i].first;
+ parsed->class_path_string_ = value.data();
+ } else if (option == "bootclasspath") {
+ parsed->boot_class_path_
+ = reinterpret_cast<const std::vector<const DexFile*>*>(options[i].second);
} else if (StartsWith(option, "-Ximage:")) {
- parsed->image_ = option.substr(strlen("-Ximage:"));
+ parsed->image_ = option.substr(strlen("-Ximage:")).data();
} else if (StartsWith(option, "-Xcheck:jni")) {
parsed->check_jni_ = true;
} else if (StartsWith(option, "-Xrunjdwp:") || StartsWith(option, "-agentlib:jdwp=")) {
@@ -582,8 +586,8 @@
Monitor::Init(options->lock_profiling_threshold_, options->hook_is_sensitive_thread_);
host_prefix_ = options->host_prefix_;
- boot_class_path_ = options->boot_class_path_;
- class_path_ = options->class_path_;
+ boot_class_path_string_ = options->boot_class_path_string_;
+ class_path_string_ = options->class_path_string_;
properties_ = options->properties_;
is_compiler_ = options->is_compiler_;
@@ -619,9 +623,14 @@
Thread::Current()->SetState(Thread::kRunnable);
CHECK_GE(Heap::GetSpaces().size(), 1U);
- class_linker_ = ((Heap::GetSpaces()[0]->IsImageSpace())
- ? ClassLinker::Create(intern_table_)
- : ClassLinker::Create(options->boot_class_path_, intern_table_));
+ if (Heap::GetSpaces()[0]->IsImageSpace()) {
+ class_linker_ = ClassLinker::CreateFromImage(intern_table_);
+ } else {
+ CHECK(options->boot_class_path_ != NULL);
+ CHECK_NE(options->boot_class_path_->size(), 0U);
+ class_linker_ = ClassLinker::CreateFromCompiler(*options->boot_class_path_, intern_table_);
+ }
+ CHECK(class_linker_ != NULL);
VLOG(startup) << "Runtime::Init exiting";
return true;
diff --git a/src/runtime.h b/src/runtime.h
index b284b46..af44948 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -60,8 +60,9 @@
// returns null if problem parsing and ignore_unrecognized is false
static ParsedOptions* Create(const Options& options, bool ignore_unrecognized);
- std::string boot_class_path_;
- std::string class_path_;
+ const std::vector<const DexFile*>* boot_class_path_;
+ std::string boot_class_path_string_;
+ std::string class_path_string_;
std::string host_prefix_;
std::string image_;
bool check_jni_;
@@ -131,18 +132,18 @@
~Runtime();
- const std::string& GetBootClassPath() const {
- return boot_class_path_;
+ const std::string& GetBootClassPathString() const {
+ return boot_class_path_string_;
+ }
+
+ const std::string& GetClassPathString() const {
+ return class_path_string_;
}
ClassLinker* GetClassLinker() const {
return class_linker_;
}
- const std::string& GetClassPath() const {
- return class_path_;
- }
-
size_t GetDefaultStackSize() const {
return default_stack_size_;
}
@@ -255,8 +256,8 @@
// files contain the expected target path.
std::string host_prefix_;
- std::string boot_class_path_;
- std::string class_path_;
+ std::string boot_class_path_string_;
+ std::string class_path_string_;
std::vector<std::string> properties_;
// The default stack size for managed threads created by the runtime.
diff --git a/src/runtime_test.cc b/src/runtime_test.cc
index 460fe44..e147749 100644
--- a/src/runtime_test.cc
+++ b/src/runtime_test.cc
@@ -56,8 +56,8 @@
UniquePtr<Runtime::ParsedOptions> parsed(Runtime::ParsedOptions::Create(options, false));
ASSERT_TRUE(parsed.get() != NULL);
- EXPECT_EQ(lib_core, parsed->boot_class_path_);
- EXPECT_EQ(lib_core, parsed->class_path_);
+ EXPECT_EQ(lib_core, parsed->boot_class_path_string_);
+ EXPECT_EQ(lib_core, parsed->class_path_string_);
EXPECT_EQ(std::string("boot_image"), parsed->image_);
EXPECT_EQ(true, parsed->check_jni_);
EXPECT_EQ(2048U, parsed->heap_initial_size_);
diff --git a/src/zip_archive_test.cc b/src/zip_archive_test.cc
index bd0bc6d..7409ec4 100644
--- a/src/zip_archive_test.cc
+++ b/src/zip_archive_test.cc
@@ -36,14 +36,14 @@
ScratchFile tmp;
ASSERT_NE(-1, tmp.GetFd());
- UniquePtr<File> file(OS::FileFromFd(tmp.GetFilename(), tmp.GetFd()));
+ UniquePtr<File> file(OS::FileFromFd(tmp.GetFilename().c_str(), tmp.GetFd()));
ASSERT_TRUE(file.get() != NULL);
bool success = zip_entry->ExtractToFile(*file);
ASSERT_TRUE(success);
close(tmp.GetFd());
uint32_t computed_crc = crc32(0L, Z_NULL, 0);
- int fd = open(tmp.GetFilename(), O_RDONLY);
+ int fd = open(tmp.GetFilename().c_str(), O_RDONLY);
ASSERT_NE(-1, fd);
const size_t kBufSize = 32768;
uint8_t buf[kBufSize];
diff --git a/test/003-omnibus-opcodes/build b/test/003-omnibus-opcodes/build
index 1123582..bec2e74 100644
--- a/test/003-omnibus-opcodes/build
+++ b/test/003-omnibus-opcodes/build
@@ -24,4 +24,4 @@
dx -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes
zip ${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar classes.dex
-dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
+dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --dex-location=/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
diff --git a/test/022-interface/build b/test/022-interface/build
index a48bf20..4aec359 100644
--- a/test/022-interface/build
+++ b/test/022-interface/build
@@ -21,4 +21,4 @@
# issue when interfaces override methods in Object
dx --debug --dex --dump-to=classes.lst --output=classes.dex classes
zip ${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar classes.dex
-dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
+dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --dex-location=/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
diff --git a/test/023-many-interfaces/build b/test/023-many-interfaces/build
index 64c4cc2..4c73685 100644
--- a/test/023-many-interfaces/build
+++ b/test/023-many-interfaces/build
@@ -26,4 +26,4 @@
dx --debug --dex --dump-to=classes.lst --output=classes.dex classes
zip ${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar classes.dex
-dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
+dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --dex-location=/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
diff --git a/test/056-const-string-jumbo/build b/test/056-const-string-jumbo/build
index 5b6c075..9043e6a 100644
--- a/test/056-const-string-jumbo/build
+++ b/test/056-const-string-jumbo/build
@@ -44,4 +44,4 @@
dx -JXmx500m --debug --dex --no-optimize --positions=none --no-locals --dump-to=classes.lst --output=classes.dex classes
zip ${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar classes.dex
-dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
+dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --dex-location=/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
diff --git a/test/071-dexfile/info.txt b/test/071-dexfile/info.txt
index 54d9ed0..7328d71 100644
--- a/test/071-dexfile/info.txt
+++ b/test/071-dexfile/info.txt
@@ -1,4 +1,4 @@
Exercise some Dalvik-specific DEX file features. This is not expected to
work on other VMs.
-NOTE: the test requires that /sdcard exists and is writable.
+NOTE: the test requires that /data/art-test/ exists and is writable and not mounted noexec.
diff --git a/test/085-old-style-inner-class/build b/test/085-old-style-inner-class/build
index 5ade65d..1162d1d 100644
--- a/test/085-old-style-inner-class/build
+++ b/test/085-old-style-inner-class/build
@@ -26,4 +26,4 @@
dx --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes 2>/dev/null
zip ${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar classes.dex
-dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat 2>/dev/null
+dex2oat --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --dex-location=/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat 2>/dev/null
diff --git a/test/etc/default-build b/test/etc/default-build
index b4c1a23..1d11c9f 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -26,7 +26,7 @@
dx -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes
zip ${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar classes.dex
-dex2oatd --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
+dex2oatd --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar --dex-location=/data/art-test/$TEST_NAME.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME.jar.oat
if [ -r src-ex ]; then
mkdir classes-ex
@@ -37,7 +37,7 @@
mv classes.dex classes-1.dex
mv classes-ex.dex classes.dex
zip ${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME-ex.jar classes.dex
- dex2oatd --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME-ex.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME-ex.jar.oat
+ dex2oatd --boot-image=${ANDROID_PRODUCT_OUT}/data/art-test/core.art --dex-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME-ex.jar --dex-location=/data/art-test/$TEST_NAME-ex.jar --oat-file=${ANDROID_PRODUCT_OUT}/data/art-test/$TEST_NAME-ex.jar.oat
mv classes.dex classes-ex.dex
mv classes-1.dex classes.dex
fi