Merge "Revert "Revert "Use LIRSlowPath for throwing ArrayOutOfBoundsException."""
diff --git a/Android.mk b/Android.mk
index 6139cb9..4351be9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -99,6 +99,8 @@
 include $(art_path)/tools/Android.mk
 include $(art_build_path)/Android.oat.mk
 
+
+
 # ART_HOST_DEPENDENCIES depends on Android.executable.mk above for ART_HOST_EXECUTABLES
 ART_HOST_DEPENDENCIES := $(ART_HOST_EXECUTABLES) $(HOST_OUT_JAVA_LIBRARIES)/core-libart-hostdex.jar
 ART_HOST_DEPENDENCIES += $(HOST_OUT_SHARED_LIBRARIES)/libjavacore$(ART_HOST_SHLIB_EXTENSION)
@@ -110,11 +112,18 @@
 include $(art_path)/test/Android.mk
 include $(art_build_path)/Android.gtest.mk
 
+$(eval $(call combine-art-multi-target-var,ART_TARGET_GTEST_TARGETS))
+$(eval $(call combine-art-multi-target-var,ART_TARGET_GTEST_EXECUTABLES))
+
 # The ART_*_TEST_DEPENDENCIES definitions:
 # - depend on Android.oattest.mk above for ART_TEST_*_DEX_FILES
 # - depend on Android.gtest.mk above for ART_*_GTEST_EXECUTABLES
 ART_HOST_TEST_DEPENDENCIES   := $(ART_HOST_DEPENDENCIES)   $(ART_HOST_GTEST_EXECUTABLES)   $(ART_TEST_HOST_DEX_FILES)   $(HOST_CORE_IMG_OUT)
-ART_TARGET_TEST_DEPENDENCIES := $(ART_TARGET_DEPENDENCIES) $(ART_TARGET_GTEST_EXECUTABLES) $(ART_TEST_TARGET_DEX_FILES) $(TARGET_CORE_IMG_OUT)
+
+define declare-art-target-test-dependencies-var
+ART_TARGET_TEST_DEPENDENCIES$(1) := $(ART_TARGET_DEPENDENCIES) $(ART_TARGET_GTEST_EXECUTABLES$(1)) $(ART_TEST_TARGET_DEX_FILES$(1)) $(TARGET_CORE_IMG_OUT$(1))
+endef
+$(eval $(call call-art-multi-target-var,declare-art-target-test-dependencies-var,ART_TARGET_TEST_DEPENDENCIES))
 
 include $(art_build_path)/Android.libarttest.mk
 
@@ -209,46 +218,70 @@
 # target test targets
 
 # "mm test-art-target" to build and run all target tests
-.PHONY: test-art-target
-test-art-target: test-art-target-gtest test-art-target-oat test-art-target-run-test
-	@echo test-art-target PASSED
+define declare-test-art-target
+.PHONY: test-art-target$(1)
+test-art-target$(1): test-art-target-gtest$(1) test-art-target-oat$(1) test-art-target-run-test$(1)
+	@echo test-art-target$(1) PASSED
+endef
+$(eval $(call call-art-multi-target-rule,declare-test-art-target,test-art-target))
 
-.PHONY: test-art-target-dependencies
-test-art-target-dependencies: $(ART_TARGET_TEST_DEPENDENCIES) $(ART_TEST_OUT)/libarttest.so
+
+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
+endef
+$(eval $(call call-art-multi-target-rule,declare-test-art-target-dependencies,test-art-target-dependencies))
+
 
 .PHONY: test-art-target-sync
-test-art-target-sync: test-art-target-dependencies
+test-art-target-sync: test-art-target-dependencies$(ART_PHONY_TEST_TARGET_SUFFIX) test-art-target-dependencies$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
 	adb remount
 	adb sync
 	adb shell mkdir -p $(ART_TEST_DIR)
 
-.PHONY: test-art-target-gtest
-test-art-target-gtest: $(ART_TARGET_GTEST_TARGETS)
 
