Merge "Add ISA directory to image and odex pathnames."
diff --git a/Android.mk b/Android.mk
index 0cd9166..a7a1556 100644
--- a/Android.mk
+++ b/Android.mk
@@ -240,10 +240,9 @@
 endef
 $(eval $(call call-art-multi-target-rule,declare-test-art-target,test-art-target))
 
-
 define declare-test-art-target-dependencies
 .PHONY: test-art-target-dependencies$(1)
-test-art-target-dependencies$(1): $(ART_TARGET_TEST_DEPENDENCIES$(1)) $(ART_TEST_OUT)/libarttest.so
+test-art-target-dependencies$(1): $(ART_TARGET_TEST_DEPENDENCIES$(1)) $(ART_TARGET_LIBARTTEST_$(1))
 endef
 $(eval $(call call-art-multi-target-rule,declare-test-art-target-dependencies,test-art-target-dependencies))
 
@@ -403,7 +402,7 @@
 .PHONY: dump-oat-core-host
 ifeq ($(ART_BUILD_HOST),true)
 dump-oat-core-host: $(HOST_CORE_IMG_OUT) $(OATDUMP)
-	$(OATDUMP) --image=$(HOST_CORE_IMG_OUT) --output=$(ART_DUMP_OAT_PATH)/core.host.oatdump.txt
+	$(OATDUMP) --image=$(HOST_CORE_IMG_LOCATION) --output=$(ART_DUMP_OAT_PATH)/core.host.oatdump.txt
 	@echo Output in $(ART_DUMP_OAT_PATH)/core.host.oatdump.txt
 endif
 
diff --git a/build/Android.common.mk b/build/Android.common.mk
index cc600bd..5341136 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -136,12 +136,12 @@
 ART_DALVIK_CACHE_DIR := /data/dalvik-cache
 
 # directory used for gtests on device
-ART_BASE_NATIVETEST_DIR := /data/nativetest/art
-ART_BASE_NATIVETEST_OUT := $(TARGET_OUT_DATA_NATIVE_TESTS)/art
+ART_NATIVETEST_DIR := /data/nativetest/art
+ART_NATIVETEST_OUT := $(TARGET_OUT_DATA_NATIVE_TESTS)/art
 
-# directory used for tests on device
-ART_BASE_TEST_DIR := /data/art-test
-ART_BASE_TEST_OUT := $(TARGET_OUT_DATA)/art-test
+# directory used for oat tests on device
+ART_TEST_DIR := /data/art-test
+ART_TEST_OUT := $(TARGET_OUT_DATA)/art-test
 
 # Primary vs. secondary
 2ND_TARGET_ARCH := $(TARGET_2ND_ARCH)
@@ -157,26 +157,15 @@
     ART_PHONY_TEST_TARGET_SUFFIX := 64
     2ND_ART_PHONY_TEST_TARGET_SUFFIX := 32
     ART_TARGET_BINARY_SUFFIX := 64
+    ART_TARGET_ARCH_32 := $(TARGET_2ND_ARCH)
+    ART_TARGET_ARCH_64 := $(TARGET_ARCH)
   else
     # TODO: ???
     $(error Do not know what to do with this multi-target configuration!)
   endif
-  # Primary with primary suffix
-  ART_NATIVETEST_DIR := $(ART_BASE_NATIVETEST_DIR)$(art_test_primary_suffix)
-  ART_NATIVETEST_OUT := $(ART_BASE_NATIVETEST_OUT)$(art_test_primary_suffix)
-  ART_TEST_DIR := $(ART_BASE_TEST_DIR)$(art_test_primary_suffix)
-  ART_TEST_OUT := $(ART_BASE_TEST_OUT)$(art_test_primary_suffix)
-  # Secondary with 2ND_ prefix and secondary suffix
-  2ND_ART_NATIVETEST_DIR := $(ART_BASE_NATIVETEST_DIR)$(art_test_secondary_suffix)
-  2ND_ART_NATIVETEST_OUT := $(ART_BASE_NATIVETEST_OUT)$(art_test_secondary_suffix)
-  2ND_ART_TEST_DIR := $(ART_BASE_TEST_DIR)$(art_test_secondary_suffix)
-  2ND_ART_TEST_OUT := $(ART_BASE_TEST_OUT)$(art_test_secondary_suffix)
 else
-  ART_NATIVETEST_DIR := $(ART_BASE_NATIVETEST_DIR)
-  ART_NATIVETEST_OUT := $(ART_BASE_NATIVETEST_OUT)
-  ART_TEST_DIR := $(ART_BASE_TEST_DIR)
-  ART_TEST_OUT := $(ART_BASE_TEST_OUT)
-  # No secondary
+  ART_TARGET_ARCH_32 := $(TARGET_ARCH)
+  ART_TARGET_ARCH_64 :=
 endif
 
 ART_CPP_EXTENSION := .cc
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 226df98..1cd528b 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -130,12 +130,12 @@
 # (1) Prefix for variables
 define build-art-test-make-target
 .PHONY: $$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX)
