Merge "Log profile info only on debug builds."
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index fbb7eb3..c67a815 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -42,6 +42,11 @@
 
 $(HOST_CORE_OAT_OUT): $(HOST_CORE_IMG_OUT)
 
+IMPLICIT_CHECKS_arm := null,stack
+IMPLICIT_CHECKS_arm64 := none
+IMPLICIT_CHECKS_x86 := none
+IMPLICIT_CHECKS_x86_64 := none
+IMPLICIT_CHECKS_mips := none
 define create-oat-target-targets
 $$($(1)TARGET_CORE_IMG_OUT): $$($(1)TARGET_CORE_DEX_FILES) $$(DEX2OATD_DEPENDENCY)
 	@echo "target dex2oat: $$@ ($$?)"
@@ -49,6 +54,7 @@
 	$$(hide) $$(DEX2OATD) --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=$$($(1)TARGET_CORE_OAT_OUT) \
 		--oat-location=$$($(1)TARGET_CORE_OAT) --image=$$($(1)TARGET_CORE_IMG_OUT) --base=$$(LIBART_IMG_TARGET_BASE_ADDRESS) \
+		--implicit-checks=$(IMPLICIT_CHECKS_$($(1)TARGET_ARCH)) \
 		--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
@@ -58,7 +64,7 @@
 endef
 
 ifdef TARGET_2ND_ARCH
-$(eval $(call create-oat-target-targets,2ND_))
+  $(eval $(call create-oat-target-targets,2ND_))
 endif
 $(eval $(call create-oat-target-targets,))
 
diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc
index 7441dac..f098a34 100644
--- a/compiler/compiled_method.cc
+++ b/compiler/compiled_method.cc
@@ -86,7 +86,11 @@
 }
 
 size_t CompiledCode::CodeDelta() const {
-  switch (instruction_set_) {
+  return CodeDelta(instruction_set_);
+}
+
+size_t CompiledCode::CodeDelta(InstructionSet instruction_set) {
+  switch (instruction_set) {
     case kArm:
     case kArm64:
     case kMips:
@@ -98,7 +102,7 @@
       return 1;
     }
     default:
-      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_;
+      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
       return 0;
   }
 }
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h
index 23cd250..b8cd851 100644
--- a/compiler/compiled_method.h
+++ b/compiler/compiled_method.h
@@ -67,6 +67,7 @@
   // returns the difference between the code address and a usable PC.
   // mainly to cope with kThumb2 where the lower bit must be set.
   size_t CodeDelta() const;
+  static size_t CodeDelta(InstructionSet instruction_set);
 
   // Returns a pointer suitable for invoking the code at the argument
   // code_pointer address.  Mainly to cope with kThumb2 where the
diff --git a/compiler/dex/quick/gen_loadstore.cc b/compiler/dex/quick/gen_loadstore.cc
index 2dd7def..d6f6ea1 100644
--- a/compiler/dex/quick/gen_loadstore.cc
+++ b/compiler/dex/quick/gen_loadstore.cc
@@ -213,11 +213,10 @@
   ResetDefLoc(rl_dest);
   if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
     def_start = last_lir_insn_;
+    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
     if (rl_dest.ref) {
-      ScopedMemRefType mem_ref_type(this, ResourceMask::kHeapRef);
       StoreRefDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
     } else {
-      ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
       Store32Disp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
     }
     MarkClean(rl_dest);
diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc
index 3f54798..f06f08e 100644
--- a/compiler/dex/quick/x86/assemble_x86.cc
+++ b/compiler/dex/quick/x86/assemble_x86.cc
@@ -325,11 +325,21 @@
 { kX86 ## opname ## RM, kRegMem,   IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1,  { prefix, 0, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \
 { kX86 ## opname ## RA, kRegArray, IS_LOAD | IS_QUIN_OP     | reg_def | REG_USE12, { prefix, 0, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RA", "!0r,[!1r+!2r<<!3d+!4d]" }
 
+#define EXT_0F_REX_NO_PREFIX_ENCODING_MAP(opname, opcode, reg_def) \
+{ kX86 ## opname ## RR, kRegReg,             IS_BINARY_OP   | reg_def | REG_USE1,  { REX, 0x00, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RR", "!0r,!1r" }, \
+{ kX86 ## opname ## RM, kRegMem,   IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1,  { REX, 0x00, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \
+{ kX86 ## opname ## RA, kRegArray, IS_LOAD | IS_QUIN_OP     | reg_def | REG_USE12, { REX, 0x00, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RA", "!0r,[!1r+!2r<<!3d+!4d]" }
+
 #define EXT_0F_REX_W_ENCODING_MAP(opname, prefix, opcode, reg_def) \
 { kX86 ## opname ## RR, kRegReg,             IS_BINARY_OP   | reg_def | REG_USE1,  { prefix, REX_W, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RR", "!0r,!1r" }, \
 { kX86 ## opname ## RM, kRegMem,   IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1,  { prefix, REX_W, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \
 { kX86 ## opname ## RA, kRegArray, IS_LOAD | IS_QUIN_OP     | reg_def | REG_USE12, { prefix, REX_W, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RA", "!0r,[!1r+!2r<<!3d+!4d]" }
 
+#define EXT_0F_REX_W_NO_PREFIX_ENCODING_MAP(opname, opcode, reg_def) \
+{ kX86 ## opname ## RR, kRegReg,             IS_BINARY_OP   | reg_def | REG_USE1,  { REX_W, 0x00, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RR", "!0r,!1r" }, \
+{ kX86 ## opname ## RM, kRegMem,   IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1,  { REX_W, 0x00, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \
+{ kX86 ## opname ## RA, kRegArray, IS_LOAD | IS_QUIN_OP     | reg_def | REG_USE12, { REX_W, 0x00, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RA", "!0r,[!1r+!2r<<!3d+!4d]" }
+
 #define EXT_0F_ENCODING2_MAP(opname, prefix, opcode, opcode2, reg_def) \
 { kX86 ## opname ## RR, kRegReg,             IS_BINARY_OP   | reg_def | REG_USE1,  { prefix, 0, 0x0F, opcode, opcode2, 0, 0, 0, false }, #opname "RR", "!0r,!1r" }, \
 { kX86 ## opname ## RM, kRegMem,   IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1,  { prefix, 0, 0x0F, opcode, opcode2, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \
@@ -481,6 +491,10 @@
   EXT_0F_ENCODING_MAP(Movzx16, 0x00, 0xB7, REG_DEF0),
   EXT_0F_ENCODING_MAP(Movsx8,  0x00, 0xBE, REG_DEF0),
   EXT_0F_ENCODING_MAP(Movsx16, 0x00, 0xBF, REG_DEF0),
+  EXT_0F_REX_NO_PREFIX_ENCODING_MAP(Movzx8q, 0xB6, REG_DEF0),
+  EXT_0F_REX_W_NO_PREFIX_ENCODING_MAP(Movzx16q, 0xB7, REG_DEF0),
+  EXT_0F_REX_NO_PREFIX_ENCODING_MAP(Movsx8q, 0xBE, REG_DEF0),
+  EXT_0F_REX_W_NO_PREFIX_ENCODING_MAP(Movsx16q, 0xBF, REG_DEF0),
 #undef EXT_0F_ENCODING_MAP
 
   { kX86Jcc8,  kJcc,  IS_BINARY_OP | IS_BRANCH | NEEDS_FIXUP | USES_CCODES, { 0,             0, 0x70, 0,    0, 0, 0, 0, false }, "Jcc8",  "!1c !0t" },
@@ -827,7 +841,8 @@
       CHECK(strchr(entry->name, '8') != nullptr) << entry->name;
     } else {
       if (entry->skeleton.immediate_bytes != 1) {  // Ignore ...I8 instructions.
-        if (!StartsWith(entry->name, "Movzx8") && !StartsWith(entry->name, "Movsx8")) {
+        if (!StartsWith(entry->name, "Movzx8") && !StartsWith(entry->name, "Movsx8")
+           && !StartsWith(entry->name, "Movzx8q") && !StartsWith(entry->name, "Movsx8q")) {
           CHECK(strchr(entry->name, '8') == nullptr) << entry->name;
         }
       }
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 48fcd2c..2f914c1 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -35,17 +35,12 @@
     rl_src1 = LoadValueWide(rl_src1, kCoreReg);
     rl_src2 = LoadValueWide(rl_src2, kCoreReg);
     RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
-    RegStorage rl_result_wide = RegStorage::Solo64(rl_result.reg.GetRegNum());
     RegStorage temp_reg = AllocTemp();
-    OpRegReg(kOpXor, temp_reg, temp_reg);  // temp = 0
-    OpRegRegReg(kOpSub, rl_result_wide, rl_src1.reg, rl_src2.reg);
-    NewLIR2(kX86Set8R, temp_reg.GetReg(), kX86CondG);  // temp = (src1 > src2) ? 1 : temp
-
-    NewLIR2(kX86Rol64RI, rl_result_wide.GetReg(), 1);
-    OpRegImm(kOpAnd, rl_result.reg, 1);
-    OpRegReg(kOpNeg, rl_result.reg, rl_result.reg);
-    // result = (src1 < src2) ? -1 : 0;
-    OpRegReg(kOpAdd, rl_result.reg, temp_reg);
+    OpRegReg(kOpCmp, rl_src1.reg, rl_src2.reg);
+    NewLIR2(kX86Set8R, rl_result.reg.GetReg(), kX86CondG);   // result = (src1 > src2) ? 1 : 0
+    NewLIR2(kX86Set8R, temp_reg.GetReg(), kX86CondL);  // temp = (src1 >= src2) ? 0 : 1
+    NewLIR2(kX86Sub8RR, rl_result.reg.GetReg(), temp_reg.GetReg());
+    NewLIR2(kX86Movsx8qRR, rl_result.reg.GetReg(), rl_result.reg.GetReg());
 
     StoreValue(rl_dest, rl_result);
     FreeTemp(temp_reg);
diff --git a/compiler/dex/quick/x86/utility_x86.cc b/compiler/dex/quick/x86/utility_x86.cc
index 46e877f..ac5162e 100644
--- a/compiler/dex/quick/x86/utility_x86.cc
+++ b/compiler/dex/quick/x86/utility_x86.cc
@@ -611,8 +611,12 @@
         if (val_lo < 0) {
           val_hi += 1;
         }
-        res = LoadConstantNoClobber(RegStorage::Solo32(r_dest.GetReg()), val_hi);
-        NewLIR2(kX86Sal64RI, r_dest.GetReg(), 32);
+        if (val_hi != 0) {
+          res = LoadConstantNoClobber(RegStorage::Solo32(r_dest.GetReg()), val_hi);
+          NewLIR2(kX86Sal64RI, r_dest.GetReg(), 32);
+        } else {
+          res = NewLIR2(kX86Xor64RR, r_dest.GetReg(), r_dest.GetReg());
+        }
         if (val_lo != 0) {
           NewLIR2(kX86Add64RI, r_dest.GetReg(), val_lo);
         }
diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h
index 28b9dca..17c44bc 100644
--- a/compiler/dex/quick/x86/x86_lir.h
+++ b/compiler/dex/quick/x86/x86_lir.h
@@ -609,6 +609,10 @@
   Binary0fOpCode(kX86Movzx16),  // zero-extend 16-bit value
   Binary0fOpCode(kX86Movsx8),   // sign-extend 8-bit value
   Binary0fOpCode(kX86Movsx16),  // sign-extend 16-bit value
+  Binary0fOpCode(kX86Movzx8q),   // zero-extend 8-bit value to quad word
+  Binary0fOpCode(kX86Movzx16q),  // zero-extend 16-bit value to quad word
+  Binary0fOpCode(kX86Movsx8q),   // sign-extend 8-bit value to quad word
+  Binary0fOpCode(kX86Movsx16q),  // sign-extend 16-bit value to quad word
 #undef Binary0fOpCode
   kX86Jcc8, kX86Jcc32,  // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
   kX86Jmp8, kX86Jmp32,  // jmp rel8/32; lir operands - 0: rel, target assigned
@@ -707,6 +711,8 @@
 #define REX_X 0x42
 // Extension of the ModR/M r/m field, SIB base field, or Opcode reg field
 #define REX_B 0x41
+// Extended register set
+#define REX 0x40
 // Mask extracting the least 3 bits of r0..r15
 #define kRegNumMask32 0x07
 // Value indicating that base or reg is not used
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index c6b9161..4590880 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -800,6 +800,7 @@
 size_t OatWriter::InitOatCode(size_t offset) {
   // calculate the offsets within OatHeader to executable code
   size_t old_offset = offset;
+  size_t adjusted_offset = offset;
   // required to be on a new page boundary
   offset = RoundUp(offset, kPageSize);
   oat_header_->SetExecutableOffset(offset);
@@ -809,7 +810,8 @@
 
     #define DO_TRAMPOLINE(field, fn_name) \
       offset = CompiledCode::AlignCode(offset, instruction_set); \
-      oat_header_->Set ## fn_name ## Offset(offset); \
+      adjusted_offset = offset + CompiledCode::CodeDelta(instruction_set); \
+      oat_header_->Set ## fn_name ## Offset(adjusted_offset); \
       field.reset(compiler_driver_->Create ## fn_name()); \
       offset += field->size();
 
diff --git a/compiler/trampolines/trampoline_compiler.cc b/compiler/trampolines/trampoline_compiler.cc
index ac84d6a..d5225c1 100644
--- a/compiler/trampolines/trampoline_compiler.cc
+++ b/compiler/trampolines/trampoline_compiler.cc
@@ -30,11 +30,7 @@
 namespace arm {
 static const std::vector<uint8_t>* CreateTrampoline(EntryPointCallingConvention abi,
                                                     ThreadOffset<4> offset) {
-  // NOTE: the assembler used here is ARM, not Thumb.  This is because the address
-  // returned by this function is a pointer and for thumb we would have to set the
-  // bottom bit.  It doesn't matter since the instructions generated are the same
-  // size anyway.
-  std::unique_ptr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
+  std::unique_ptr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kThumb2)));
 
   switch (abi) {
     case kInterpreterAbi:  // Thread* is first argument (R0) in interpreter ABI.
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 5f3cd92..38051ea 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -748,6 +748,7 @@
                                bool* explicit_so_checks, bool* explicit_suspend_checks) {
   switch (isa) {
     case kArm:
+    case kThumb2:
       break;  // All checks implemented, leave as is.
 
     default:  // No checks implemented, reset all to explicit checks.
@@ -1039,8 +1040,8 @@
         } else {
           Usage("--implicit-checks passed non-recognized value %s", val.c_str());
         }
-        has_explicit_checks_options = true;
       }
+      has_explicit_checks_options = true;
     } else {
       Usage("Unknown argument %s", option.data());
     }
@@ -1170,6 +1171,7 @@
   CheckExplicitCheckOptions(instruction_set, &explicit_null_checks, &explicit_so_checks,
                             &explicit_suspend_checks);
 
+  LOG(INFO) << "init compiler options for explicit null: " << explicit_null_checks;
   CompilerOptions compiler_options(compiler_filter,
                                    huge_method_threshold,
                                    large_method_threshold,
@@ -1256,7 +1258,17 @@
   // TODO: Not sure whether it's a good idea to allow anything else but the runtime option in
   // this case at all, as we'll have to throw away produced code for a mismatch.
   if (!has_explicit_checks_options) {
-    if (instruction_set == kRuntimeISA) {
+    bool cross_compiling = true;
+    switch (kRuntimeISA) {
+      case kArm:
+      case kThumb2:
+        cross_compiling = instruction_set != kArm && instruction_set != kThumb2;
+        break;
+      default:
+        cross_compiling = instruction_set != kRuntimeISA;
+        break;
+    }
+    if (!cross_compiling) {
       Runtime* runtime = Runtime::Current();
       compiler_options.SetExplicitNullChecks(runtime->ExplicitNullChecks());
       compiler_options.SetExplicitStackOverflowChecks(runtime->ExplicitStackOverflowChecks());
diff --git a/runtime/gc/allocator/rosalloc.cc b/runtime/gc/allocator/rosalloc.cc
index 55262f2..656c55b 100644
--- a/runtime/gc/allocator/rosalloc.cc
+++ b/runtime/gc/allocator/rosalloc.cc
@@ -529,7 +529,7 @@
 }
 
 size_t RosAlloc::Free(Thread* self, void* ptr) {
-  ReaderMutexLock rmu(self, bulk_free_lock_);
+  WriterMutexLock rmu(self, bulk_free_lock_);
   return FreeInternal(self, ptr);
 }
 
@@ -1642,7 +1642,7 @@
 void RosAlloc::RevokeThreadLocalRuns(Thread* thread) {
   Thread* self = Thread::Current();
   // Avoid race conditions on the bulk free bit maps with BulkFree() (GC).
-  WriterMutexLock wmu(self, bulk_free_lock_);
+  ReaderMutexLock wmu(self, bulk_free_lock_);
   for (size_t idx = 0; idx < kNumThreadLocalSizeBrackets; idx++) {
     MutexLock mu(self, *size_bracket_locks_[idx]);
     Run* thread_local_run = reinterpret_cast<Run*>(thread->GetRosAllocRun(idx));
@@ -1720,7 +1720,7 @@
   if (kIsDebugBuild) {
     Thread* self = Thread::Current();
     // Avoid race conditions on the bulk free bit maps with BulkFree() (GC).
-    WriterMutexLock wmu(self, bulk_free_lock_);
+    ReaderMutexLock wmu(self, bulk_free_lock_);
     for (size_t idx = 0; idx < kNumThreadLocalSizeBrackets; idx++) {
       MutexLock mu(self, *size_bracket_locks_[idx]);
       Run* thread_local_run = reinterpret_cast<Run*>(thread->GetRosAllocRun(idx));
@@ -1867,7 +1867,7 @@
   CHECK(Locks::mutator_lock_->IsExclusiveHeld(self))
       << "The mutator locks isn't exclusively locked at RosAlloc::Verify()";
   MutexLock mu(self, *Locks::thread_list_lock_);
-  WriterMutexLock wmu(self, bulk_free_lock_);
+  ReaderMutexLock wmu(self, bulk_free_lock_);
   std::vector<Run*> runs;
   {
     MutexLock mu(self, lock_);
diff --git a/runtime/gc/allocator/rosalloc.h b/runtime/gc/allocator/rosalloc.h
index a439188..13f61ec 100644
--- a/runtime/gc/allocator/rosalloc.h
+++ b/runtime/gc/allocator/rosalloc.h
@@ -45,10 +45,7 @@
     byte magic_num_;  // The magic number used for debugging only.
 
     bool IsFree() const {
-      if (kIsDebugBuild) {
-        return magic_num_ == kMagicNumFree;
-      }
-      return true;
+      return !kIsDebugBuild || magic_num_ == kMagicNumFree;
     }
     size_t ByteSize(RosAlloc* rosalloc) const EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
       const byte* fpr_base = reinterpret_cast<const byte*>(this);
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 81a8623..8d987df 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -34,6 +34,13 @@
 
 #ifdef USE_ASHMEM
 #include <cutils/ashmem.h>
+#ifndef ANDROID_OS
+#include <sys/resource.h>
+#endif
+#endif
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
 #endif
 
 namespace art {
@@ -179,20 +186,32 @@
   }
   size_t page_aligned_byte_count = RoundUp(byte_count, kPageSize);
 
-#ifdef USE_ASHMEM
-  // android_os_Debug.cpp read_mapinfo assumes all ashmem regions associated with the VM are
-  // prefixed "dalvik-".
-  std::string debug_friendly_name("dalvik-");
-  debug_friendly_name += name;
-  ScopedFd fd(ashmem_create_region(debug_friendly_name.c_str(), page_aligned_byte_count));
-  if (fd.get() == -1) {
-    *error_msg = StringPrintf("ashmem_create_region failed for '%s': %s", name, strerror(errno));
-    return nullptr;
-  }
-  int flags = MAP_PRIVATE;
-#else
-  ScopedFd fd(-1);
   int flags = MAP_PRIVATE | MAP_ANONYMOUS;
+  ScopedFd fd(-1);
+
+#ifdef USE_ASHMEM
+#ifdef HAVE_ANDROID_OS
+  const bool use_ashmem = true;
+#else
+  // When not on Android ashmem is faked using files in /tmp. Ensure that such files won't
+  // fail due to ulimit restrictions. If they will then use a regular mmap.
+  struct rlimit rlimit_fsize;
+  CHECK_EQ(getrlimit(RLIMIT_FSIZE, &rlimit_fsize), 0);
+  const bool use_ashmem = (rlimit_fsize.rlim_cur == RLIM_INFINITY) ||
+      (page_aligned_byte_count < rlimit_fsize.rlim_cur);
+#endif
+  if (use_ashmem) {
+    // android_os_Debug.cpp read_mapinfo assumes all ashmem regions associated with the VM are
+    // prefixed "dalvik-".
+    std::string debug_friendly_name("dalvik-");
+    debug_friendly_name += name;
+    fd.reset(ashmem_create_region(debug_friendly_name.c_str(), page_aligned_byte_count));
+    if (fd.get() == -1) {
+      *error_msg = StringPrintf("ashmem_create_region failed for '%s': %s", name, strerror(errno));
+      return nullptr;
+    }
+    flags = MAP_PRIVATE;
+  }
 #endif
 
   // We need to store and potentially set an error number for pretty printing of errors
diff --git a/test/003-omnibus-opcodes/build b/test/003-omnibus-opcodes/build
index 9dff837..f909fb2 100644
--- a/test/003-omnibus-opcodes/build
+++ b/test/003-omnibus-opcodes/build
@@ -22,5 +22,5 @@
 rm classes/UnresClass.class
 ${JAVAC} -d classes `find src2 -name '*.java'`
 
-${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes
+${DX} -JXmx256m --debug --dex --output=classes.dex classes
 zip $TEST_NAME.jar classes.dex
diff --git a/test/056-const-string-jumbo/build b/test/056-const-string-jumbo/build
index a12c9d3..ef286d1 100644
--- a/test/056-const-string-jumbo/build
+++ b/test/056-const-string-jumbo/build
@@ -42,5 +42,5 @@
 mkdir classes
 ${JAVAC} -d classes src/*.java
 
-${DX} -JXmx500m --debug --dex --no-optimize --positions=none --no-locals --dump-to=classes.lst --output=classes.dex classes
+${DX} -JXmx500m --debug --dex --no-optimize --positions=none --no-locals --output=classes.dex classes
 zip $TEST_NAME.jar classes.dex
diff --git a/test/303-verification-stress/build b/test/303-verification-stress/build
index 2ef9bea..c1935d2 100644
--- a/test/303-verification-stress/build
+++ b/test/303-verification-stress/build
@@ -24,5 +24,5 @@
 mkdir classes
 ${JAVAC} -d classes src/*.java
 
-${DX} --debug --dex --dump-to=classes.lst --output=classes.dex classes
+${DX} --debug --dex --output=classes.dex classes
 zip $TEST_NAME.jar classes.dex
diff --git a/test/run-test b/test/run-test
index 34b06cc..d1c5bb2 100755
--- a/test/run-test
+++ b/test/run-test
@@ -298,6 +298,17 @@
 
 export TEST_NAME=`basename ${test_dir}`
 
+# To cause tests to fail fast, limit the file sizes created by dx, dex2oat and ART output to 2MB.
+file_size_limit=2048
+if echo "$test_dir" | grep 089; then
+  file_size_limit=5120
+elif echo "$test_dir" | grep 083; then
+  file_size_limit=5120
+fi
+if ! ulimit "$file_size_limit"; then
+   echo "ulimit file size setting failed"
+fi
+
 good="no"
 if [ "$dev_mode" = "yes" ]; then
     "./${build}" 2>&1
@@ -376,7 +387,7 @@
         echo '#################### info'
         cat "${td_info}" | sed 's/^/# /g'
         echo '#################### diffs'
-        diff --strip-trailing-cr -u "$expected" "$output"
+        diff --strip-trailing-cr -u "$expected" "$output" | tail -n 500
         echo '####################'
         echo ' '
     fi