-.PHONY: test-art-target-oat
-test-art-target-oat: $(ART_TEST_TARGET_OAT_TARGETS)
-	@echo test-art-target-oat PASSED
+define declare-test-art-target-gtest
+.PHONY: test-art-target-gtest$(1)
+test-art-target-gtest$(1): $(ART_TARGET_GTEST_TARGETS$(1))
+	@echo test-art-target-gtest$(1) PASSED
+endef
+$(eval $(call call-art-multi-target-rule,declare-test-art-target-gtest,test-art-target-gtest))
+
+
+define declare-test-art-target-oat
+.PHONY: test-art-target-oat$(1)
+test-art-target-oat$(1): $(ART_TEST_TARGET_OAT_TARGETS$(1))
+	@echo test-art-target-oat$(1) PASSED
+endef
+$(eval $(call call-art-multi-target-rule,declare-test-art-target-oat,test-art-target-oat))
+
 
 define declare-test-art-target-run-test-impl
+$(2)run_test_$(1) :=
+ifeq ($($(2)ART_PHONY_TEST_TARGET_SUFFIX),64)
+ $(2)run_test_$(1) := --64
+endif
 .PHONY: test-art-target-run-test-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX)
 test-art-target-run-test-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX): test-art-target-sync $(DX) $(HOST_OUT_EXECUTABLES)/jasmin
-	DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) art/test/run-test $(DALVIKVM_FLAGS) $(1) $(3)
+	DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) art/test/run-test $(DALVIKVM_FLAGS) $$($(2)run_test_$(1)) $(1)
 	@echo test-art-target-run-test-$(1)$($(2)ART_PHONY_TEST_TARGET_SUFFIX) PASSED
 endef
 
 define declare-test-art-target-run-test
 
   ifdef TARGET_2ND_ARCH
-    $(call declare-test-art-target-run-test-impl,$(1),2ND_,)
+    $(call declare-test-art-target-run-test-impl,$(1),2ND_)
+    
+    TEST_ART_TARGET_RUN_TEST_TARGETS$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += test-art-target-run-test-$(1)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
 
     ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
       # Link primary to non-suffix
 test-art-target-run-test-$(1): test-art-target-run-test-$(1)$(ART_PHONY_TEST_TARGET_SUFFIX)
     endif
   endif
-  $(call declare-test-art-target-run-test-impl,$(1),,--$(ART_TARGET_BINARY_SUFFIX))
+  $(call declare-test-art-target-run-test-impl,$(1),)
 
-  TEST_ART_TARGET_RUN_TEST_TARGETS += test-art-target-run-test-$(1)
+  TEST_ART_TARGET_RUN_TEST_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) += test-art-target-run-test-$(1)$(ART_PHONY_TEST_TARGET_SUFFIX)
 
 test-art-run-test-$(1): test-art-host-run-test-$(1) test-art-target-run-test-$(1)
 
@@ -256,9 +289,14 @@
 
 $(foreach test, $(TEST_ART_RUN_TESTS), $(eval $(call declare-test-art-target-run-test,$(test))))
 
-.PHONY: test-art-target-run-test
-test-art-target-run-test: $(TEST_ART_TARGET_RUN_TEST_TARGETS)
-	@echo test-art-target-run-test PASSED
+
+define declare-test-art-target-run-test
+.PHONY: test-art-target-run-test$(1)
+test-art-target-run-test$(1): $(TEST_ART_TARGET_RUN_TEST_TARGETS$(1))
+	@echo test-art-target-run-test$(1) PASSED
+endef
+$(eval $(call call-art-multi-target-rule,declare-test-art-target-run-test,test-art-target-run-test))
+
 
 ########################################################################
 # oat-target and oat-target-sync targets
@@ -286,7 +324,12 @@
 
 $$(OUT_OAT_FILE): $(PRODUCT_OUT)/$(1) $(DEFAULT_DEX_PREOPT_BUILT_IMAGE) $(DEX2OATD_DEPENDENCY)
 	@mkdir -p $$(dir $$@)