-$$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX): $($(1)ART_NATIVETEST_OUT)/$$(LOCAL_MODULE) test-art-target-sync
-	adb shell touch $($(1)ART_TEST_DIR)/$$@
-	adb shell rm $($(1)ART_TEST_DIR)/$$@
-	adb shell chmod 755 $($(1)ART_NATIVETEST_DIR)/$$(notdir $$<)
-	adb shell sh -c "$($(1)ART_NATIVETEST_DIR)/$$(notdir $$<) && touch $($(1)ART_TEST_DIR)/$$@"
-	$(hide) (adb pull $($(1)ART_TEST_DIR)/$$@ /tmp/ && echo $$@ PASSED) || (echo $$@ FAILED && exit 1)
+$$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX): $(ART_NATIVETEST_OUT)/$(TARGET_$(1)ARCH)/$$(LOCAL_MODULE) test-art-target-sync
+	adb shell touch $(ART_TEST_DIR)/$(TARGET_$(1)ARCH)/$$@
+	adb shell rm $(ART_TEST_DIR)/$(TARGET_$(1)ARCH)/$$@
+	adb shell chmod 755 $(ART_NATIVETEST_DIR)/$(TARGET_$(1)ARCH)/$$(notdir $$<)
+	adb shell sh -c "$(ART_NATIVETEST_DIR)/$(TARGET_$(1)ARCH)/$$(notdir $$<) && touch $(ART_TEST_DIR)/$(TARGET_$(1)ARCH)/$$@"
+	$(hide) (adb pull $(ART_TEST_DIR)/$(TARGET_$(1)ARCH)/$$@ /tmp/ && echo $$@ PASSED) || (echo $$@ FAILED && exit 1)
 	$(hide) rm /tmp/$$@
 
   ART_TARGET_GTEST_TARGETS$($(1)ART_PHONY_TEST_TARGET_SUFFIX) += $$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX)
@@ -188,19 +188,19 @@
     LOCAL_CFLAGS_x86 := $(ART_TARGET_CFLAGS_x86)
     LOCAL_SHARED_LIBRARIES += libdl libicuuc libicui18n libnativehelper libz libcutils libvixl
     LOCAL_STATIC_LIBRARIES += libgtest
-    LOCAL_MODULE_PATH_32 := $(ART_BASE_NATIVETEST_OUT)
-    LOCAL_MODULE_PATH_64 := $(ART_BASE_NATIVETEST_OUT)64
+    LOCAL_MODULE_PATH_32 := $(ART_NATIVETEST_OUT)/$(ART_TARGET_ARCH_32)
+    LOCAL_MODULE_PATH_64 := $(ART_NATIVETEST_OUT)/$(ART_TARGET_ARCH_64)
     LOCAL_MULTILIB := both
     include art/build/Android.libcxx.mk
     include $(BUILD_EXECUTABLE)
     
-    ART_TARGET_GTEST_EXECUTABLES$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_NATIVETEST_OUT)/$$(LOCAL_MODULE)
+    ART_TARGET_GTEST_EXECUTABLES$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_NATIVETEST_OUT)/$(TARGET_ARCH)/$$(LOCAL_MODULE)
     art_gtest_target := test-art-$$(art_target_or_host)-gtest-$$(art_gtest_name)
 
     ifdef TARGET_2ND_ARCH
       $(call build-art-test-make-target,2ND_)
 
-      ART_TARGET_GTEST_EXECUTABLES$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += $(2ND_ART_NATIVETEST_OUT)/$$(LOCAL_MODULE)
+      ART_TARGET_GTEST_EXECUTABLES$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_NATIVETEST_OUT)/$(TARGET_2ND_ARCH)/$$(LOCAL_MODULE)
 
       # Bind the primary to the non-suffix rule
       ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
diff --git a/build/Android.libarttest.mk b/build/Android.libarttest.mk
index 18d321a..e2c9864 100644
--- a/build/Android.libarttest.mk
+++ b/build/Android.libarttest.mk
@@ -20,6 +20,11 @@
 	test/StackWalk/stack_walk_jni.cc \
 	test/UnsafeTest/unsafe_test.cc
 
+ART_TARGET_LIBARTTEST_$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TEST_OUT)/$(TARGET_ARCH)/libarttest.so
+ifdef TARGET_2ND_ARCH
+  ART_TARGET_LIBARTTEST_$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TEST_OUT)/$(TARGET_2ND_ARCH)/libarttest.so
+endif
+
 # $(1): target or host
 define build-libarttest
   ifneq ($(1),target)
