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