-	$(DEX2OATD) --runtime-arg -Xms64m --runtime-arg -Xmx64m --boot-image=$(DEFAULT_DEX_PREOPT_BUILT_IMAGE) --dex-file=$(PRODUCT_OUT)/$(1) --dex-location=/$(1) --oat-file=$$@ --instruction-set=$(TARGET_ARCH) --instruction-set-features=$(TARGET_INSTRUCTION_SET_FEATURES) --android-root=$(PRODUCT_OUT)/system
+	$(DEX2OATD) --runtime-arg -Xms64m --runtime-arg -Xmx64m \
+		--boot-image=$(DEFAULT_DEX_PREOPT_BUILT_IMAGE) --dex-file=$(PRODUCT_OUT)/$(1) \
+		--dex-location=/$(1) --oat-file=$$@ \
+		--instruction-set=$(DEX2OAT_TARGET_ARCH) \
+		--instruction-set-features=$(DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
+		--android-root=$(PRODUCT_OUT)/system
 
 endif
 
diff --git a/build/Android.common.mk b/build/Android.common.mk
index b9a297b..c95b1c6 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -291,4 +291,71 @@
   ART_BUILD_DEBUG := true
 endif
 
+# Helper function to call a function twice with a target suffix
+# $(1): The generator function for the rules
+#         Has one argument, the suffix
+define call-art-multi-target
+  $(call $(1),$(ART_PHONY_TEST_TARGET_SUFFIX))
+  
+  ifdef TARGET_2ND_ARCH
+    $(call $(1),$(2ND_ART_PHONY_TEST_TARGET_SUFFIX))
+  endif
+endef
+
+# Helper function to combine two variables with suffixes together.
+# $(1): The base name.
+define combine-art-multi-target-var
+  ifdef TARGET_2ND_ARCH
+    ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
+      ifneq ($(2ND_ART_PHONY_TEST_TARGET_SUFFIX),)
+$(1) := $($(1)$(ART_PHONY_TEST_TARGET_SUFFIX)) $($(1)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX))
+      endif
+    endif
+  endif
+endef
+
+
+# Helper function to define a variable twice with a target suffix. Assume the name generated is
+# derived from $(2) so we can create a combined var.
+# $(1): The generator function for the rules
+#         Has one argument, the suffix
+define call-art-multi-target-var
+  $(call $(1),$(ART_PHONY_TEST_TARGET_SUFFIX))
+  
+  ifdef TARGET_2ND_ARCH
+    $(call $(1),$(2ND_ART_PHONY_TEST_TARGET_SUFFIX))
+    
+    # Link both together, if it makes sense
+    ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
+      ifneq ($(2ND_ART_PHONY_TEST_TARGET_SUFFIX),)
+$(2) := $(2)$(ART_PHONY_TEST_TARGET_SUFFIX) $(2)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+      endif
+    endif
+
+  endif
+endef
+
+# Helper function to call a function twice with a target suffix. Assume it generates make rules
+# with the given name, and link them.
+# $(1): The generator function for the rules
+#         Has one argument, the suffix
+# $(2): The base rule name, necessary for the link
+#       We assume we can link the names together easily...
+define call-art-multi-target-rule
+  $(call $(1),$(ART_PHONY_TEST_TARGET_SUFFIX))
+  
+  ifdef TARGET_2ND_ARCH
+    $(call $(1),$(2ND_ART_PHONY_TEST_TARGET_SUFFIX))
+  
+    # Link both together, if it makes sense
+    ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
+      ifneq ($(2ND_ART_PHONY_TEST_TARGET_SUFFIX),)
+.PHONY: $(2)
+$(2): $(2)$(ART_PHONY_TEST_TARGET_SUFFIX) $(2)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+      endif
+    endif
+  endif
+endef
+
+
 endif # ANDROID_COMMON_MK
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index b6e6fac..4b655b5 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -105,10 +105,12 @@
 	compiler/utils/x86/assembler_x86_test.cc
 
 ART_HOST_GTEST_EXECUTABLES :=
-ART_TARGET_GTEST_EXECUTABLES :=
+ART_TARGET_GTEST_EXECUTABLES$(ART_PHONY_TEST_TARGET_SUFFIX) :=
+ART_TARGET_GTEST_EXECUTABLES$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) :=
 ART_HOST_GTEST_TARGETS :=
 ART_HOST_VALGRIND_GTEST_TARGETS :=
-ART_TARGET_GTEST_TARGETS :=
+ART_TARGET_GTEST_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) :=
+ART_TARGET_GTEST_TARGETS$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) :=
 
 ART_TEST_CFLAGS :=
 ifeq ($(ART_USE_PORTABLE_COMPILER),true)