@@ -48,8 +53,8 @@
     LOCAL_SHARED_LIBRARIES += libdl libcutils
     LOCAL_STATIC_LIBRARIES := libgtest
     LOCAL_MULTILIB := both
-    LOCAL_MODULE_PATH_32 := $(ART_BASE_TEST_OUT)
-    LOCAL_MODULE_PATH_64 := $(ART_BASE_TEST_OUT)64
+    LOCAL_MODULE_PATH_32 := $(ART_TEST_OUT)/$(ART_TARGET_ARCH_32)
+    LOCAL_MODULE_PATH_64 := $(ART_TEST_OUT)/$(ART_TARGET_ARCH_64)
     LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
     include art/build/Android.libcxx.mk
     include $(BUILD_SHARED_LIBRARY)
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index 9d7579d..8240ece 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -29,17 +29,25 @@
 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_DIR)/core.oat
-2ND_TARGET_CORE_OAT := $(2ND_ART_TEST_DIR)/core.oat
+HOST_CORE_OAT := $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/core.oat
+TARGET_CORE_OAT := $(ART_TEST_DIR)/$(DEX2OAT_TARGET_ARCH)/core.oat
+ifdef TARGET_2ND_ARCH
+2ND_TARGET_CORE_OAT := $(2ND_ART_TEST_DIR)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.oat
+endif
 
-HOST_CORE_OAT_OUT := $(HOST_OUT_JAVA_LIBRARIES)/core.oat
-TARGET_CORE_OAT_OUT := $(ART_TEST_OUT)/core.oat
-2ND_TARGET_CORE_OAT_OUT := $(2ND_ART_TEST_OUT)/core.oat
+HOST_CORE_OAT_OUT := $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/core.oat
+TARGET_CORE_OAT_OUT := $(ART_TEST_OUT)/$(DEX2OAT_TARGET_ARCH)/core.oat
+ifdef TARGET_2ND_ARCH
+2ND_TARGET_CORE_OAT_OUT := $(ART_TEST_OUT)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.oat
+endif
 
-HOST_CORE_IMG_OUT := $(HOST_OUT_JAVA_LIBRARIES)/core.art
-TARGET_CORE_IMG_OUT := $(ART_TEST_OUT)/core.art
-2ND_TARGET_CORE_IMG_OUT := $(2ND_ART_TEST_OUT)/core.art
+HOST_CORE_IMG_OUT := $(HOST_OUT_JAVA_LIBRARIES)/$(ART_HOST_ARCH)/core.art
+TARGET_CORE_IMG_OUT := $(ART_TEST_OUT)/$(DEX2OAT_TARGET_ARCH)/core.art
+ifdef TARGET_2ND_ARCH
+2ND_TARGET_CORE_IMG_OUT := $(ART_TEST_OUT)/$($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)/core.art
+endif
+
+HOST_CORE_IMG_LOCATION := $(realpath $(HOST_OUT_JAVA_LIBRARIES))/core.art
 
 TARGET_INSTRUCTION_SET_FEATURES := $(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES)
 
diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc
index 864dadc..dd7ef2a 100644
--- a/compiler/elf_writer_test.cc
+++ b/compiler/elf_writer_test.cc
@@ -50,12 +50,9 @@
     CHECK(host_dir != NULL);
     elf_filename = StringPrintf("%s/framework/core.oat", host_dir);
   } else {
-#ifdef __LP64__
-    elf_filename = "/data/art-test64/core.oat";
-#else
     elf_filename = "/data/art-test/core.oat";
-#endif
   }
+  elf_filename = GetSystemImageFilename(elf_filename.c_str(), kRuntimeISA);
   LOG(INFO) << "elf_filename=" << elf_filename;
 
   UnreserveImageSpace();
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 5a79542..0babfe3 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -42,9 +42,23 @@
 };
 
 TEST_F(ImageTest, WriteRead) {
-  // Create a root tmp file, to be the base of the .art and .oat temporary files.
-  ScratchFile tmp;
-  ScratchFile tmp_elf(tmp, "oat");
+  // Create a generic location tmp file, to be the base of the .art and .oat temporary files.
+  ScratchFile location;
+  ScratchFile image_location(location, ".art");
+
+  std::string image_filename(GetSystemImageFilename(image_location.GetFilename().c_str(),
+                                                    kRuntimeISA));
+  size_t pos = image_filename.rfind('/');
+  CHECK_NE(pos, std::string::npos) << image_filename;
+  std::string image_dir(image_filename, 0, pos);
+  int mkdir_result = mkdir(image_dir.c_str(), 0700);
+  CHECK_EQ(0, mkdir_result) << image_dir;
+  ScratchFile image_file(OS::CreateEmptyFile(image_filename.c_str()));
+
+  std::string oat_filename(image_filename, 0, image_filename.size() - 3);
+  oat_filename += "oat";
+  ScratchFile oat_file(OS::CreateEmptyFile(oat_filename.c_str()));
+
   {
     {
       jobject class_loader = NULL;
@@ -68,28 +82,27 @@
                                                 !kIsTargetBuild,
                                                 class_linker->GetBootClassPath(),
                                                 &oat_writer,
-                                                tmp_elf.GetFile());
+                                                oat_file.GetFile());
       ASSERT_TRUE(success);
       timings.EndSplit();
     }
   }
