diff options
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 251 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.h | 14 | ||||
-rw-r--r-- | compiler/utils/arm/assembler_arm.h | 3 | ||||
-rw-r--r-- | compiler/utils/arm/assembler_thumb2.cc | 24 | ||||
-rw-r--r-- | compiler/utils/arm/assembler_thumb2.h | 2 | ||||
-rw-r--r-- | runtime/arch/arm/asm_support_arm.S | 12 | ||||
-rw-r--r-- | test/003-omnibus-opcodes/build | 9 | ||||
-rw-r--r-- | test/005-annotations/build | 8 | ||||
-rw-r--r-- | test/023-many-interfaces/build | 6 | ||||
-rw-r--r-- | test/056-const-string-jumbo/build | 8 | ||||
-rw-r--r-- | test/111-unresolvable-exception/build | 9 | ||||
-rw-r--r-- | test/113-multidex/build | 15 | ||||
-rw-r--r-- | test/124-missing-classes/build | 9 | ||||
-rw-r--r-- | test/126-miranda-multidex/build | 15 | ||||
-rw-r--r-- | test/128-reg-spill-on-implicit-nullcheck/expected.txt (renamed from test/128-reg-spilling-on-implicit-nullcheck/expected.txt) | 0 | ||||
-rw-r--r-- | test/128-reg-spill-on-implicit-nullcheck/info.txt (renamed from test/128-reg-spilling-on-implicit-nullcheck/info.txt) | 0 | ||||
-rw-r--r-- | test/128-reg-spill-on-implicit-nullcheck/src/Main.java (renamed from test/128-reg-spilling-on-implicit-nullcheck/src/Main.java) | 0 | ||||
-rw-r--r-- | test/201-built-in-except-detail-messages/expected.txt (renamed from test/201-built-in-exception-detail-messages/expected.txt) | 0 | ||||
-rw-r--r-- | test/201-built-in-except-detail-messages/info.txt (renamed from test/201-built-in-exception-detail-messages/info.txt) | 0 | ||||
-rw-r--r-- | test/201-built-in-except-detail-messages/src/Main.java (renamed from test/201-built-in-exception-detail-messages/src/Main.java) | 0 | ||||
-rw-r--r-- | test/303-verification-stress/build | 6 | ||||
-rw-r--r-- | test/458-checker-instruct-simplification/expected.txt (renamed from test/458-checker-instruction-simplification/expected.txt) | 0 | ||||
-rw-r--r-- | test/458-checker-instruct-simplification/info.txt (renamed from test/458-checker-instruction-simplification/info.txt) | 0 | ||||
-rw-r--r-- | test/458-checker-instruct-simplification/smali/SmaliTests.smali (renamed from test/458-checker-instruction-simplification/smali/SmaliTests.smali) | 0 | ||||
-rw-r--r-- | test/458-checker-instruct-simplification/src/Main.java (renamed from test/458-checker-instruction-simplification/src/Main.java) | 0 | ||||
-rw-r--r-- | test/462-checker-inlining-dex-files/expected.txt (renamed from test/462-checker-inlining-across-dex-files/expected.txt) | 0 | ||||
-rw-r--r-- | test/462-checker-inlining-dex-files/info.txt (renamed from test/462-checker-inlining-across-dex-files/info.txt) | 0 | ||||
-rw-r--r-- | test/462-checker-inlining-dex-files/multidex.jpp (renamed from test/462-checker-inlining-across-dex-files/multidex.jpp) | 0 | ||||
-rw-r--r-- | test/462-checker-inlining-dex-files/src-multidex/OtherDex.java (renamed from test/462-checker-inlining-across-dex-files/src-multidex/OtherDex.java) | 0 | ||||
-rw-r--r-- | test/462-checker-inlining-dex-files/src/Main.java (renamed from test/462-checker-inlining-across-dex-files/src/Main.java) | 0 | ||||
-rw-r--r-- | test/468-checker-bool-simplif-regression/expected.txt (renamed from test/468-checker-bool-simplifier-regression/expected.txt) | 0 | ||||
-rw-r--r-- | test/468-checker-bool-simplif-regression/info.txt (renamed from test/468-checker-bool-simplifier-regression/info.txt) | 0 | ||||
-rw-r--r-- | test/468-checker-bool-simplif-regression/smali/TestCase.smali (renamed from test/468-checker-bool-simplifier-regression/smali/TestCase.smali) | 0 | ||||
-rw-r--r-- | test/468-checker-bool-simplif-regression/src/Main.java (renamed from test/468-checker-bool-simplifier-regression/src/Main.java) | 0 | ||||
-rw-r--r-- | test/477-long-2-float-convers-precision/expected.txt (renamed from test/477-long-to-float-conversion-precision/expected.txt) | 0 | ||||
-rw-r--r-- | test/477-long-2-float-convers-precision/info.txt (renamed from test/477-long-to-float-conversion-precision/info.txt) | 0 | ||||
-rw-r--r-- | test/477-long-2-float-convers-precision/src/Main.java (renamed from test/477-long-to-float-conversion-precision/src/Main.java) | 0 | ||||
-rw-r--r-- | test/496-checker-inlining-class-loader/expected.txt (renamed from test/496-checker-inlining-and-class-loader/expected.txt) | 0 | ||||
-rw-r--r-- | test/496-checker-inlining-class-loader/info.txt (renamed from test/496-checker-inlining-and-class-loader/info.txt) | 0 | ||||
-rw-r--r-- | test/496-checker-inlining-class-loader/src/FirstSeenByMyClassLoader.java (renamed from test/496-checker-inlining-and-class-loader/src/FirstSeenByMyClassLoader.java) | 0 | ||||
-rw-r--r-- | test/496-checker-inlining-class-loader/src/Main.java (renamed from test/496-checker-inlining-and-class-loader/src/Main.java) | 0 | ||||
-rw-r--r-- | test/530-checker-regression-reftyp-final/expected.txt (renamed from test/530-checker-regression-reftype-final/expected.txt) | 0 | ||||
-rw-r--r-- | test/530-checker-regression-reftyp-final/info.txt (renamed from test/530-checker-regression-reftype-final/info.txt) | 0 | ||||
-rw-r--r-- | test/530-checker-regression-reftyp-final/smali/TestCase.smali (renamed from test/530-checker-regression-reftype-final/smali/TestCase.smali) | 0 | ||||
-rw-r--r-- | test/530-checker-regression-reftyp-final/src/Main.java (renamed from test/530-checker-regression-reftype-final/src/Main.java) | 0 | ||||
-rw-r--r-- | test/547-regression-trycatch-critic-edge/expected.txt (renamed from test/547-regression-trycatch-critical-edge/expected.txt) | 0 | ||||
-rw-r--r-- | test/547-regression-trycatch-critic-edge/info.txt (renamed from test/547-regression-trycatch-critical-edge/info.txt) | 0 | ||||
-rw-r--r-- | test/547-regression-trycatch-critic-edge/smali/TestCase.smali (renamed from test/547-regression-trycatch-critical-edge/smali/TestCase.smali) | 0 | ||||
-rw-r--r-- | test/547-regression-trycatch-critic-edge/src/Main.java (renamed from test/547-regression-trycatch-critical-edge/src/Main.java) | 0 | ||||
-rw-r--r-- | test/557-checker-instruct-simplifier-ror/expected.txt (renamed from test/557-checker-instruction-simplifier-ror/expected.txt) | 0 | ||||
-rw-r--r-- | test/557-checker-instruct-simplifier-ror/info.txt (renamed from test/557-checker-instruction-simplifier-ror/info.txt) | 0 | ||||
-rw-r--r-- | test/557-checker-instruct-simplifier-ror/src/Main.java (renamed from test/557-checker-instruction-simplifier-ror/src/Main.java) | 0 | ||||
-rw-r--r-- | test/580-checker-string-fact-intrinsics/expected.txt (renamed from test/580-checker-string-factory-intrinsics/expected.txt) | 0 | ||||
-rw-r--r-- | test/580-checker-string-fact-intrinsics/info.txt (renamed from test/580-checker-string-factory-intrinsics/info.txt) | 0 | ||||
-rw-r--r-- | test/580-checker-string-fact-intrinsics/src/Main.java (renamed from test/580-checker-string-factory-intrinsics/src/Main.java) | 0 | ||||
-rw-r--r-- | test/588-checker-irreducib-lifetime-hole/expected.txt (renamed from test/588-checker-irreducible-lifetime-hole/expected.txt) | 0 | ||||
-rw-r--r-- | test/588-checker-irreducib-lifetime-hole/info.txt (renamed from test/588-checker-irreducible-lifetime-hole/info.txt) | 0 | ||||
-rw-r--r-- | test/588-checker-irreducib-lifetime-hole/smali/IrreducibleLoop.smali (renamed from test/588-checker-irreducible-lifetime-hole/smali/IrreducibleLoop.smali) | 0 | ||||
-rw-r--r-- | test/588-checker-irreducib-lifetime-hole/src/Main.java (renamed from test/588-checker-irreducible-lifetime-hole/src/Main.java) | 0 | ||||
-rw-r--r-- | test/590-checker-arr-set-null-regression/expected.txt (renamed from test/590-checker-array-set-null-regression/expected.txt) | 0 | ||||
-rw-r--r-- | test/590-checker-arr-set-null-regression/info.txt (renamed from test/590-checker-array-set-null-regression/info.txt) | 0 | ||||
-rw-r--r-- | test/590-checker-arr-set-null-regression/src/Main.java (renamed from test/590-checker-array-set-null-regression/src/Main.java) | 0 | ||||
-rw-r--r-- | test/593-checker-boolean-2-integral-conv/expected.txt (renamed from test/593-checker-boolean-to-integral-conv/expected.txt) | 0 | ||||
-rw-r--r-- | test/593-checker-boolean-2-integral-conv/info.txt (renamed from test/593-checker-boolean-to-integral-conv/info.txt) | 0 | ||||
-rw-r--r-- | test/593-checker-boolean-2-integral-conv/src/Main.java (renamed from test/593-checker-boolean-to-integral-conv/src/Main.java) | 0 | ||||
-rw-r--r-- | test/593-checker-long-2-float-regression/expected.txt (renamed from test/593-checker-long-to-float-regression/expected.txt) | 0 | ||||
-rw-r--r-- | test/593-checker-long-2-float-regression/info.txt (renamed from test/593-checker-long-to-float-regression/info.txt) | 0 | ||||
-rw-r--r-- | test/593-checker-long-2-float-regression/src/Main.java (renamed from test/593-checker-long-to-float-regression/src/Main.java) | 0 | ||||
-rwxr-xr-x | test/961-default-iface-resolut-generated/build (renamed from test/961-default-iface-resolution-generated/build) | 0 | ||||
-rw-r--r-- | test/961-default-iface-resolut-generated/expected.txt (renamed from test/961-default-iface-resolution-generated/expected.txt) | 0 | ||||
-rw-r--r-- | test/961-default-iface-resolut-generated/info.txt (renamed from test/961-default-iface-resolution-generated/info.txt) | 0 | ||||
-rwxr-xr-x | test/961-default-iface-resolut-generated/util-src/generate_java.py (renamed from test/961-default-iface-resolution-generated/util-src/generate_java.py) | 0 | ||||
-rwxr-xr-x | test/968-default-part-compile-generated/build (renamed from test/968-default-partial-compile-generated/build) | 0 | ||||
-rw-r--r-- | test/968-default-part-compile-generated/expected.txt (renamed from test/968-default-partial-compile-generated/expected.txt) | 0 | ||||
-rw-r--r-- | test/968-default-part-compile-generated/info.txt (renamed from test/968-default-partial-compile-generated/info.txt) | 0 | ||||
-rwxr-xr-x | test/968-default-part-compile-generated/util-src/generate_java.py (renamed from test/968-default-partial-compile-generated/util-src/generate_java.py) | 0 | ||||
-rwxr-xr-x | test/968-default-part-compile-generated/util-src/generate_smali.py (renamed from test/968-default-partial-compile-generated/util-src/generate_smali.py) | 0 | ||||
-rwxr-xr-x | test/970-iface-superresolution-generated/build (renamed from test/970-iface-super-resolution-generated/build) | 0 | ||||
-rw-r--r-- | test/970-iface-superresolution-generated/expected.txt (renamed from test/970-iface-super-resolution-generated/expected.txt) | 0 | ||||
-rw-r--r-- | test/970-iface-superresolution-generated/info.txt (renamed from test/970-iface-super-resolution-generated/info.txt) | 0 | ||||
-rwxr-xr-x | test/970-iface-superresolution-generated/util-src/generate_java.py (renamed from test/970-iface-super-resolution-generated/util-src/generate_java.py) | 0 | ||||
-rwxr-xr-x | test/970-iface-superresolution-generated/util-src/generate_smali.py (renamed from test/970-iface-super-resolution-generated/util-src/generate_smali.py) | 0 | ||||
-rw-r--r-- | test/Android.run-test.mk | 53 | ||||
-rwxr-xr-x | test/etc/run-test-jar | 50 | ||||
-rwxr-xr-x | test/run-test | 66 |
85 files changed, 471 insertions, 89 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 8b2d6fd838..3b2758bc42 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -63,9 +63,188 @@ static constexpr uint32_t kPackedSwitchCompareJumpThreshold = 7; #define __ down_cast<ArmAssembler*>(codegen->GetAssembler())-> // NOLINT #define QUICK_ENTRY_POINT(x) QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, x).Int32Value() -class NullCheckSlowPathARM : public SlowPathCode { +static constexpr int kRegListThreshold = 4; + +// SaveLiveRegisters and RestoreLiveRegisters from SlowPathCodeARM operate on sets of S registers, +// for each live D registers they treat two corresponding S registers as live ones. +// +// Two following functions (SaveContiguousSRegisterList, RestoreContiguousSRegisterList) build +// from a list of contiguous S registers a list of contiguous D registers (processing first/last +// S registers corner cases) and save/restore this new list treating them as D registers. +// - decreasing code size +// - avoiding hazards on Cortex-A57, when a pair of S registers for an actual live D register is +// restored and then used in regular non SlowPath code as D register. +// +// For the following example (v means the S register is live): +// D names: | D0 | D1 | D2 | D4 | ... +// S names: | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | ... +// Live? | | v | v | v | v | v | v | | ... +// +// S1 and S6 will be saved/restored independently; D registers list (D1, D2) will be processed +// as D registers. +static size_t SaveContiguousSRegisterList(size_t first, + size_t last, + CodeGenerator* codegen, + size_t stack_offset) { + DCHECK_LE(first, last); + if ((first == last) && (first == 0)) { + stack_offset += codegen->SaveFloatingPointRegister(stack_offset, first); + return stack_offset; + } + if (first % 2 == 1) { + stack_offset += codegen->SaveFloatingPointRegister(stack_offset, first++); + } + + bool save_last = false; + if (last % 2 == 0) { + save_last = true; + --last; + } + + if (first < last) { + DRegister d_reg = static_cast<DRegister>(first / 2); + DCHECK_EQ((last - first + 1) % 2, 0u); + size_t number_of_d_regs = (last - first + 1) / 2; + + if (number_of_d_regs == 1) { + __ StoreDToOffset(d_reg, SP, stack_offset); + } else if (number_of_d_regs > 1) { + __ add(IP, SP, ShifterOperand(stack_offset)); + __ vstmiad(IP, d_reg, number_of_d_regs); + } + stack_offset += number_of_d_regs * kArmWordSize * 2; + } + + if (save_last) { + stack_offset += codegen->SaveFloatingPointRegister(stack_offset, last + 1); + } + + return stack_offset; +} + +static size_t RestoreContiguousSRegisterList(size_t first, + size_t last, + CodeGenerator* codegen, + size_t stack_offset) { + DCHECK_LE(first, last); + if ((first == last) && (first == 0)) { + stack_offset += codegen->RestoreFloatingPointRegister(stack_offset, first); + return stack_offset; + } + if (first % 2 == 1) { + stack_offset += codegen->RestoreFloatingPointRegister(stack_offset, first++); + } + + bool restore_last = false; + if (last % 2 == 0) { + restore_last = true; + --last; + } + + if (first < last) { + DRegister d_reg = static_cast<DRegister>(first / 2); + DCHECK_EQ((last - first + 1) % 2, 0u); + size_t number_of_d_regs = (last - first + 1) / 2; + if (number_of_d_regs == 1) { + __ LoadDFromOffset(d_reg, SP, stack_offset); + } else if (number_of_d_regs > 1) { + __ add(IP, SP, ShifterOperand(stack_offset)); + __ vldmiad(IP, d_reg, number_of_d_regs); + } + stack_offset += number_of_d_regs * kArmWordSize * 2; + } + + if (restore_last) { + stack_offset += codegen->RestoreFloatingPointRegister(stack_offset, last + 1); + } + + return stack_offset; +} + +void SlowPathCodeARM::SaveLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) { + size_t stack_offset = codegen->GetFirstRegisterSlotInSlowPath(); + size_t orig_offset = stack_offset; + + const uint32_t core_spills = codegen->GetSlowPathSpills(locations, /* core_registers */ true); + for (uint32_t i : LowToHighBits(core_spills)) { + // If the register holds an object, update the stack mask. + if (locations->RegisterContainsObject(i)) { + locations->SetStackBit(stack_offset / kVRegSize); + } + DCHECK_LT(stack_offset, codegen->GetFrameSize() - codegen->FrameEntrySpillSize()); + DCHECK_LT(i, kMaximumNumberOfExpectedRegisters); + saved_core_stack_offsets_[i] = stack_offset; + stack_offset += kArmWordSize; + } + + int reg_num = POPCOUNT(core_spills); + if (reg_num != 0) { + if (reg_num > kRegListThreshold) { + __ StoreList(RegList(core_spills), orig_offset); + } else { + stack_offset = orig_offset; + for (uint32_t i : LowToHighBits(core_spills)) { + stack_offset += codegen->SaveCoreRegister(stack_offset, i); + } + } + } + + uint32_t fp_spills = codegen->GetSlowPathSpills(locations, /* core_registers */ false); + orig_offset = stack_offset; + for (size_t i : LowToHighBits(fp_spills)) { + DCHECK_LT(i, kMaximumNumberOfExpectedRegisters); + saved_fpu_stack_offsets_[i] = stack_offset; + stack_offset += kArmWordSize; + } + + stack_offset = orig_offset; + while (fp_spills != 0u) { + uint32_t begin = CTZ(fp_spills); + uint32_t tmp = fp_spills + (1u << begin); + fp_spills &= tmp; // Clear the contiguous range of 1s. + uint32_t end = (tmp == 0u) ? 32u : CTZ(tmp); // CTZ(0) is undefined. + stack_offset = SaveContiguousSRegisterList(begin, end - 1, codegen, stack_offset); + } + DCHECK_LE(stack_offset, codegen->GetFrameSize() - codegen->FrameEntrySpillSize()); +} + +void SlowPathCodeARM::RestoreLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) { + size_t stack_offset = codegen->GetFirstRegisterSlotInSlowPath(); + size_t orig_offset = stack_offset; + + const uint32_t core_spills = codegen->GetSlowPathSpills(locations, /* core_registers */ true); + for (uint32_t i : LowToHighBits(core_spills)) { + DCHECK_LT(stack_offset, codegen->GetFrameSize() - codegen->FrameEntrySpillSize()); + DCHECK_LT(i, kMaximumNumberOfExpectedRegisters); + stack_offset += kArmWordSize; + } + + int reg_num = POPCOUNT(core_spills); + if (reg_num != 0) { + if (reg_num > kRegListThreshold) { + __ LoadList(RegList(core_spills), orig_offset); + } else { + stack_offset = orig_offset; + for (uint32_t i : LowToHighBits(core_spills)) { + stack_offset += codegen->RestoreCoreRegister(stack_offset, i); + } + } + } + + uint32_t fp_spills = codegen->GetSlowPathSpills(locations, /* core_registers */ false); + while (fp_spills != 0u) { + uint32_t begin = CTZ(fp_spills); + uint32_t tmp = fp_spills + (1u << begin); + fp_spills &= tmp; // Clear the contiguous range of 1s. + uint32_t end = (tmp == 0u) ? 32u : CTZ(tmp); // CTZ(0) is undefined. + stack_offset = RestoreContiguousSRegisterList(begin, end - 1, codegen, stack_offset); + } + DCHECK_LE(stack_offset, codegen->GetFrameSize() - codegen->FrameEntrySpillSize()); +} + +class NullCheckSlowPathARM : public SlowPathCodeARM { public: - explicit NullCheckSlowPathARM(HNullCheck* instruction) : SlowPathCode(instruction) {} + explicit NullCheckSlowPathARM(HNullCheck* instruction) : SlowPathCodeARM(instruction) {} void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); @@ -89,9 +268,9 @@ class NullCheckSlowPathARM : public SlowPathCode { DISALLOW_COPY_AND_ASSIGN(NullCheckSlowPathARM); }; -class DivZeroCheckSlowPathARM : public SlowPathCode { +class DivZeroCheckSlowPathARM : public SlowPathCodeARM { public: - explicit DivZeroCheckSlowPathARM(HDivZeroCheck* instruction) : SlowPathCode(instruction) {} + explicit DivZeroCheckSlowPathARM(HDivZeroCheck* instruction) : SlowPathCodeARM(instruction) {} void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); @@ -112,10 +291,10 @@ class DivZeroCheckSlowPathARM : public SlowPathCode { DISALLOW_COPY_AND_ASSIGN(DivZeroCheckSlowPathARM); }; -class SuspendCheckSlowPathARM : public SlowPathCode { +class SuspendCheckSlowPathARM : public SlowPathCodeARM { public: SuspendCheckSlowPathARM(HSuspendCheck* instruction, HBasicBlock* successor) - : SlowPathCode(instruction), successor_(successor) {} + : SlowPathCodeARM(instruction), successor_(successor) {} void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); @@ -150,10 +329,10 @@ class SuspendCheckSlowPathARM : public SlowPathCode { DISALLOW_COPY_AND_ASSIGN(SuspendCheckSlowPathARM); }; -class BoundsCheckSlowPathARM : public SlowPathCode { +class BoundsCheckSlowPathARM : public SlowPathCodeARM { public: explicit BoundsCheckSlowPathARM(HBoundsCheck* instruction) - : SlowPathCode(instruction) {} + : SlowPathCodeARM(instruction) {} void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); @@ -190,13 +369,13 @@ class BoundsCheckSlowPathARM : public SlowPathCode { DISALLOW_COPY_AND_ASSIGN(BoundsCheckSlowPathARM); }; -class LoadClassSlowPathARM : public SlowPathCode { +class LoadClassSlowPathARM : public SlowPathCodeARM { public: LoadClassSlowPathARM(HLoadClass* cls, HInstruction* at, uint32_t dex_pc, bool do_clinit) - : SlowPathCode(at), cls_(cls), at_(at), dex_pc_(dex_pc), do_clinit_(do_clinit) { + : SlowPathCodeARM(at), cls_(cls), at_(at), dex_pc_(dex_pc), do_clinit_(do_clinit) { DCHECK(at->IsLoadClass() || at->IsClinitCheck()); } @@ -247,10 +426,10 @@ class LoadClassSlowPathARM : public SlowPathCode { DISALLOW_COPY_AND_ASSIGN(LoadClassSlowPathARM); }; -class TypeCheckSlowPathARM : public SlowPathCode { +class TypeCheckSlowPathARM : public SlowPathCodeARM { public: TypeCheckSlowPathARM(HInstruction* instruction, bool is_fatal) - : SlowPathCode(instruction), is_fatal_(is_fatal) {} + : SlowPathCodeARM(instruction), is_fatal_(is_fatal) {} void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { LocationSummary* locations = instruction_->GetLocations(); @@ -307,10 +486,10 @@ class TypeCheckSlowPathARM : public SlowPathCode { DISALLOW_COPY_AND_ASSIGN(TypeCheckSlowPathARM); }; -class DeoptimizationSlowPathARM : public SlowPathCode { +class DeoptimizationSlowPathARM : public SlowPathCodeARM { public: explicit DeoptimizationSlowPathARM(HDeoptimize* instruction) - : SlowPathCode(instruction) {} + : SlowPathCodeARM(instruction) {} void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); @@ -325,9 +504,9 @@ class DeoptimizationSlowPathARM : public SlowPathCode { DISALLOW_COPY_AND_ASSIGN(DeoptimizationSlowPathARM); }; -class ArraySetSlowPathARM : public SlowPathCode { +class ArraySetSlowPathARM : public SlowPathCodeARM { public: - explicit ArraySetSlowPathARM(HInstruction* instruction) : SlowPathCode(instruction) {} + explicit ArraySetSlowPathARM(HInstruction* instruction) : SlowPathCodeARM(instruction) {} void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { LocationSummary* locations = instruction_->GetLocations(); @@ -367,10 +546,10 @@ class ArraySetSlowPathARM : public SlowPathCode { }; // Slow path marking an object during a read barrier. -class ReadBarrierMarkSlowPathARM : public SlowPathCode { +class ReadBarrierMarkSlowPathARM : public SlowPathCodeARM { public: ReadBarrierMarkSlowPathARM(HInstruction* instruction, Location obj) - : SlowPathCode(instruction), obj_(obj) { + : SlowPathCodeARM(instruction), obj_(obj) { DCHECK(kEmitCompilerReadBarrier); } @@ -434,7 +613,7 @@ class ReadBarrierMarkSlowPathARM : public SlowPathCode { }; // Slow path generating a read barrier for a heap reference. -class ReadBarrierForHeapReferenceSlowPathARM : public SlowPathCode { +class ReadBarrierForHeapReferenceSlowPathARM : public SlowPathCodeARM { public: ReadBarrierForHeapReferenceSlowPathARM(HInstruction* instruction, Location out, @@ -442,7 +621,7 @@ class ReadBarrierForHeapReferenceSlowPathARM : public SlowPathCode { Location obj, uint32_t offset, Location index) - : SlowPathCode(instruction), + : SlowPathCodeARM(instruction), out_(out), ref_(ref), obj_(obj), @@ -614,10 +793,10 @@ class ReadBarrierForHeapReferenceSlowPathARM : public SlowPathCode { }; // Slow path generating a read barrier for a GC root. -class ReadBarrierForRootSlowPathARM : public SlowPathCode { +class ReadBarrierForRootSlowPathARM : public SlowPathCodeARM { public: ReadBarrierForRootSlowPathARM(HInstruction* instruction, Location out, Location root) - : SlowPathCode(instruction), out_(out), root_(root) { + : SlowPathCodeARM(instruction), out_(out), root_(root) { DCHECK(kEmitCompilerReadBarrier); } @@ -1509,7 +1688,7 @@ void LocationsBuilderARM::VisitDeoptimize(HDeoptimize* deoptimize) { } void InstructionCodeGeneratorARM::VisitDeoptimize(HDeoptimize* deoptimize) { - SlowPathCode* slow_path = deopt_slow_paths_.NewSlowPath<DeoptimizationSlowPathARM>(deoptimize); + SlowPathCodeARM* slow_path = deopt_slow_paths_.NewSlowPath<DeoptimizationSlowPathARM>(deoptimize); GenerateTestAndBranch(deoptimize, /* condition_input_index */ 0, slow_path->GetEntryLabel(), @@ -3096,7 +3275,7 @@ void LocationsBuilderARM::VisitDivZeroCheck(HDivZeroCheck* instruction) { } void InstructionCodeGeneratorARM::VisitDivZeroCheck(HDivZeroCheck* instruction) { - SlowPathCode* slow_path = new (GetGraph()->GetArena()) DivZeroCheckSlowPathARM(instruction); + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) DivZeroCheckSlowPathARM(instruction); codegen_->AddSlowPath(slow_path); LocationSummary* locations = instruction->GetLocations(); @@ -4265,7 +4444,7 @@ void CodeGeneratorARM::GenerateImplicitNullCheck(HNullCheck* instruction) { } void CodeGeneratorARM::GenerateExplicitNullCheck(HNullCheck* instruction) { - SlowPathCode* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathARM(instruction); + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathARM(instruction); AddSlowPath(slow_path); LocationSummary* locations = instruction->GetLocations(); @@ -4683,7 +4862,7 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { uint32_t super_offset = mirror::Class::SuperClassOffset().Int32Value(); uint32_t component_offset = mirror::Class::ComponentTypeOffset().Int32Value(); Label done; - SlowPathCode* slow_path = nullptr; + SlowPathCodeARM* slow_path = nullptr; if (may_need_runtime_call_for_type_check) { slow_path = new (GetGraph()->GetArena()) ArraySetSlowPathARM(instruction); @@ -4901,7 +5080,7 @@ void LocationsBuilderARM::VisitBoundsCheck(HBoundsCheck* instruction) { void InstructionCodeGeneratorARM::VisitBoundsCheck(HBoundsCheck* instruction) { LocationSummary* locations = instruction->GetLocations(); - SlowPathCode* slow_path = + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) BoundsCheckSlowPathARM(instruction); codegen_->AddSlowPath(slow_path); @@ -5370,7 +5549,7 @@ void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) { if (generate_null_check || cls->MustGenerateClinitCheck()) { DCHECK(cls->CanCallRuntime()); - SlowPathCode* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM( + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM( cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck()); codegen_->AddSlowPath(slow_path); if (generate_null_check) { @@ -5395,7 +5574,7 @@ void LocationsBuilderARM::VisitClinitCheck(HClinitCheck* check) { void InstructionCodeGeneratorARM::VisitClinitCheck(HClinitCheck* check) { // We assume the class is not null. - SlowPathCode* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM( + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM( check->GetLoadClass(), check, check->GetDexPc(), true); codegen_->AddSlowPath(slow_path); GenerateClassInitializationCheck(slow_path, @@ -5403,7 +5582,7 @@ void InstructionCodeGeneratorARM::VisitClinitCheck(HClinitCheck* check) { } void InstructionCodeGeneratorARM::GenerateClassInitializationCheck( - SlowPathCode* slow_path, Register class_reg) { + SlowPathCodeARM* slow_path, Register class_reg) { __ LoadFromOffset(kLoadWord, IP, class_reg, mirror::Class::StatusOffset().Int32Value()); __ cmp(IP, ShifterOperand(mirror::Class::kStatusInitialized)); __ b(slow_path->GetEntryLabel(), LT); @@ -5596,7 +5775,7 @@ void InstructionCodeGeneratorARM::VisitInstanceOf(HInstanceOf* instruction) { uint32_t component_offset = mirror::Class::ComponentTypeOffset().Int32Value(); uint32_t primitive_offset = mirror::Class::PrimitiveTypeOffset().Int32Value(); Label done, zero; - SlowPathCode* slow_path = nullptr; + SlowPathCodeARM* slow_path = nullptr; // Return 0 if `obj` is null. // avoid null check if we know obj is not null. @@ -5788,7 +5967,7 @@ void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) { type_check_kind == TypeCheckKind::kClassHierarchyCheck || type_check_kind == TypeCheckKind::kArrayObjectCheck) && !instruction->CanThrowIntoCatchBlock(); - SlowPathCode* type_check_slow_path = + SlowPathCodeARM* type_check_slow_path = new (GetGraph()->GetArena()) TypeCheckSlowPathARM(instruction, is_type_check_slow_path_fatal); codegen_->AddSlowPath(type_check_slow_path); @@ -6282,7 +6461,7 @@ void InstructionCodeGeneratorARM::GenerateGcRootFieldLoad(HInstruction* instruct "have different sizes."); // Slow path marking the GC root `root`. - SlowPathCode* slow_path = + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) ReadBarrierMarkSlowPathARM(instruction, root); codegen_->AddSlowPath(slow_path); @@ -6423,7 +6602,7 @@ void CodeGeneratorARM::GenerateReferenceLoadWithBakerReadBarrier(HInstruction* i __ MaybeUnpoisonHeapReference(ref_reg); // Slow path marking the object `ref` when it is gray. - SlowPathCode* slow_path = + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) ReadBarrierMarkSlowPathARM(instruction, ref); AddSlowPath(slow_path); @@ -6459,7 +6638,7 @@ void CodeGeneratorARM::GenerateReadBarrierSlow(HInstruction* instruction, // not used by the artReadBarrierSlow entry point. // // TODO: Unpoison `ref` when it is used by artReadBarrierSlow. - SlowPathCode* slow_path = new (GetGraph()->GetArena()) + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) ReadBarrierForHeapReferenceSlowPathARM(instruction, out, ref, obj, offset, index); AddSlowPath(slow_path); @@ -6494,7 +6673,7 @@ void CodeGeneratorARM::GenerateReadBarrierForRootSlow(HInstruction* instruction, // // Note that GC roots are not affected by heap poisoning, so we do // not need to do anything special for this here. - SlowPathCode* slow_path = + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) ReadBarrierForRootSlowPathARM(instruction, out, root); AddSlowPath(slow_path); diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index 38a2410f9a..424a1a1455 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -50,6 +50,18 @@ static constexpr SRegister kRuntimeParameterFpuRegisters[] = { S0, S1, S2, S3 }; static constexpr size_t kRuntimeParameterFpuRegistersLength = arraysize(kRuntimeParameterFpuRegisters); +class SlowPathCodeARM : public SlowPathCode { + public: + explicit SlowPathCodeARM(HInstruction* instruction) : SlowPathCode(instruction) {} + + void SaveLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) FINAL; + void RestoreLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) FINAL; + + private: + DISALLOW_COPY_AND_ASSIGN(SlowPathCodeARM); +}; + + class InvokeRuntimeCallingConvention : public CallingConvention<Register, SRegister> { public: InvokeRuntimeCallingConvention() @@ -216,7 +228,7 @@ class InstructionCodeGeneratorARM : public InstructionCodeGenerator { // is the block to branch to if the suspend check is not needed, and after // the suspend call. void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor); - void GenerateClassInitializationCheck(SlowPathCode* slow_path, Register class_reg); + void GenerateClassInitializationCheck(SlowPathCodeARM* slow_path, Register class_reg); void GenerateAndConst(Register out, Register first, uint32_t value); void GenerateOrrConst(Register out, Register first, uint32_t value); void GenerateEorConst(Register out, Register first, uint32_t value); diff --git a/compiler/utils/arm/assembler_arm.h b/compiler/utils/arm/assembler_arm.h index aefbf26db7..ee5811c3c0 100644 --- a/compiler/utils/arm/assembler_arm.h +++ b/compiler/utils/arm/assembler_arm.h @@ -763,6 +763,9 @@ class ArmAssembler : public Assembler { virtual void PushList(RegList regs, Condition cond = AL) = 0; virtual void PopList(RegList regs, Condition cond = AL) = 0; + virtual void StoreList(RegList regs, size_t stack_offset) = 0; + virtual void LoadList(RegList regs, size_t stack_offset) = 0; + virtual void Mov(Register rd, Register rm, Condition cond = AL) = 0; // Convenience shift instructions. Use mov instruction with shifter operand diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc index f5ccf409fc..2269ba2d20 100644 --- a/compiler/utils/arm/assembler_thumb2.cc +++ b/compiler/utils/arm/assembler_thumb2.cc @@ -3372,6 +3372,30 @@ void Thumb2Assembler::PopList(RegList regs, Condition cond) { ldm(IA_W, SP, regs, cond); } +void Thumb2Assembler::StoreList(RegList regs, size_t stack_offset) { + DCHECK_NE(regs, 0u); + DCHECK_EQ(regs & (1u << IP), 0u); + if (IsPowerOfTwo(regs)) { + Register reg = static_cast<Register>(CTZ(static_cast<uint32_t>(regs))); + str(reg, Address(SP, stack_offset)); + } else { + add(IP, SP, ShifterOperand(stack_offset)); + stm(IA, IP, regs); + } +} + +void Thumb2Assembler::LoadList(RegList regs, size_t stack_offset) { + DCHECK_NE(regs, 0u); + DCHECK_EQ(regs & (1u << IP), 0u); + if (IsPowerOfTwo(regs)) { + Register reg = static_cast<Register>(CTZ(static_cast<uint32_t>(regs))); + ldr(reg, Address(SP, stack_offset)); + } else { + Register lowest_reg = static_cast<Register>(CTZ(static_cast<uint32_t>(regs))); + add(lowest_reg, SP, ShifterOperand(stack_offset)); + ldm(IA, lowest_reg, regs); + } +} void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) { if (cond != AL || rd != rm) { diff --git a/compiler/utils/arm/assembler_thumb2.h b/compiler/utils/arm/assembler_thumb2.h index 917c947aa4..1c495aa7a7 100644 --- a/compiler/utils/arm/assembler_thumb2.h +++ b/compiler/utils/arm/assembler_thumb2.h @@ -293,6 +293,8 @@ class Thumb2Assembler FINAL : public ArmAssembler { void PushList(RegList regs, Condition cond = AL) OVERRIDE; void PopList(RegList regs, Condition cond = AL) OVERRIDE; + void StoreList(RegList regs, size_t stack_offset) OVERRIDE; + void LoadList(RegList regs, size_t stack_offset) OVERRIDE; void Mov(Register rd, Register rm, Condition cond = AL) OVERRIDE; diff --git a/runtime/arch/arm/asm_support_arm.S b/runtime/arch/arm/asm_support_arm.S index 38ca76a6a9..9eca86232d 100644 --- a/runtime/arch/arm/asm_support_arm.S +++ b/runtime/arch/arm/asm_support_arm.S @@ -68,14 +68,14 @@ .set .Lruntime_current3_used, 0 // The RUNTIME_CURRENT macros that are bound to the \name argument of DEF_ENTRY to ensure // that label names are unique. - .macro RUNTIME_CURRENT1 rDest, rTemp - RUNTIME_CURRENT \name, 1, \rDest, \rTemp + .macro RUNTIME_CURRENT1 rDest + RUNTIME_CURRENT \name, 1, \rDest .endm - .macro RUNTIME_CURRENT2 rDest, rTemp - RUNTIME_CURRENT \name, 2, \rDest, \rTemp + .macro RUNTIME_CURRENT2 rDest + RUNTIME_CURRENT \name, 2, \rDest .endm - .macro RUNTIME_CURRENT3 rDest, rTemp - RUNTIME_CURRENT \name, 3, \rDest, \rTemp + .macro RUNTIME_CURRENT3 rDest + RUNTIME_CURRENT \name, 3, \rDest .endm .endm diff --git a/test/003-omnibus-opcodes/build b/test/003-omnibus-opcodes/build index 56e87844c0..dba3549b1a 100644 --- a/test/003-omnibus-opcodes/build +++ b/test/003-omnibus-opcodes/build @@ -26,6 +26,11 @@ if [ ${USE_JACK} = "true" ]; then jar cf classes.jill.jar -C classes . ${JACK} --import classes.jill.jar --output-dex . else - ${DX} -JXmx256m --debug --dex --output=classes.dex classes + if [ ${NEED_DEX} = "true" ]; then + ${DX} -JXmx256m --debug --dex --output=classes.dex classes fi -zip $TEST_NAME.jar classes.dex +fi + +if [ ${NEED_DEX} = "true" ]; then + zip $TEST_NAME.jar classes.dex +fi diff --git a/test/005-annotations/build b/test/005-annotations/build index 93bee507df..216843d619 100644 --- a/test/005-annotations/build +++ b/test/005-annotations/build @@ -32,7 +32,11 @@ if [ ${USE_JACK} = "true" ]; then jar cf classes.jill.jar -C classes . ${JACK} --import classes.jill.jar --output-dex . else - ${DX} -JXmx256m --debug --dex --output=classes.dex classes + if [ ${NEED_DEX} = "true" ]; then + ${DX} -JXmx256m --debug --dex --output=classes.dex classes + fi fi -zip $TEST_NAME.jar classes.dex +if [ ${NEED_DEX} = "true" ]; then + zip $TEST_NAME.jar classes.dex +fi diff --git a/test/023-many-interfaces/build b/test/023-many-interfaces/build index 3bb6747c17..b4b5bd4c4a 100644 --- a/test/023-many-interfaces/build +++ b/test/023-many-interfaces/build @@ -29,6 +29,8 @@ else ${JAVAC} -d classes src/*.java # dx needs more memory for that test so do not pass Xmx option here. - ${DX} --debug --dex --dump-to=classes.lst --output=classes.dex classes - zip $TEST_NAME.jar classes.dex + if [ ${NEED_DEX} = "true" ]; then + ${DX} --debug --dex --dump-to=classes.lst --output=classes.dex classes + zip $TEST_NAME.jar classes.dex + fi fi diff --git a/test/056-const-string-jumbo/build b/test/056-const-string-jumbo/build index ae42519b8f..5344ac38eb 100644 --- a/test/056-const-string-jumbo/build +++ b/test/056-const-string-jumbo/build @@ -45,7 +45,11 @@ else mkdir classes ${JAVAC} -d classes src/*.java - ${DX} -JXmx500m --debug --dex --no-optimize --positions=none --no-locals --output=classes.dex classes + if [ ${NEED_DEX} = "true" ]; then + ${DX} -JXmx500m --debug --dex --no-optimize --positions=none --no-locals --output=classes.dex classes + fi fi -zip $TEST_NAME.jar classes.dex +if [ ${NEED_DEX} = "true" ]; then + zip $TEST_NAME.jar classes.dex +fi diff --git a/test/111-unresolvable-exception/build b/test/111-unresolvable-exception/build index 58ac26d836..cf19f60d51 100644 --- a/test/111-unresolvable-exception/build +++ b/test/111-unresolvable-exception/build @@ -25,6 +25,11 @@ if [ ${USE_JACK} = "true" ]; then jar cf classes.jill.jar -C classes . ${JACK} --import classes.jill.jar --output-dex . else - ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes + if [ ${NEED_DEX} = "true" ]; then + ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes + fi +fi + +if [ ${NEED_DEX} = "true" ]; then + zip $TEST_NAME.jar classes.dex fi -zip $TEST_NAME.jar classes.dex diff --git a/test/113-multidex/build b/test/113-multidex/build index 4557ccd22a..b980e501be 100644 --- a/test/113-multidex/build +++ b/test/113-multidex/build @@ -37,10 +37,15 @@ if [ ${USE_JACK} = "true" ]; then mv classes.dex classes2.dex mv classes-1.dex classes.dex else - # All except Main - ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes + if [ ${NEED_DEX} = "true" ]; then + # All except Main + ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes - # Only Main - ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex classes2 + # Only Main + ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex classes2 + fi +fi + +if [ ${NEED_DEX} = "true" ]; then + zip $TEST_NAME.jar classes.dex classes2.dex fi -zip $TEST_NAME.jar classes.dex classes2.dex diff --git a/test/124-missing-classes/build b/test/124-missing-classes/build index 0a340a26d6..ea45cd27e5 100644 --- a/test/124-missing-classes/build +++ b/test/124-missing-classes/build @@ -30,6 +30,11 @@ if [ ${USE_JACK} = "true" ]; then jar cf classes.jill.jar -C classes . ${JACK} --import classes.jill.jar --output-dex . else - ${DX} -JXmx256m --debug --dex --output=classes.dex classes + if [ ${NEED_DEX} = "true" ]; then + ${DX} -JXmx256m --debug --dex --output=classes.dex classes + fi +fi + +if [ ${NEED_DEX} = "true" ]; then + zip $TEST_NAME.jar classes.dex fi -zip $TEST_NAME.jar classes.dex diff --git a/test/126-miranda-multidex/build b/test/126-miranda-multidex/build index 00b9ba0ac2..2a5e7daa12 100644 --- a/test/126-miranda-multidex/build +++ b/test/126-miranda-multidex/build @@ -37,10 +37,15 @@ if [ ${USE_JACK} = "true" ]; then mv classes.dex classes2.dex mv classes-1.dex classes.dex else - # All except Main - ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes + if [ ${NEED_DEX} = "true" ]; then + # All except Main + ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes - # Only Main - ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex classes2 + # Only Main + ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex classes2 + fi +fi + +if [ ${NEED_DEX} = "true" ]; then + zip $TEST_NAME.jar classes.dex classes2.dex fi -zip $TEST_NAME.jar classes.dex classes2.dex diff --git a/test/128-reg-spilling-on-implicit-nullcheck/expected.txt b/test/128-reg-spill-on-implicit-nullcheck/expected.txt index 9bdf658823..9bdf658823 100644 --- a/test/128-reg-spilling-on-implicit-nullcheck/expected.txt +++ b/test/128-reg-spill-on-implicit-nullcheck/expected.txt diff --git a/test/128-reg-spilling-on-implicit-nullcheck/info.txt b/test/128-reg-spill-on-implicit-nullcheck/info.txt index 18b2112268..18b2112268 100644 --- a/test/128-reg-spilling-on-implicit-nullcheck/info.txt +++ b/test/128-reg-spill-on-implicit-nullcheck/info.txt diff --git a/test/128-reg-spilling-on-implicit-nullcheck/src/Main.java b/test/128-reg-spill-on-implicit-nullcheck/src/Main.java index 48276bfd9f..48276bfd9f 100644 --- a/test/128-reg-spilling-on-implicit-nullcheck/src/Main.java +++ b/test/128-reg-spill-on-implicit-nullcheck/src/Main.java diff --git a/test/201-built-in-exception-detail-messages/expected.txt b/test/201-built-in-except-detail-messages/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/201-built-in-exception-detail-messages/expected.txt +++ b/test/201-built-in-except-detail-messages/expected.txt diff --git a/test/201-built-in-exception-detail-messages/info.txt b/test/201-built-in-except-detail-messages/info.txt index a01b7277de..a01b7277de 100644 --- a/test/201-built-in-exception-detail-messages/info.txt +++ b/test/201-built-in-except-detail-messages/info.txt diff --git a/test/201-built-in-exception-detail-messages/src/Main.java b/test/201-built-in-except-detail-messages/src/Main.java index dc58819924..dc58819924 100644 --- a/test/201-built-in-exception-detail-messages/src/Main.java +++ b/test/201-built-in-except-detail-messages/src/Main.java diff --git a/test/303-verification-stress/build b/test/303-verification-stress/build index 5ff73eccf7..b67eaf2261 100644 --- a/test/303-verification-stress/build +++ b/test/303-verification-stress/build @@ -29,6 +29,8 @@ else ${JAVAC} -d classes src/*.java # dx needs more memory for that test so do not pass Xmx option here. - ${DX} --debug --dex --output=classes.dex classes - zip $TEST_NAME.jar classes.dex + if [ ${NEED_DEX} = "true" ]; then + ${DX} --debug --dex --output=classes.dex classes + zip $TEST_NAME.jar classes.dex + fi fi diff --git a/test/458-checker-instruction-simplification/expected.txt b/test/458-checker-instruct-simplification/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/458-checker-instruction-simplification/expected.txt +++ b/test/458-checker-instruct-simplification/expected.txt diff --git a/test/458-checker-instruction-simplification/info.txt b/test/458-checker-instruct-simplification/info.txt index 09da84b925..09da84b925 100644 --- a/test/458-checker-instruction-simplification/info.txt +++ b/test/458-checker-instruct-simplification/info.txt diff --git a/test/458-checker-instruction-simplification/smali/SmaliTests.smali b/test/458-checker-instruct-simplification/smali/SmaliTests.smali index 6845961f39..6845961f39 100644 --- a/test/458-checker-instruction-simplification/smali/SmaliTests.smali +++ b/test/458-checker-instruct-simplification/smali/SmaliTests.smali diff --git a/test/458-checker-instruction-simplification/src/Main.java b/test/458-checker-instruct-simplification/src/Main.java index 5b1473523b..5b1473523b 100644 --- a/test/458-checker-instruction-simplification/src/Main.java +++ b/test/458-checker-instruct-simplification/src/Main.java diff --git a/test/462-checker-inlining-across-dex-files/expected.txt b/test/462-checker-inlining-dex-files/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/462-checker-inlining-across-dex-files/expected.txt +++ b/test/462-checker-inlining-dex-files/expected.txt diff --git a/test/462-checker-inlining-across-dex-files/info.txt b/test/462-checker-inlining-dex-files/info.txt index 57008c39e1..57008c39e1 100644 --- a/test/462-checker-inlining-across-dex-files/info.txt +++ b/test/462-checker-inlining-dex-files/info.txt diff --git a/test/462-checker-inlining-across-dex-files/multidex.jpp b/test/462-checker-inlining-dex-files/multidex.jpp index ae554566cb..ae554566cb 100644 --- a/test/462-checker-inlining-across-dex-files/multidex.jpp +++ b/test/462-checker-inlining-dex-files/multidex.jpp diff --git a/test/462-checker-inlining-across-dex-files/src-multidex/OtherDex.java b/test/462-checker-inlining-dex-files/src-multidex/OtherDex.java index 2056e2f2aa..2056e2f2aa 100644 --- a/test/462-checker-inlining-across-dex-files/src-multidex/OtherDex.java +++ b/test/462-checker-inlining-dex-files/src-multidex/OtherDex.java diff --git a/test/462-checker-inlining-across-dex-files/src/Main.java b/test/462-checker-inlining-dex-files/src/Main.java index c2bb479468..c2bb479468 100644 --- a/test/462-checker-inlining-across-dex-files/src/Main.java +++ b/test/462-checker-inlining-dex-files/src/Main.java diff --git a/test/468-checker-bool-simplifier-regression/expected.txt b/test/468-checker-bool-simplif-regression/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/468-checker-bool-simplifier-regression/expected.txt +++ b/test/468-checker-bool-simplif-regression/expected.txt diff --git a/test/468-checker-bool-simplifier-regression/info.txt b/test/468-checker-bool-simplif-regression/info.txt index 0a465846b1..0a465846b1 100644 --- a/test/468-checker-bool-simplifier-regression/info.txt +++ b/test/468-checker-bool-simplif-regression/info.txt diff --git a/test/468-checker-bool-simplifier-regression/smali/TestCase.smali b/test/468-checker-bool-simplif-regression/smali/TestCase.smali index 87ad21ead4..87ad21ead4 100644 --- a/test/468-checker-bool-simplifier-regression/smali/TestCase.smali +++ b/test/468-checker-bool-simplif-regression/smali/TestCase.smali diff --git a/test/468-checker-bool-simplifier-regression/src/Main.java b/test/468-checker-bool-simplif-regression/src/Main.java index 8fe05c7a8a..8fe05c7a8a 100644 --- a/test/468-checker-bool-simplifier-regression/src/Main.java +++ b/test/468-checker-bool-simplif-regression/src/Main.java diff --git a/test/477-long-to-float-conversion-precision/expected.txt b/test/477-long-2-float-convers-precision/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/477-long-to-float-conversion-precision/expected.txt +++ b/test/477-long-2-float-convers-precision/expected.txt diff --git a/test/477-long-to-float-conversion-precision/info.txt b/test/477-long-2-float-convers-precision/info.txt index 1e07cf3f0b..1e07cf3f0b 100644 --- a/test/477-long-to-float-conversion-precision/info.txt +++ b/test/477-long-2-float-convers-precision/info.txt diff --git a/test/477-long-to-float-conversion-precision/src/Main.java b/test/477-long-2-float-convers-precision/src/Main.java index 568bc04d6c..568bc04d6c 100644 --- a/test/477-long-to-float-conversion-precision/src/Main.java +++ b/test/477-long-2-float-convers-precision/src/Main.java diff --git a/test/496-checker-inlining-and-class-loader/expected.txt b/test/496-checker-inlining-class-loader/expected.txt index 312c28f8b0..312c28f8b0 100644 --- a/test/496-checker-inlining-and-class-loader/expected.txt +++ b/test/496-checker-inlining-class-loader/expected.txt diff --git a/test/496-checker-inlining-and-class-loader/info.txt b/test/496-checker-inlining-class-loader/info.txt index aa4b256207..aa4b256207 100644 --- a/test/496-checker-inlining-and-class-loader/info.txt +++ b/test/496-checker-inlining-class-loader/info.txt diff --git a/test/496-checker-inlining-and-class-loader/src/FirstSeenByMyClassLoader.java b/test/496-checker-inlining-class-loader/src/FirstSeenByMyClassLoader.java index e97b4e3391..e97b4e3391 100644 --- a/test/496-checker-inlining-and-class-loader/src/FirstSeenByMyClassLoader.java +++ b/test/496-checker-inlining-class-loader/src/FirstSeenByMyClassLoader.java diff --git a/test/496-checker-inlining-and-class-loader/src/Main.java b/test/496-checker-inlining-class-loader/src/Main.java index 15d4dc07bc..15d4dc07bc 100644 --- a/test/496-checker-inlining-and-class-loader/src/Main.java +++ b/test/496-checker-inlining-class-loader/src/Main.java diff --git a/test/530-checker-regression-reftype-final/expected.txt b/test/530-checker-regression-reftyp-final/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/530-checker-regression-reftype-final/expected.txt +++ b/test/530-checker-regression-reftyp-final/expected.txt diff --git a/test/530-checker-regression-reftype-final/info.txt b/test/530-checker-regression-reftyp-final/info.txt index 07789d6e9e..07789d6e9e 100644 --- a/test/530-checker-regression-reftype-final/info.txt +++ b/test/530-checker-regression-reftyp-final/info.txt diff --git a/test/530-checker-regression-reftype-final/smali/TestCase.smali b/test/530-checker-regression-reftyp-final/smali/TestCase.smali index 44facfca05..44facfca05 100644 --- a/test/530-checker-regression-reftype-final/smali/TestCase.smali +++ b/test/530-checker-regression-reftyp-final/smali/TestCase.smali diff --git a/test/530-checker-regression-reftype-final/src/Main.java b/test/530-checker-regression-reftyp-final/src/Main.java index f86b515cae..f86b515cae 100644 --- a/test/530-checker-regression-reftype-final/src/Main.java +++ b/test/530-checker-regression-reftyp-final/src/Main.java diff --git a/test/547-regression-trycatch-critical-edge/expected.txt b/test/547-regression-trycatch-critic-edge/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/547-regression-trycatch-critical-edge/expected.txt +++ b/test/547-regression-trycatch-critic-edge/expected.txt diff --git a/test/547-regression-trycatch-critical-edge/info.txt b/test/547-regression-trycatch-critic-edge/info.txt index dc798c0016..dc798c0016 100644 --- a/test/547-regression-trycatch-critical-edge/info.txt +++ b/test/547-regression-trycatch-critic-edge/info.txt diff --git a/test/547-regression-trycatch-critical-edge/smali/TestCase.smali b/test/547-regression-trycatch-critic-edge/smali/TestCase.smali index 53a3cc5b62..53a3cc5b62 100644 --- a/test/547-regression-trycatch-critical-edge/smali/TestCase.smali +++ b/test/547-regression-trycatch-critic-edge/smali/TestCase.smali diff --git a/test/547-regression-trycatch-critical-edge/src/Main.java b/test/547-regression-trycatch-critic-edge/src/Main.java index 8eddac3fea..8eddac3fea 100644 --- a/test/547-regression-trycatch-critical-edge/src/Main.java +++ b/test/547-regression-trycatch-critic-edge/src/Main.java diff --git a/test/557-checker-instruction-simplifier-ror/expected.txt b/test/557-checker-instruct-simplifier-ror/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/557-checker-instruction-simplifier-ror/expected.txt +++ b/test/557-checker-instruct-simplifier-ror/expected.txt diff --git a/test/557-checker-instruction-simplifier-ror/info.txt b/test/557-checker-instruct-simplifier-ror/info.txt index f9a86f8009..f9a86f8009 100644 --- a/test/557-checker-instruction-simplifier-ror/info.txt +++ b/test/557-checker-instruct-simplifier-ror/info.txt diff --git a/test/557-checker-instruction-simplifier-ror/src/Main.java b/test/557-checker-instruct-simplifier-ror/src/Main.java index 0e3d14518a..0e3d14518a 100644 --- a/test/557-checker-instruction-simplifier-ror/src/Main.java +++ b/test/557-checker-instruct-simplifier-ror/src/Main.java diff --git a/test/580-checker-string-factory-intrinsics/expected.txt b/test/580-checker-string-fact-intrinsics/expected.txt index 86e041dad6..86e041dad6 100644 --- a/test/580-checker-string-factory-intrinsics/expected.txt +++ b/test/580-checker-string-fact-intrinsics/expected.txt diff --git a/test/580-checker-string-factory-intrinsics/info.txt b/test/580-checker-string-fact-intrinsics/info.txt index 3d01a1964a..3d01a1964a 100644 --- a/test/580-checker-string-factory-intrinsics/info.txt +++ b/test/580-checker-string-fact-intrinsics/info.txt diff --git a/test/580-checker-string-factory-intrinsics/src/Main.java b/test/580-checker-string-fact-intrinsics/src/Main.java index a2e34bffd0..a2e34bffd0 100644 --- a/test/580-checker-string-factory-intrinsics/src/Main.java +++ b/test/580-checker-string-fact-intrinsics/src/Main.java diff --git a/test/588-checker-irreducible-lifetime-hole/expected.txt b/test/588-checker-irreducib-lifetime-hole/expected.txt index aab200982b..aab200982b 100644 --- a/test/588-checker-irreducible-lifetime-hole/expected.txt +++ b/test/588-checker-irreducib-lifetime-hole/expected.txt diff --git a/test/588-checker-irreducible-lifetime-hole/info.txt b/test/588-checker-irreducib-lifetime-hole/info.txt index a2861a9fd5..a2861a9fd5 100644 --- a/test/588-checker-irreducible-lifetime-hole/info.txt +++ b/test/588-checker-irreducib-lifetime-hole/info.txt diff --git a/test/588-checker-irreducible-lifetime-hole/smali/IrreducibleLoop.smali b/test/588-checker-irreducib-lifetime-hole/smali/IrreducibleLoop.smali index 186f0ab3e8..186f0ab3e8 100644 --- a/test/588-checker-irreducible-lifetime-hole/smali/IrreducibleLoop.smali +++ b/test/588-checker-irreducib-lifetime-hole/smali/IrreducibleLoop.smali diff --git a/test/588-checker-irreducible-lifetime-hole/src/Main.java b/test/588-checker-irreducib-lifetime-hole/src/Main.java index 98565b103a..98565b103a 100644 --- a/test/588-checker-irreducible-lifetime-hole/src/Main.java +++ b/test/588-checker-irreducib-lifetime-hole/src/Main.java diff --git a/test/590-checker-array-set-null-regression/expected.txt b/test/590-checker-arr-set-null-regression/expected.txt index b0aad4deb5..b0aad4deb5 100644 --- a/test/590-checker-array-set-null-regression/expected.txt +++ b/test/590-checker-arr-set-null-regression/expected.txt diff --git a/test/590-checker-array-set-null-regression/info.txt b/test/590-checker-arr-set-null-regression/info.txt index fe173a334d..fe173a334d 100644 --- a/test/590-checker-array-set-null-regression/info.txt +++ b/test/590-checker-arr-set-null-regression/info.txt diff --git a/test/590-checker-array-set-null-regression/src/Main.java b/test/590-checker-arr-set-null-regression/src/Main.java index 792ee4ecd6..792ee4ecd6 100644 --- a/test/590-checker-array-set-null-regression/src/Main.java +++ b/test/590-checker-arr-set-null-regression/src/Main.java diff --git a/test/593-checker-boolean-to-integral-conv/expected.txt b/test/593-checker-boolean-2-integral-conv/expected.txt index b0aad4deb5..b0aad4deb5 100644 --- a/test/593-checker-boolean-to-integral-conv/expected.txt +++ b/test/593-checker-boolean-2-integral-conv/expected.txt diff --git a/test/593-checker-boolean-to-integral-conv/info.txt b/test/593-checker-boolean-2-integral-conv/info.txt index 2d883c77ee..2d883c77ee 100644 --- a/test/593-checker-boolean-to-integral-conv/info.txt +++ b/test/593-checker-boolean-2-integral-conv/info.txt diff --git a/test/593-checker-boolean-to-integral-conv/src/Main.java b/test/593-checker-boolean-2-integral-conv/src/Main.java index b4c91c8db6..b4c91c8db6 100644 --- a/test/593-checker-boolean-to-integral-conv/src/Main.java +++ b/test/593-checker-boolean-2-integral-conv/src/Main.java diff --git a/test/593-checker-long-to-float-regression/expected.txt b/test/593-checker-long-2-float-regression/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/593-checker-long-to-float-regression/expected.txt +++ b/test/593-checker-long-2-float-regression/expected.txt diff --git a/test/593-checker-long-to-float-regression/info.txt b/test/593-checker-long-2-float-regression/info.txt index 39402e9cdd..39402e9cdd 100644 --- a/test/593-checker-long-to-float-regression/info.txt +++ b/test/593-checker-long-2-float-regression/info.txt diff --git a/test/593-checker-long-to-float-regression/src/Main.java b/test/593-checker-long-2-float-regression/src/Main.java index 9c07f3d692..9c07f3d692 100644 --- a/test/593-checker-long-to-float-regression/src/Main.java +++ b/test/593-checker-long-2-float-regression/src/Main.java diff --git a/test/961-default-iface-resolution-generated/build b/test/961-default-iface-resolut-generated/build index ccebbe4ac9..ccebbe4ac9 100755 --- a/test/961-default-iface-resolution-generated/build +++ b/test/961-default-iface-resolut-generated/build diff --git a/test/961-default-iface-resolution-generated/expected.txt b/test/961-default-iface-resolut-generated/expected.txt index 1ddd65d177..1ddd65d177 100644 --- a/test/961-default-iface-resolution-generated/expected.txt +++ b/test/961-default-iface-resolut-generated/expected.txt diff --git a/test/961-default-iface-resolution-generated/info.txt b/test/961-default-iface-resolut-generated/info.txt index 2cd2cc75b7..2cd2cc75b7 100644 --- a/test/961-default-iface-resolution-generated/info.txt +++ b/test/961-default-iface-resolut-generated/info.txt diff --git a/test/961-default-iface-resolution-generated/util-src/generate_java.py b/test/961-default-iface-resolut-generated/util-src/generate_java.py index a205cd6ce0..a205cd6ce0 100755 --- a/test/961-default-iface-resolution-generated/util-src/generate_java.py +++ b/test/961-default-iface-resolut-generated/util-src/generate_java.py diff --git a/test/968-default-partial-compile-generated/build b/test/968-default-part-compile-generated/build index 1e9f8aadd5..1e9f8aadd5 100755 --- a/test/968-default-partial-compile-generated/build +++ b/test/968-default-part-compile-generated/build diff --git a/test/968-default-partial-compile-generated/expected.txt b/test/968-default-part-compile-generated/expected.txt index 1ddd65d177..1ddd65d177 100644 --- a/test/968-default-partial-compile-generated/expected.txt +++ b/test/968-default-part-compile-generated/expected.txt diff --git a/test/968-default-partial-compile-generated/info.txt b/test/968-default-part-compile-generated/info.txt index bc1c42816e..bc1c42816e 100644 --- a/test/968-default-partial-compile-generated/info.txt +++ b/test/968-default-part-compile-generated/info.txt diff --git a/test/968-default-partial-compile-generated/util-src/generate_java.py b/test/968-default-part-compile-generated/util-src/generate_java.py index 35290efe1d..35290efe1d 100755 --- a/test/968-default-partial-compile-generated/util-src/generate_java.py +++ b/test/968-default-part-compile-generated/util-src/generate_java.py diff --git a/test/968-default-partial-compile-generated/util-src/generate_smali.py b/test/968-default-part-compile-generated/util-src/generate_smali.py index 9855bcf854..9855bcf854 100755 --- a/test/968-default-partial-compile-generated/util-src/generate_smali.py +++ b/test/968-default-part-compile-generated/util-src/generate_smali.py diff --git a/test/970-iface-super-resolution-generated/build b/test/970-iface-superresolution-generated/build index fd1b271c1c..fd1b271c1c 100755 --- a/test/970-iface-super-resolution-generated/build +++ b/test/970-iface-superresolution-generated/build diff --git a/test/970-iface-super-resolution-generated/expected.txt b/test/970-iface-superresolution-generated/expected.txt index 1ddd65d177..1ddd65d177 100644 --- a/test/970-iface-super-resolution-generated/expected.txt +++ b/test/970-iface-superresolution-generated/expected.txt diff --git a/test/970-iface-super-resolution-generated/info.txt b/test/970-iface-superresolution-generated/info.txt index 2cd2cc75b7..2cd2cc75b7 100644 --- a/test/970-iface-super-resolution-generated/info.txt +++ b/test/970-iface-superresolution-generated/info.txt diff --git a/test/970-iface-super-resolution-generated/util-src/generate_java.py b/test/970-iface-superresolution-generated/util-src/generate_java.py index c12f10d790..c12f10d790 100755 --- a/test/970-iface-super-resolution-generated/util-src/generate_java.py +++ b/test/970-iface-superresolution-generated/util-src/generate_java.py diff --git a/test/970-iface-super-resolution-generated/util-src/generate_smali.py b/test/970-iface-superresolution-generated/util-src/generate_smali.py index cb7b0fa4f2..cb7b0fa4f2 100755 --- a/test/970-iface-super-resolution-generated/util-src/generate_smali.py +++ b/test/970-iface-superresolution-generated/util-src/generate_smali.py diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 5301a03e4a..559e96359b 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -47,6 +47,14 @@ ifeq ($(ART_TEST_DEBUG_GC),true) ART_TEST_WITH_STRACE := true endif +ifeq ($(ART_TEST_BISECTION),true) + # Need to keep rebuilding the test to bisection search it. + ART_TEST_RUN_TEST_NO_PREBUILD := true + ART_TEST_RUN_TEST_PREBUILD := false + # Bisection search writes to standard output. + ART_TEST_QUIET := false +endif + # Helper to create individual build targets for tests. Must be called with $(eval). # $(1): the test number define define-build-art-run-test @@ -270,11 +278,11 @@ TEST_ART_BROKEN_TARGET_TESTS := # Tests that require python3. TEST_ART_PYTHON3_DEPENDENCY_RUN_TESTS := \ 960-default-smali \ - 961-default-iface-resolution-generated \ + 961-default-iface-resolut-generated \ 964-default-iface-init-generated \ - 968-default-partial-compile-generated \ + 968-default-part-compile-generated \ 969-iface-super \ - 970-iface-super-resolution-generated \ + 970-iface-superresolution-generated \ 971-iface-super # Check if we have python3 to run our tests. @@ -354,12 +362,12 @@ TEST_ART_BROKEN_INTERPRETER_ACCESS_CHECK_TESTS := # Tests that are broken with GC stress. # * 137-cfi needs to unwind a second forked process. We're using a primitive sleep to wait till we # hope the second process got into the expected state. The slowness of gcstress makes this bad. -# * 961-default-iface-resolution-generated and 964-default-iface-init-generated are very long tests +# * 961-default-iface-resolut-generated and 964-default-iface-init-generated are very long tests # that often will take more than the timeout to run when gcstress is enabled. This is because # gcstress slows down allocations significantly which these tests do a lot. TEST_ART_BROKEN_GCSTRESS_RUN_TESTS := \ 137-cfi \ - 961-default-iface-resolution-generated \ + 961-default-iface-resolut-generated \ 964-default-iface-init-generated ifneq (,$(filter gcstress,$(GC_TYPES))) @@ -644,6 +652,38 @@ endif TEST_ART_BROKEN_OPTIMIZING_HEAP_POISONING_RUN_TESTS := +# Tests incompatible with bisection bug search. Sorted by incompatibility reason. +# 000 through 595 do not compile anything. 089 tests a build failure. 018 through 137 +# run dalvikvm more than once. 115 and 088 assume they are always compiled. +# 055 tests performance which is degraded during bisecting. +TEST_ART_INCOMPATIBLE_BISECTION_SEARCH_RUN_TESTS := \ + 000-nop \ + 134-nodex2oat-nofallback \ + 147-stripped-dex-fallback \ + 595-profile-saving \ + \ + 089-many-methods \ + \ + 018-stack-overflow \ + 116-nodex2oat \ + 117-nopatchoat \ + 118-noimage-dex2oat \ + 119-noimage-patchoat \ + 126-miranda-multidex \ + 137-cfi \ + \ + 115-native-bridge \ + 088-monitor-verification \ + \ + 055-enum-performance + +ifeq ($(ART_TEST_BISECTION),true) + ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), \ + $(PREBUILD_TYPES),$(OPTIMIZING_COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \ + $(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), \ + $(TEST_ART_INCOMPATIBLE_BISECTION_SEARCH_RUN_TESTS),$(ALL_ADDRESS_SIZES)) +endif + # Clear variables ahead of appending to them when defining tests. $(foreach target, $(TARGET_TYPES), $(eval ART_RUN_TEST_$(call name-to-var,$(target))_RULES :=)) $(foreach target, $(TARGET_TYPES), \ @@ -762,6 +802,9 @@ define define-test-art-run-test ifeq ($(ART_TEST_RUN_TEST_ALWAYS_CLEAN),true) run_test_options += --always-clean endif + ifeq ($(ART_TEST_BISECTION),true) + run_test_options += --bisection-search + endif ifeq ($(1),host) uc_host_or_target := HOST test_groups := ART_RUN_TEST_HOST_RULES diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index a0e99d8125..a445f4d630 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -56,6 +56,8 @@ DEX_VERIFY="" USE_DEX2OAT_AND_PATCHOAT="y" INSTRUCTION_SET_FEATURES="" ARGS="" +EXTERNAL_LOG_TAGS="n" # if y respect externally set ANDROID_LOG_TAGS. +DRY_RUN="n" # if y prepare to run the test but don't run it. while true; do if [ "x$1" = "x--quiet" ]; then @@ -235,6 +237,12 @@ while true; do fi EXPERIMENTAL="$EXPERIMENTAL $2" shift 2 + elif [ "x$1" = "x--external-log-tags" ]; then + EXTERNAL_LOG_TAGS="y" + shift + elif [ "x$1" = "x--dry-run" ]; then + DRY_RUN="y" + shift elif expr "x$1" : "x--" >/dev/null 2>&1; then echo "unknown $0 option: $1" 1>&2 exit 1 @@ -493,12 +501,14 @@ if [ "$HOST" = "n" ]; then # Create a script with the command. The command can get longer than the longest # allowed adb command and there is no way to get the exit status from a adb shell - # command. + # command. Dalvik cache is cleaned before running to make subsequent executions + # of the script follow the same runtime path. cmdline="cd $DEX_LOCATION && \ export ANDROID_DATA=$DEX_LOCATION && \ export ANDROID_ADDITIONAL_PUBLIC_LIBRARIES=$PUBLIC_LIBS && \ export DEX_LOCATION=$DEX_LOCATION && \ export ANDROID_ROOT=$ANDROID_ROOT && \ + rm -rf ${DEX_LOCATION}/dalvik-cache/ && \ mkdir -p ${mkdir_locations} && \ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH && \ export PATH=$ANDROID_ROOT/bin:$PATH && \ @@ -519,7 +529,9 @@ if [ "$HOST" = "n" ]; then adb push $cmdfile $DEX_LOCATION/cmdline.sh > /dev/null 2>&1 fi - adb shell sh $DEX_LOCATION/cmdline.sh + if [ "$DRY_RUN" != "y" ]; then + adb shell sh $DEX_LOCATION/cmdline.sh + fi rm -f $cmdfile else @@ -527,10 +539,12 @@ else # By default, and for prebuild dex2oat, we are interested in errors being logged. In dev mode # we want debug messages. - if [ "$DEV_MODE" = "y" ]; then - export ANDROID_LOG_TAGS='*:d' - else - export ANDROID_LOG_TAGS='*:e' + if [ "$EXTERNAL_LOG_TAGS" = "n" ]; then + if [ "$DEV_MODE" = "y" ]; then + export ANDROID_LOG_TAGS='*:d' + else + export ANDROID_LOG_TAGS='*:e' + fi fi export ANDROID_DATA="$DEX_LOCATION" @@ -584,15 +598,21 @@ else # For running, we must turn off logging when dex2oat or patchoat are missing. Otherwise we use # the same defaults as for prebuilt: everything when --dev, otherwise errors and above only. - if [ "$DEV_MODE" = "y" ]; then - export ANDROID_LOG_TAGS='*:d' - elif [ "$USE_DEX2OAT_AND_PATCHOAT" = "n" ]; then - # All tests would log the error of failing dex2oat/patchoat. Be silent here and only - # log fatal events. - export ANDROID_LOG_TAGS='*:s' - else - # We are interested in LOG(ERROR) output. - export ANDROID_LOG_TAGS='*:e' + if [ "$EXTERNAL_LOG_TAGS" = "n" ]; then + if [ "$DEV_MODE" = "y" ]; then + export ANDROID_LOG_TAGS='*:d' + elif [ "$USE_DEX2OAT_AND_PATCHOAT" = "n" ]; then + # All tests would log the error of failing dex2oat/patchoat. Be silent here and only + # log fatal events. + export ANDROID_LOG_TAGS='*:s' + else + # We are interested in LOG(ERROR) output. + export ANDROID_LOG_TAGS='*:e' + fi + fi + + if [ "$DRY_RUN" = "y" ]; then + exit 0 fi if [ "$USE_GDB" = "y" ]; then diff --git a/test/run-test b/test/run-test index aea64351f5..ae53f9ecc0 100755 --- a/test/run-test +++ b/test/run-test @@ -130,6 +130,7 @@ have_image="yes" pic_image_suffix="" multi_image_suffix="" android_root="/system" +bisection_search="no" # By default we will use optimizing. image_args="" image_suffix="" @@ -347,6 +348,9 @@ while true; do shift run_args="${run_args} --instruction-set-features $1" shift + elif [ "x$1" = "x--bisection-search" ]; then + bisection_search="yes" + shift elif expr "x$1" : "x--" >/dev/null 2>&1; then echo "unknown $0 option: $1" 1>&2 usage="yes" @@ -519,6 +523,21 @@ if [ "$dev_mode" = "yes" -a "$quiet" = "yes" ]; then usage="yes" fi +if [ "$bisection_search" = "yes" -a "$prebuild_mode" = "yes" ]; then + err_echo "--bisection-search and --prebuild are mutually exclusive" + usage="yes" +fi + +if [ "$bisection_search" = "yes" -a "$have_dex2oat" = "no" ]; then + err_echo "--bisection-search and --no-dex2oat are mutually exclusive" + usage="yes" +fi + +if [ "$bisection_search" = "yes" -a "$have_patchoat" = "no" ]; then + err_echo "--bisection-search and --no-patchoat are mutually exclusive" + usage="yes" +fi + if [ "$usage" = "no" ]; then if [ "x$1" = "x" -o "x$1" = "x-" ]; then test_dir=`basename "$oldwd"` @@ -539,6 +558,13 @@ if [ "$usage" = "no" ]; then shift fi +# For building with javac and dx always use Java 7. The dx compiler +# only support byte codes from Java 7 or earlier (class file major +# version 51 or lower). +if [ "$USE_JACK" != "true" ] && [ "$NEED_DEX" = "true" ]; then + export JAVAC="${JAVAC} -source 1.7 -target 1.7" +fi + if [ "$usage" = "yes" ]; then prog=`basename $prog` ( @@ -560,8 +586,8 @@ if [ "$usage" = "yes" ]; then echo " --gdb Run under gdb; incompatible with some tests." echo " --gdb-arg Pass an option to gdb." echo " --build-only Build test files only (off by default)." - echo " --build-with-javac-dx Build test files with javac and dx (on by default)." - echo " --build-with-jack Build test files with jack and jill (off by default)." + echo " --build-with-javac-dx Build test files with javac and dx (off by default)." + echo " --build-with-jack Build test files with jack and jill (on by default)." echo " --interpreter Enable interpreter only mode (off by default)." echo " --jit Enable jit (off by default)." echo " --optimizing Enable optimizing compiler (default)." @@ -613,6 +639,7 @@ if [ "$usage" = "yes" ]; then echo " the boot class path." echo " --pic-test Compile the test code position independent." echo " --quiet Don't print anything except failure messages" + echo " --bisection-search Perform bisection bug search." ) 1>&2 # Direct to stderr so usage is not printed if --quiet is set. exit 1 fi @@ -881,6 +908,41 @@ fi ) 2>&${real_stderr} 1>&2 +# Attempt bisection only if the test failed. +if [ "$bisection_search" = "yes" -a "$good" != "yes" ]; then + # Bisecting works by skipping different optimization passes which breaks checker assertions. + if [ "$run_checker" == "yes" ]; then + echo "${test_dir}: not bisecting, checker test." 1>&2 + else + # Increase file size limit, bisection search can generate large logfiles. + if ! ulimit -S unlimited; then + err_echo "ulimit file size setting failed" + fi + echo "${test_dir}: bisecting..." 1>&2 + cwd=`pwd` + maybe_device_mode="" + raw_cmd="" + if [ "$target_mode" = "yes" ]; then + # Produce cmdline.sh in $DEX_LOCATION. "$@" is passed as a runtime option + # so that cmdline.sh forwards its arguments to dalvikvm. invoke-with is set + # to exec in order to preserve pid when calling dalvikvm. This is required + # for bisection search to correctly retrieve logs from device. + "./${run}" $run_args --runtime-option '"$@"' --invoke-with exec --dry-run "$@" &> /dev/null + adb shell chmod u+x "$DEX_LOCATION/cmdline.sh" + maybe_device_mode="--device" + raw_cmd="$DEX_LOCATION/cmdline.sh" + else + raw_cmd="$cwd/${run} --external-log-tags $run_args $@" + fi + $ANDROID_BUILD_TOP/art/tools/bisection_search/bisection_search.py \ + $maybe_device_mode \ + --raw-cmd="$raw_cmd" \ + --check-script="$cwd/check" \ + --expected-output="$cwd/expected.txt" \ + --timeout=300 + fi +fi + # Clean up test files. if [ "$always_clean" = "yes" -o "$good" = "yes" ] && [ "$never_clean" = "no" ]; then cd "$oldwd" |