@@ -127,7 +129,7 @@
 	$(hide) (adb pull $($(1)ART_TEST_DIR)/$$@ /tmp/ && echo $$@ PASSED) || (echo $$@ FAILED && exit 1)
 	$(hide) rm /tmp/$$@
 
-    ART_TARGET_GTEST_TARGETS += $$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX)
+  ART_TARGET_GTEST_TARGETS$($(1)ART_PHONY_TEST_TARGET_SUFFIX) += $$(art_gtest_target)$($(1)ART_PHONY_TEST_TARGET_SUFFIX)
 endef
 
 
@@ -182,12 +184,15 @@
     LOCAL_MULTILIB := both
     include art/build/Android.libcxx.mk
     include $(BUILD_EXECUTABLE)
-    ART_TARGET_GTEST_EXECUTABLES += $$(art_gtest_exe)
+    
+    ART_TARGET_GTEST_EXECUTABLES$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_NATIVETEST_OUT)/$$(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)
+
       # Bind the primary to the non-suffix rule
       ifneq ($(ART_PHONY_TEST_TARGET_SUFFIX),)
 $$(art_gtest_target): $$(art_gtest_target)$(ART_PHONY_TEST_TARGET_SUFFIX)
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index cb45a85..9d7579d 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -63,6 +63,9 @@
 		--oat-location=$$($(1)TARGET_CORE_OAT) --image=$$($(1)TARGET_CORE_IMG_OUT) --base=$$(LIBART_IMG_TARGET_BASE_ADDRESS) \
 		--instruction-set=$$($(1)TARGET_ARCH) --instruction-set-features=$$(TARGET_INSTRUCTION_SET_FEATURES) --android-root=$$(PRODUCT_OUT)/system
 
+# This "renaming" eases declaration in art/Android.mk
+TARGET_CORE_IMG_OUT$($(1)ART_PHONY_TEST_TARGET_SUFFIX) := $($(1)TARGET_CORE_IMG_OUT)
+
 $$($(1)TARGET_CORE_OAT_OUT): $$($(1)TARGET_CORE_IMG_OUT)
 endef
 
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 1bf5fce..ed2ecac 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -181,6 +181,17 @@
         (cu.enable_debug & (1 << kDebugVerbose));
   }
 