-  // Workound bug that mcld::Linker::emit closes tmp_elf by reopening as tmp_oat.
-  UniquePtr<File> tmp_oat(OS::OpenFileReadWrite(tmp_elf.GetFilename().c_str()));
-  ASSERT_TRUE(tmp_oat.get() != NULL);
+  // Workound bug that mcld::Linker::emit closes oat_file by reopening as dup_oat.
+  UniquePtr<File> dup_oat(OS::OpenFileReadWrite(oat_file.GetFilename().c_str()));
+  ASSERT_TRUE(dup_oat.get() != NULL);
 
-  ScratchFile tmp_image(tmp, "art");
   const uintptr_t requested_image_base = ART_BASE_ADDRESS;
   {
     ImageWriter writer(*compiler_driver_.get());
-    bool success_image = writer.Write(tmp_image.GetFilename(), requested_image_base,
-                                      tmp_oat->GetPath(), tmp_oat->GetPath());
+    bool success_image = writer.Write(image_file.GetFilename(), requested_image_base,
+                                      dup_oat->GetPath(), dup_oat->GetPath());
     ASSERT_TRUE(success_image);
-    bool success_fixup = ElfFixup::Fixup(tmp_oat.get(), writer.GetOatDataBegin());
+    bool success_fixup = ElfFixup::Fixup(dup_oat.get(), writer.GetOatDataBegin());
     ASSERT_TRUE(success_fixup);
   }
 
   {
-    UniquePtr<File> file(OS::OpenFileForReading(tmp_image.GetFilename().c_str()));
+    UniquePtr<File> file(OS::OpenFileForReading(image_file.GetFilename().c_str()));
     ASSERT_TRUE(file.get() != NULL);
     ImageHeader image_header;
     file->ReadFully(&image_header, sizeof(image_header));
@@ -127,7 +140,7 @@
 
   Runtime::Options options;
   std::string image("-Ximage:");
-  image.append(tmp_image.GetFilename());
+  image.append(image_location.GetFilename());
   options.push_back(std::make_pair(image.c_str(), reinterpret_cast<void*>(NULL)));
 
   if (!Runtime::Create(options, false)) {
@@ -166,6 +179,11 @@
     }
     EXPECT_TRUE(Monitor::IsValidLockWord(klass->GetLockWord(false)));
   }
+
+  image_file.Unlink();
+  oat_file.Unlink();
+  int rmdir_result = rmdir(image_dir.c_str());
+  CHECK_EQ(0, rmdir_result);
 }
 
 TEST_F(ImageTest, ImageHeaderIsValid) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 363e8b2..3c620de 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -557,7 +557,7 @@
 
   gc::Heap* heap = Runtime::Current()->GetHeap();
   std::string boot_image_option("--boot-image=");
-  boot_image_option += heap->GetImageSpace()->GetImageFilename();
+  boot_image_option += heap->GetImageSpace()->GetImageLocation();
 
   std::string dex_file_option("--dex-file=");
   dex_file_option += dex_filename;
@@ -915,6 +915,7 @@
 
 const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const char* dex_location,
                                                                 const uint32_t* const dex_location_checksum,
+                                                                InstructionSet isa,
                                                                 std::vector<std::string>* error_msgs) {
   const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location,
                                                                   dex_location_checksum);
@@ -930,8 +931,8 @@
   }
 
   // Look for an existing file next to dex. for example, for
-  // /foo/bar/baz.jar, look for /foo/bar/baz.odex.
-  std::string odex_filename(OatFile::DexFilenameToOdexFilename(dex_location));
+  // /foo/bar/baz.jar, look for /foo/bar/<isa>/baz.odex.
+  std::string odex_filename(DexFilenameToOdexFilename(dex_location, isa));
   bool open_failed;
   std::string error_msg;
   const DexFile* dex_file = VerifyAndOpenDexFileFromOatFile(odex_filename, dex_location,
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index db780d9..22fd668 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -280,6 +280,7 @@
   // does not match the OatFile.
   const DexFile* FindDexFileInOatFileFromDexLocation(const char* location,
                                                      const uint32_t* const location_checksum,
+                                                     InstructionSet isa,
                                                      std::vector<std::string>* error_msgs)
       LOCKS_EXCLUDED(dex_lock_, Locks::mutator_lock_);
 
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index d7a1667..54ef68d 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -75,9 +75,14 @@
     file_.reset(new File(fd, GetFilename()));
   }
 