+  if (gVerboseMethods.size() != 0) {
+    cu.verbose = false;
+    for (size_t i = 0; i < gVerboseMethods.size(); ++i) {
+      if (PrettyMethod(method_idx, dex_file).find(gVerboseMethods[i])
+          != std::string::npos) {
+        cu.verbose = true;
+        break;
+      }
+    }
+  }
+
   /*
    * TODO: rework handling of optimization and debug flags.  Should we split out
    * MIR and backend flags?  Need command-line setting as well.
diff --git a/runtime/base/logging.cc b/runtime/base/logging.cc
index 46b8ff2..730a2c2 100644
--- a/runtime/base/logging.cc
+++ b/runtime/base/logging.cc
@@ -26,6 +26,8 @@
 
 LogVerbosity gLogVerbosity;
 
+std::vector<std::string> gVerboseMethods;
+
 unsigned int gAborting = 0;
 
 static LogSeverity gMinimumLogSeverity = INFO;
diff --git a/runtime/base/logging.h b/runtime/base/logging.h
index fcec733..bd5ae85 100644
--- a/runtime/base/logging.h
+++ b/runtime/base/logging.h
@@ -22,6 +22,7 @@
 #include <iostream>  // NOLINT
 #include <sstream>
 #include <signal.h>
+#include <vector>
 #include "base/macros.h"
 #include "log_severity.h"
 #include "UniquePtr.h"
@@ -299,6 +300,8 @@
 
 extern LogVerbosity gLogVerbosity;
 
+extern std::vector<std::string> gVerboseMethods;
+
 // Used on fatal exit. Prevents recursive aborts. Allows us to disable
 // some error checking to ensure fatal shutdown makes forward progress.
 extern unsigned int gAborting;
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 57d32bb..084e8f6 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -251,7 +251,7 @@
       // TODO: support -Djava.class.path
       i++;
       if (i == options.size()) {
-        Usage("Missing required class path value for %s", option.c_str());
+        Usage("Missing required class path value for %s\n", option.c_str());
         return false;
       }
       const StringPiece& value = options[i].first;
@@ -279,35 +279,35 @@
     } else if (StartsWith(option, "-Xms")) {
       size_t size = ParseMemoryOption(option.substr(strlen("-Xms")).c_str(), 1024);
       if (size == 0) {
-        Usage("Failed to parse memory option %s", option.c_str());
+        Usage("Failed to parse memory option %s\n", option.c_str());
         return false;
       }
       heap_initial_size_ = size;
     } else if (StartsWith(option, "-Xmx")) {
       size_t size = ParseMemoryOption(option.substr(strlen("-Xmx")).c_str(), 1024);
       if (size == 0) {
-        Usage("Failed to parse memory option %s", option.c_str());
+        Usage("Failed to parse memory option %s\n", option.c_str());
         return false;
       }
       heap_maximum_size_ = size;
     } else if (StartsWith(option, "-XX:HeapGrowthLimit=")) {
       size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapGrowthLimit=")).c_str(), 1024);
       if (size == 0) {
-        Usage("Failed to parse memory option %s", option.c_str());
+        Usage("Failed to parse memory option %s\n", option.c_str());
         return false;
       }
       heap_growth_limit_ = size;
     } else if (StartsWith(option, "-XX:HeapMinFree=")) {
       size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapMinFree=")).c_str(), 1024);
       if (size == 0) {
-        Usage("Failed to parse memory option %s", option.c_str());
+        Usage("Failed to parse memory option %s\n", option.c_str());
         return false;
       }
       heap_min_free_ = size;
     } else if (StartsWith(option, "-XX:HeapMaxFree=")) {
       size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapMaxFree=")).c_str(), 1024);
       if (size == 0) {
-        Usage("Failed to parse memory option %s", option.c_str());
+        Usage("Failed to parse memory option %s\n", option.c_str());
         return false;
       }
       heap_max_free_ = size;
@@ -316,7 +316,7 @@
         return false;
       }
     } else if (StartsWith(option, "-XX:ForegroundHeapGrowthMultiplier=")) {
-      if (!ParseDouble(option, '=', 0.1, 0.9, &foreground_heap_growth_multiplier_)) {
+      if (!ParseDouble(option, '=', 0.1, 10.0, &foreground_heap_growth_multiplier_)) {
         return false;
       }
     } else if (StartsWith(option, "-XX:ParallelGCThreads=")) {
@@ -330,7 +330,7 @@
     } else if (StartsWith(option, "-Xss")) {
       size_t size = ParseMemoryOption(option.substr(strlen("-Xss")).c_str(), 1);
       if (size == 0) {
-        Usage("Failed to parse memory option %s", option.c_str());
+        Usage("Failed to parse memory option %s\n", option.c_str());
         return false;
       }
       stack_size_ = size;
@@ -398,7 +398,7 @@
                    (gc_option == "noverifycardtable")) {
           // Ignored for backwards compatibility.
         } else {
-          Usage("Unknown -Xgc option %s", gc_option.c_str());
+          Usage("Unknown -Xgc option %s\n", gc_option.c_str());
           return false;
         }
       }
@@ -411,7 +411,7 @@
       if (collector_type != gc::kCollectorTypeNone) {
         background_collector_type_ = collector_type;
       } else {
-        Usage("Unknown -XX:BackgroundGC option %s", substring.c_str());
+        Usage("Unknown -XX:BackgroundGC option %s\n", substring.c_str());
         return false;
       }
     } else if (option == "-XX:+DisableExplicitGC") {
@@ -443,10 +443,13 @@
         } else if (verbose_options[i] == "threads") {
           gLogVerbosity.threads = true;
         } else {
-          Usage("Unknown -verbose option %s", verbose_options[i].c_str());
+          Usage("Unknown -verbose option %s\n", verbose_options[i].c_str());
           return false;
         }
       }
+    } else if (StartsWith(option, "-verbose-methods:")) {
+      gLogVerbosity.compiler = false;
+      Split(option.substr(strlen("-verbose-methods:")), ',', gVerboseMethods);
     } else if (StartsWith(option, "-Xlockprofthreshold:")) {
       if (!ParseUnsignedInteger(option, ':', &lock_profiling_threshold_)) {
         return false;
@@ -476,7 +479,7 @@
     } else if (option == "abort") {
       const void* hook = options[i].second;
       if (hook == nullptr) {
-        Usage("abort was NULL");
+        Usage("abort was NULL\n");
         return false;
       }
       hook_abort_ = reinterpret_cast<void(*)()>(const_cast<void*>(hook));
@@ -568,14 +571,14 @@
     } else if (option == "-Xcompiler-option") {
       i++;
       if (i == options.size()) {
-        Usage("Missing required compiler option for %s", option.c_str());
+        Usage("Missing required compiler option for %s\n", option.c_str());
         return false;
       }
       compiler_options_.push_back(options[i].first);
     } else if (option == "-Ximage-compiler-option") {
       i++;
       if (i == options.size()) {
-        Usage("Missing required compiler option for %s", option.c_str());
+        Usage("Missing required compiler option for %s\n", option.c_str());
         return false;
       }
       image_compiler_options_.push_back(options[i].first);
@@ -586,7 +589,7 @@
       } else if (verify_mode == "remote" || verify_mode == "all") {
         verify_ = true;
       } else {
-        Usage("Unknown -Xverify option %s", verify_mode.c_str());
+        Usage("Unknown -Xverify option %s\n", verify_mode.c_str());
         return false;
       }
     } else if (StartsWith(option, "-ea") ||
@@ -626,7 +629,7 @@
                StartsWith(option, "-XX:mainThreadStackSize=")) {
       // Ignored for backwards compatibility.
     } else if (!ignore_unrecognized) {
-      Usage("Unrecognized option %s", option.c_str());
+      Usage("Unrecognized option %s\n", option.c_str());
       return false;
     }
   }
@@ -717,6 +720,7 @@
   UsageMessage(stream, "  -XX:HeapMinFree=N\n");
   UsageMessage(stream, "  -XX:HeapMaxFree=N\n");
   UsageMessage(stream, "  -XX:HeapTargetUtilization=doublevalue\n");
+  UsageMessage(stream, "  -XX:ForegroundHeapGrowthMultiplier=doublevalue\n");
   UsageMessage(stream, "  -XX:LowMemoryMode\n");
   UsageMessage(stream, "  -Xprofile:{threadcpuclock,wallclock,dualclock}\n");
   UsageMessage(stream, "\n");
@@ -789,7 +793,7 @@
 bool ParsedOptions::ParseStringAfterChar(const std::string& s, char c, std::string* parsed_value) {
   std::string::size_type colon = s.find(c);
   if (colon == std::string::npos) {
-    Usage("Missing char %c in option %s", c, s.c_str());
+    Usage("Missing char %c in option %s\n", c, s.c_str());
     return false;
   }
   // Add one to remove the char we were trimming until.
@@ -800,14 +804,14 @@
 bool ParsedOptions::ParseInteger(const std::string& s, char after_char, int* parsed_value) {
   std::string::size_type colon = s.find(after_char);
   if (colon == std::string::npos) {
-    Usage("Missing char %c in option %s", after_char, s.c_str());
+    Usage("Missing char %c in option %s\n", after_char, s.c_str());
     return false;
   }
   const char* begin = &s[colon + 1];
   char* end;
   size_t result = strtoul(begin, &end, 10);
   if (begin == end || *end != '\0') {
-    Usage("Failed to parse integer from %s ", s.c_str());
+    Usage("Failed to parse integer from %s\n", s.c_str());
     return false;
   }
   *parsed_value = result;
@@ -821,7 +825,7 @@
     return false;
   }
   if (i < 0) {
-    Usage("Negative value %d passed for unsigned option %s", i, s.c_str());
+    Usage("Negative value %d passed for unsigned option %s\n", i, s.c_str());
     return false;
   }
   *parsed_value = i;
@@ -840,7 +844,7 @@
   // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
   const bool sane_val = iss.eof() && (value >= min) && (value <= max);
   if (!sane_val) {
-    Usage("Invalid double value %s for option %s", option.c_str());
+    Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
     return false;
   }
   *parsed_value = value;
diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc
index da1b2ca..960d332 100644
--- a/runtime/runtime_linux.cc
+++ b/runtime/runtime_linux.cc
@@ -33,7 +33,7 @@
 
 struct Backtrace {
   void Dump(std::ostream& os) {
-    DumpNativeStack(os, GetTid(), "\t", true);
+    DumpNativeStack(os, GetTid(), "\t");
   }
 };
 
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 8691dec..3408dd3 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -939,7 +939,7 @@
     if (dump_for_abort || ShouldShowNativeStack(this)) {
       DumpKernelStack(os, GetTid(), "  kernel: ", false);
       SirtRef<mirror::ArtMethod> method_ref(Thread::Current(), GetCurrentMethod(nullptr));
-      DumpNativeStack(os, GetTid(), "  native: ", false, method_ref.get());
+      DumpNativeStack(os, GetTid(), "  native: ", method_ref.get());
     }
     DumpJavaStack(os);
   } else {
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 270deb0..6f93566 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -78,7 +78,7 @@
   MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
   for (const auto& thread : list_) {
     os << "DUMPING THREAD " << thread->GetTid() << "\n";
-    DumpNativeStack(os, thread->GetTid(), "\t", true);
+    DumpNativeStack(os, thread->GetTid(), "\t");
     os << "\n";
   }
 }
@@ -99,7 +99,7 @@
   // TODO: Reenable this when the native code in system_server can handle it.
   // Currently "adb shell kill -3 `pid system_server`" will cause it to exit.
   if (false) {
-    DumpNativeStack(os, tid, "  native: ", false);
+    DumpNativeStack(os, tid, "  native: ");
   }
   os << "\n";
 }
diff --git a/runtime/utils.cc b/runtime/utils.cc
index afbcbb7..c4d1a78 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -1041,20 +1041,7 @@
   return "";
 }
 
-static std::string CleanMapName(const backtrace_map_t* map) {
-  if (map == NULL || map->name.empty()) {
-    return "???";
-  }
-  // Turn "/usr/local/google/home/enh/clean-dalvik-dev/out/host/linux-x86/lib/libartd.so"
-  // into "libartd.so".
-  size_t last_slash = map->name.rfind('/');
-  if (last_slash == std::string::npos) {
-    return map->name;
-  }
-  return map->name.substr(last_slash + 1);
-}
-
-void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix, bool include_count,
+void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix,
     mirror::ArtMethod* current_method) {
   // We may be called from contexts where current_method is not null, so we must assert this.
   if (current_method != nullptr) {
@@ -1072,27 +1059,34 @@
   for (Backtrace::const_iterator it = backtrace->begin();
        it != backtrace->end(); ++it) {
     // We produce output like this:
-    // ]    #00 unwind_backtrace_thread+536 [0x55d75bb8] (libbacktrace.so)
-    os << prefix;
-    if (include_count) {
-      os << StringPrintf("#%02zu ", it->num);
-    }
-    if (!it->func_name.empty()) {
-      os << it->func_name;
+    // ]    #00 pc 000075bb8  /system/lib/libc.so (unwind_backtrace_thread+536)
+    // In order for parsing tools to continue to function, the stack dump
+    // format must at least adhere to this format:
+    //  #XX pc <RELATIVE_ADDR>  <FULL_PATH_TO_SHARED_LIBRARY> ...
+    // The parsers require a single space before and after pc, and two spaces
+    // after the <RELATIVE_ADDR>. There can be any prefix data before the
+    // #XX. <RELATIVE_ADDR> has to be a hex number but with no 0x prefix.
+    os << prefix << StringPrintf("#%02zu pc ", it->num);
+    if (!it->map) {
+      os << StringPrintf("%08" PRIxPTR "  ???", it->pc);
     } else {
-      if (current_method != nullptr && current_method->IsWithinQuickCode(it->pc)) {
+      os << StringPrintf("%08" PRIxPTR "  ", it->pc - it->map->start)
+         << it->map->name << " (";
+      if (!it->func_name.empty()) {
+        os << it->func_name;
+        if (it->func_offset != 0) {
+          os << "+" << it->func_offset;
+        }
+      } else if (current_method != nullptr && current_method->IsWithinQuickCode(it->pc)) {
         const void* start_of_code = current_method->GetEntryPointFromQuickCompiledCode();
         os << JniLongName(current_method) << "+"
            << (it->pc - reinterpret_cast<uintptr_t>(start_of_code));
       } else {
         os << "???";
       }
+      os << ")";
     }
-    if (it->func_offset != 0) {
-      os << "+" << it->func_offset;
-    }
-    os << StringPrintf(" [%p]", reinterpret_cast<void*>(it->pc));
-    os << " (" << CleanMapName(it->map) << ")\n";
+    os << "\n";
   }
 }
 
diff --git a/runtime/utils.h b/runtime/utils.h
index 5def66b..6ab1013 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -382,7 +382,7 @@
 
 // Dumps the native stack for thread 'tid' to 'os'.
 void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix = "",
-    bool include_count = true, mirror::ArtMethod* current_method = nullptr)
+    mirror::ArtMethod* current_method = nullptr)
     NO_THREAD_SAFETY_ANALYSIS;
 
 // Dumps the kernel stack for thread 'tid' to 'os'. Note that this is only available on linux-x86.
diff --git a/test/Android.mk b/test/Android.mk
index 334df1f..08a925c 100644
--- a/test/Android.mk
+++ b/test/Android.mk
@@ -57,6 +57,8 @@
 #	StackWalk2 \
 
 ART_TEST_TARGET_DEX_FILES :=
+ART_TEST_TARGET_DEX_FILES$(ART_PHONY_TEST_TARGET_SUFFIX) :=
+ART_TEST_TARGET_DEX_FILES$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) :=
 ART_TEST_HOST_DEX_FILES :=
 
 # $(1): module prefix
@@ -76,13 +78,17 @@
     LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common.mk
     LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
     include $(BUILD_JAVA_LIBRARY)
+    
     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)/$(1)-$(2).jar: $(3)/$(1)-$(2).jar $(4)
 	cp $$< $(4)/
-    endif
+    endif    
   endif
 
   ifeq ($(ART_BUILD_HOST),true)
@@ -102,9 +108,22 @@
 $(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))))
 
+# 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_TEST_TARGET_OAT_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) :=
+ART_TEST_TARGET_OAT_TARGETS$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) :=
 ART_TEST_HOST_OAT_DEFAULT_TARGETS :=
 ART_TEST_HOST_OAT_INTERPRETER_TARGETS :=
 
@@ -160,7 +179,10 @@
 .PHONY: test-art-oat-$(1)
 test-art-oat-$(1): test-art-host-oat-$(1) test-art-target-oat-$(1)
 
-ART_TEST_TARGET_OAT_TARGETS += test-art-target-oat-$(1)
+ART_TEST_TARGET_OAT_TARGETS$(ART_PHONY_TEST_TARGET_SUFFIX) += test-art-target-oat-$(1)$(ART_PHONY_TEST_TARGET_SUFFIX)
+ifdef TARGET_2ND_ARCH
+  ART_TEST_TARGET_OAT_TARGETS$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += test-art-target-oat-$(1)$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)
+endif
 ART_TEST_HOST_OAT_DEFAULT_TARGETS += test-art-host-oat-default-$(1)
 ART_TEST_HOST_OAT_INTERPRETER_TARGETS += test-art-host-oat-interpreter-$(1)
 endef
diff --git a/test/run-test b/test/run-test
index 58de980..6e59641 100755
--- a/test/run-test
+++ b/test/run-test
@@ -68,6 +68,7 @@
 runtime="art"
 usage="no"
 build_only="no"
+suffix64=""
 
 while true; do
     if [ "x$1" = "x--host" ]; then
@@ -154,6 +155,7 @@
         shift
     elif [ "x$1" = "x--64" ]; then
         run_args="${run_args} --64"
+        suffix64="64"
         shift
     elif expr "x$1" : "x--" >/dev/null 2>&1; then
         echo "unknown $0 option: $1" 1>&2
@@ -187,7 +189,7 @@
         fi
         run_args="${run_args} --boot -Ximage:${ANDROID_HOST_OUT}/framework/core.art"
     else
-        run_args="${run_args} --boot -Ximage:/data/art-test/core.art"
+        run_args="${run_args} --boot -Ximage:/data/art-test${suffix64}/core.art"
     fi
 fi