+  explicit ScratchFile(File* file) {
+    CHECK(file != NULL);
+    filename_ = file->GetPath();
+    file_.reset(file);
+  }
+
   ~ScratchFile() {
-    int unlink_result = unlink(filename_.c_str());
-    CHECK_EQ(0, unlink_result);
+    Unlink();
   }
 
   const std::string& GetFilename() const {
@@ -92,6 +97,14 @@
     return file_->Fd();
   }
 
+  void Unlink() {
+    if (!OS::FileExists(filename_.c_str())) {
+      return;
+    }
+    int unlink_result = unlink(filename_.c_str());
+    CHECK_EQ(0, unlink_result);
+  }
+
  private:
   std::string filename_;
   UniquePtr<File> file_;
@@ -258,11 +271,7 @@
       filename += getenv("ANDROID_HOST_OUT");
       filename += "/framework/";
     } else {
-#ifdef __LP64__
-      filename += "/data/nativetest/art64/";
-#else
       filename += "/data/nativetest/art/";
-#endif
     }
     filename += "art-test-dex-";
     filename += name;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 446f898..2a717cb 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -103,8 +103,11 @@
                                    const InstructionSet image_isa,
                                    std::string* image_filename,
                                    bool *is_system) {
-  if (OS::FileExists(image_location)) {
-    *image_filename = image_location;
+  // image_location = /system/framework/boot.art
+  // system_image_location = /system/framework/<image_isa>/boot.art
+  std::string system_image_filename(GetSystemImageFilename(image_location, image_isa));
+  if (OS::FileExists(system_image_filename.c_str())) {
+    *image_filename = system_image_filename;
     *is_system = true;
     return true;
   }
@@ -113,6 +116,9 @@
 
   // Always set output location even if it does not exist,
   // so that the caller knows where to create the image.
+  //
+  // image_location = /system/framework/boot.art
+  // *image_filename = /data/dalvik-cache/<image_isa>/boot.art
   *image_filename = GetDalvikCacheFilenameOrDie(image_location, dalvik_cache.c_str());
   *is_system = false;
   return OS::FileExists(image_filename->c_str());
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 5353592..27f19a7 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -115,7 +115,9 @@
   if (outputName.c_str() == nullptr) {
     // FindOrCreateOatFileForDexLocation can tolerate a missing dex_location_checksum
     dex_file = linker->FindDexFileInOatFileFromDexLocation(sourceName.c_str(),
-                                                           dex_location_checksum_pointer, &error_msgs);
+                                                           dex_location_checksum_pointer,
+                                                           kRuntimeISA,
+                                                           &error_msgs);
   } else {
     // FindOrCreateOatFileForDexLocation requires the dex_location_checksum
     if (dex_location_checksum_pointer == NULL) {
@@ -387,7 +389,7 @@
   const InstructionSet target_instruction_set = GetInstructionSetFromString(instruction_set);
 
   // Check if we have an odex file next to the dex file.
-  std::string odex_filename(OatFile::DexFilenameToOdexFilename(filename));
+  std::string odex_filename(DexFilenameToOdexFilename(filename, kRuntimeISA));
   std::string error_msg;
   UniquePtr<const OatFile> oat_file(OatFile::Open(odex_filename, odex_filename, NULL, false,
                                                   &error_msg));
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 7976f6a..46a4d53 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -33,17 +33,6 @@
 
 namespace art {
 
-std::string OatFile::DexFilenameToOdexFilename(const std::string& location) {
-  CHECK_GE(location.size(), 4U) << location;  // must be at least .123
-  size_t dot_index = location.size() - 3 - 1;  // 3=dex or zip or apk
-  CHECK_EQ('.', location[dot_index]) << location;
-  std::string odex_location(location);
-  odex_location.resize(dot_index + 1);
-  CHECK_EQ('.', odex_location[odex_location.size()-1]) << location << " " << odex_location;
-  odex_location += "odex";
-  return odex_location;
-}
-
 void OatFile::CheckLocation(const std::string& location) {
   CHECK(!location.empty());
 }
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index e5dc53c..07d70ff 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -37,10 +37,6 @@
 
 class OatFile {
  public:
-  // Returns an .odex file name next adjacent to the dex location.
-  // For example, for "/foo/bar/baz.jar", return "/foo/bar/baz.odex".
-  static std::string DexFilenameToOdexFilename(const std::string& location);
-
   // 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,
diff --git a/runtime/utils.cc b/runtime/utils.cc
index ad0175a..02b955a 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -1204,6 +1204,37 @@
   return StringPrintf("%s/%s", cache_location, cache_file.c_str());
 }
 
+static void InsertIsaDirectory(std::string* filename, const InstructionSet isa) {
+  // in = /foo/bar/baz
+  // out = /foo/bar/<isa>/baz
+  size_t pos = filename->rfind('/');
+  CHECK_NE(pos, std::string::npos) << *filename << " " << isa;
+  filename->insert(pos, "/", 1);
+  filename->insert(pos + 1, GetInstructionSetString(isa));
+}
+
+std::string GetSystemImageFilename(const char* location, const InstructionSet isa) {
+  // location = /system/framework/boot.art
+  // filename = /system/framework/<isa>/boot.art
+  std::string filename(location);
+  InsertIsaDirectory(&filename, isa);
+  return filename;
+}
+
+std::string DexFilenameToOdexFilename(const std::string& location, const InstructionSet isa) {
+  // location = /foo/bar/baz.jar
+  // odex_location = /foo/bar/<isa>/baz.odex
+  CHECK_GE(location.size(), 4U) << location;  // must be at least .123
+  std::string odex_location(location);
+  InsertIsaDirectory(&odex_location, isa);
+  size_t dot_index = odex_location.size() - 3 - 1;  // 3=dex or zip or apk
+  CHECK_EQ('.', odex_location[dot_index]) << location;
+  odex_location.resize(dot_index + 1);
+  CHECK_EQ('.', odex_location[odex_location.size()-1]) << location << " " << odex_location;
+  odex_location += "odex";
+  return odex_location;
+}
+
 bool IsZipMagic(uint32_t magic) {
   return (('P' == ((magic >> 0) & 0xff)) &&
           ('K' == ((magic >> 8) & 0xff)));
diff --git a/runtime/utils.h b/runtime/utils.h
index 14a532e..9de5d23 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -25,6 +25,7 @@
 #include "base/logging.h"
 #include "base/stringprintf.h"
 #include "globals.h"
+#include "instruction_set.h"
 #include "primitive.h"
 
 namespace art {
@@ -402,6 +403,13 @@
 std::string GetDalvikCacheFilenameOrDie(const char* file_location,
                                         const char* cache_location);
 
+// Returns the system location for an image
+std::string GetSystemImageFilename(const char* location, const InstructionSet isa);
+
+// Returns an .odex file name next adjacent to the dex location.
+// For example, for "/foo/bar/baz.jar", return "/foo/bar/<isa>/baz.odex".
+std::string DexFilenameToOdexFilename(const std::string& location, const InstructionSet isa);
+
 // Check whether the given magic matches a known file type.
 bool IsZipMagic(uint32_t magic);
 bool IsDexMagic(uint32_t magic);
diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc
index 8a8834d..4a1e477 100644
--- a/runtime/utils_test.cc
+++ b/runtime/utils_test.cc
@@ -351,6 +351,16 @@
                GetDalvikCacheFilenameOrDie("/system/framework/boot.art", "/foo").c_str());
 }
 
+TEST_F(UtilsTest, GetSystemImageFilename) {
+  EXPECT_STREQ("/system/framework/arm/boot.art",
+               GetSystemImageFilename("/system/framework/boot.art", kArm).c_str());
+}
+
+TEST_F(UtilsTest, DexFilenameToOdexFilename) {
+  EXPECT_STREQ("/foo/bar/arm/baz.odex",
+               DexFilenameToOdexFilename("/foo/bar/baz.jar", kArm).c_str());
+}
+
 TEST_F(UtilsTest, ExecSuccess) {
   std::vector<std::string> command;
   if (kIsTargetBuild) {
diff --git a/test/Android.mk b/test/Android.mk
index 9b79abf..a3aabe6 100644
--- a/test/Android.mk
+++ b/test/Android.mk
@@ -73,7 +73,7 @@
     LOCAL_JAVA_LIBRARIES := $(TARGET_CORE_JARS)
     LOCAL_NO_STANDARD_LIBRARIES := true
     LOCAL_MODULE_PATH := $(3)
-    LOCAL_DEX_PREOPT_IMAGE := $(TARGET_CORE_IMG_OUT)
+    LOCAL_DEX_PREOPT_IMAGE_LOCATION := $(TARGET_CORE_IMG_OUT)
     LOCAL_DEX_PREOPT := false
     LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
     LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
@@ -81,14 +81,6 @@
 
     ART_TEST_TARGET_DEX_FILES += $$(LOCAL_INSTALLED_MODULE)
     ART_TEST_TARGET_DEX_FILES$(ART_PHONY_TEST_TARGET_SUFFIX) += $$(LOCAL_INSTALLED_MODULE)
-
-    ifdef TARGET_2ND_ARCH
-	    ART_TEST_TARGET_DEX_FILES$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += $(4)/$(1)-$(2).jar
-
-      # TODO: make this a simple copy
-$(4)/$(1)-$(2).jar: $(3)/$(1)-$(2).jar $(4)
-	cp $$< $(4)/
-    endif
   endif
 
   ifeq ($(ART_BUILD_HOST),true)
@@ -97,7 +89,7 @@
     LOCAL_SRC_FILES := $(call all-java-files-under, $(2))
     LOCAL_JAVA_LIBRARIES := $(HOST_CORE_JARS)
     LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_DEX_PREOPT_IMAGE := $(HOST_CORE_IMG_OUT)
+    LOCAL_DEX_PREOPT_IMAGE := $(HOST_CORE_IMG_LOCATION)
     LOCAL_DEX_PREOPT := false
     LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
     LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
@@ -105,25 +97,13 @@
     ART_TEST_HOST_DEX_FILES += $$(LOCAL_INSTALLED_MODULE)
   endif
 endef
-$(foreach dir,$(TEST_DEX_DIRECTORIES), $(eval $(call build-art-test-dex,art-test-dex,$(dir),$(ART_NATIVETEST_OUT),$(2ND_ART_NATIVETEST_OUT))))
-$(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval $(call build-art-test-dex,oat-test-dex,$(dir),$(ART_TEST_OUT),$(2ND_ART_TEST_OUT))))
+$(foreach dir,$(TEST_DEX_DIRECTORIES), $(eval $(call build-art-test-dex,art-test-dex,$(dir),$(ART_NATIVETEST_OUT))))
+$(foreach dir,$(TEST_OAT_DIRECTORIES), $(eval $(call build-art-test-dex,oat-test-dex,$(dir),$(ART_TEST_OUT))))
 
 # Used outside the art project to get a list of the current tests
 ART_TEST_DEX_MAKE_TARGETS := $(addprefix art-test-dex-, $(TEST_DEX_DIRECTORIES))
 ART_TEST_OAT_MAKE_TARGETS := $(addprefix oat-test-dex-, $(TEST_OAT_DIRECTORIES))
 
-# Rules to explicitly create 2nd-arch test directories, as we use a "cp" for them
-# instead of BUILD_JAVA_LIBRARY
-ifneq ($(2ND_ART_NATIVETEST_OUT),)
-$(2ND_ART_NATIVETEST_OUT):
-	$(hide) mkdir -p $@
-endif
-
-ifneq ($(2ND_ART_TEST_OUT),)
-$(2ND_ART_TEST_OUT):
-	$(hide) mkdir -p $@
-endif
-
 ########################################################################
 
 ART_TEST_TARGET_OAT_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) :=
@@ -133,12 +113,12 @@
 
 define declare-test-art-oat-targets-impl
 .PHONY: test-art-target-oat-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
-test-art-target-oat-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX): $($(2)ART_TEST_OUT)/oat-test-dex-$(1).jar test-art-target-sync
-	adb shell touch $($(2)ART_TEST_DIR)/test-art-target-oat-$(1)
-	adb shell rm $($(2)ART_TEST_DIR)/test-art-target-oat-$(1)
-	adb shell sh -c "/system/bin/dalvikvm$($(2)ART_TARGET_BINARY_SUFFIX) $(DALVIKVM_FLAGS) -XXlib:libartd.so -Ximage:$($(2)ART_TEST_DIR)/core.art -classpath $($(2)ART_TEST_DIR)/oat-test-dex-$(1).jar -Djava.library.path=$($(2)ART_TEST_DIR) $(1) && touch $($(2)ART_TEST_DIR)/test-art-target-oat-$(1)"
-	$(hide) (adb pull $($(2)ART_TEST_DIR)/test-art-target-oat-$(1) /tmp/ && echo test-art-target-oat-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX) PASSED) || (echo test-art-target-oat-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX) FAILED && exit 1)
-	$(hide) rm /tmp/test-art-target-oat-$(1)
+test-art-target-oat-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX): $(ART_TEST_OUT)/oat-test-dex-$(1).jar test-art-target-sync
+	adb shell touch $(ART_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@
+	adb shell rm $(ART_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@
+	adb shell sh -c "/system/bin/dalvikvm$($(2)ART_TARGET_BINARY_SUFFIX) $(DALVIKVM_FLAGS) -XXlib:libartd.so -Ximage:$(ART_TEST_DIR)/core.art -classpath $(ART_TEST_DIR)/oat-test-dex-$(1).jar -Djava.library.path=$(ART_TEST_DIR)/$(TARGET_$(2)ARCH) $(1) && touch $(ART_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@"
+	$(hide) (adb pull $(ART_TEST_DIR)/$(TARGET_$(2)ARCH)/$$@ /tmp/ && echo $$@ PASSED) || (echo $$@ FAILED && exit 1)
+	$(hide) rm /tmp/$$@
 endef
 
 # $(1): directory
@@ -155,7 +135,7 @@
   $(call declare-test-art-oat-targets-impl,$(1),)
 
 $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).odex: $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar $(HOST_CORE_IMG_OUT) | $(DEX2OATD)
-	$(DEX2OATD) $(DEX2OAT_FLAGS) --runtime-arg -Xms16m --runtime-arg -Xmx16m --boot-image=$(HOST_CORE_IMG_OUT) --dex-file=$$(realpath $$<) --oat-file=$$(realpath $(HOST_OUT_JAVA_LIBRARIES))/oat-test-dex-$(1).odex --instruction-set=$(ART_HOST_ARCH) --host --android-root=$(HOST_OUT)
+	$(DEX2OATD) $(DEX2OAT_FLAGS) --runtime-arg -Xms16m --runtime-arg -Xmx16m --boot-image=$(HOST_CORE_IMG_LOCATION) --dex-file=$$(realpath $$<) --oat-file=$$(realpath $(HOST_OUT_JAVA_LIBRARIES))/oat-test-dex-$(1).odex --instruction-set=$(ART_HOST_ARCH) --host --android-root=$(HOST_OUT)
 
 .PHONY: test-art-host-oat-default-$(1)
 test-art-host-oat-default-$(1): $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).odex test-art-host-dependencies
@@ -163,7 +143,7 @@
 	ANDROID_DATA=/tmp/android-data/test-art-host-oat-default-$(1) \
 	  ANDROID_ROOT=$(HOST_OUT) \
 	  LD_LIBRARY_PATH=$(HOST_OUT_SHARED_LIBRARIES) \
-	  $(HOST_OUT_EXECUTABLES)/dalvikvm $(DALVIKVM_FLAGS) -XXlib:libartd.so -Ximage:$$(realpath $(HOST_CORE_IMG_OUT)) -classpath $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar -Djava.library.path=$(HOST_OUT_SHARED_LIBRARIES) $(1) $(2) \
+	  $(HOST_OUT_EXECUTABLES)/dalvikvm $(DALVIKVM_FLAGS) -XXlib:libartd.so -Ximage:$(HOST_CORE_IMG_LOCATION) -classpath $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar -Djava.library.path=$(HOST_OUT_SHARED_LIBRARIES) $(1) $(2) \
           && echo test-art-host-oat-default-$(1) PASSED || (echo test-art-host-oat-default-$(1) FAILED && exit 1)
 	$(hide) rm -r /tmp/android-data/test-art-host-oat-default-$(1)
 
@@ -173,7 +153,7 @@
 	ANDROID_DATA=/tmp/android-data/test-art-host-oat-interpreter-$(1) \
 	  ANDROID_ROOT=$(HOST_OUT) \
 	  LD_LIBRARY_PATH=$(HOST_OUT_SHARED_LIBRARIES) \
-	  $(HOST_OUT_EXECUTABLES)/dalvikvm -XXlib:libartd.so -Ximage:$$(realpath $(HOST_CORE_IMG_OUT)) -Xint -classpath $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar -Djava.library.path=$(HOST_OUT_SHARED_LIBRARIES) $(1) $(2) \
+	  $(HOST_OUT_EXECUTABLES)/dalvikvm -XXlib:libartd.so -Ximage:$(HOST_CORE_IMG_LOCATION) -Xint -classpath $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar -Djava.library.path=$(HOST_OUT_SHARED_LIBRARIES) $(1) $(2) \
           && echo test-art-host-oat-interpreter-$(1) PASSED || (echo test-art-host-oat-interpreter-$(1) FAILED && exit 1)
 	$(hide) rm -r /tmp/android-data/test-art-host-oat-interpreter-$(1)
 
diff --git a/test/run-test b/test/run-test
index 1c5904f..323f846 100755
--- a/test/run-test
+++ b/test/run-test
@@ -190,7 +190,7 @@
         fi
         run_args="${run_args} --boot -Ximage:${ANDROID_HOST_OUT}/framework/core.art"
     else
-        run_args="${run_args} --boot -Ximage:/data/art-test${suffix64}/core.art"
+        run_args="${run_args} --boot -Ximage:/data/art-test/core.art"
     fi
 fi