diff options
author | Mingyao Yang <mingyao@google.com> | 2014-04-07 12:42:16 -0700 |
---|---|---|
committer | Mingyao Yang <mingyao@google.com> | 2014-04-07 13:49:40 -0700 |
commit | 4289456fa265b833434c2a8eee9e7a16da31c524 (patch) | |
tree | 56aa57f5d8cd4621c0b3d48c6825632966995765 /compiler | |
parent | b7a691f6398c55dacb3531d921e8cb298c3c8b8d (diff) | |
download | art-4289456fa265b833434c2a8eee9e7a16da31c524.zip art-4289456fa265b833434c2a8eee9e7a16da31c524.tar.gz art-4289456fa265b833434c2a8eee9e7a16da31c524.tar.bz2 |
Use LIRSlowPath for throwing div by zero exception.
Get rid of launchpads for throwing div by zero exception and
use LIRSlowPath instead. Add a CallRuntimeHelper that takes no
argument for the runtime function.
Bug: 13170824
Change-Id: I7e0563e736c6f92bd63e3fbdfe3a777ad333e338
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/compiler_enums.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 2 | ||||
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 54 | ||||
-rw-r--r-- | compiler/dex/quick/gen_invoke.cc | 6 | ||||
-rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 2 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 5 | ||||
-rw-r--r-- | compiler/dex/quick/x86/int_x86.cc | 4 |
7 files changed, 50 insertions, 24 deletions
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h index 6c8c85d..38d37b0 100644 --- a/compiler/dex/compiler_enums.h +++ b/compiler/dex/compiler_enums.h @@ -324,7 +324,6 @@ std::ostream& operator<<(std::ostream& os, const X86ConditionCode& kind); enum ThrowKind { kThrowNullPointer, - kThrowDivZero, kThrowArrayBounds, kThrowConstantArrayBounds, kThrowNoSuchMethod, diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index 1abb91d..c80297b 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -917,7 +917,7 @@ void ArmMir2Lir::GenDivZeroCheck(RegStorage reg) { RegStorage t_reg = AllocTemp(); NewLIR4(kThumb2OrrRRRs, t_reg.GetReg(), reg.GetLowReg(), reg.GetHighReg(), 0); FreeTemp(t_reg); - GenCheck(kCondEq, kThrowDivZero); + AddDivZeroSlowPath(kCondEq); } // Test suspend flag, return target of taken suspend branch diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index a3fb420..4522379 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -42,17 +42,6 @@ void Mir2Lir::GenBarrier() { barrier->u.m.def_mask = ENCODE_ALL; } -// TODO: need to do some work to split out targets with -// condition codes and those without -LIR* Mir2Lir::GenCheck(ConditionCode c_code, ThrowKind kind) { - DCHECK_NE(cu_->instruction_set, kMips); - LIR* tgt = RawLIR(0, kPseudoThrowTarget, kind, current_dalvik_offset_); - LIR* branch = OpCondBranch(c_code, tgt); - // Remember branch target - will process later - throw_launchpads_.Insert(tgt); - return branch; -} - LIR* Mir2Lir::GenImmedCheck(ConditionCode c_code, RegStorage reg, int imm_val, ThrowKind kind) { LIR* tgt; LIR* branch; @@ -69,6 +58,38 @@ LIR* Mir2Lir::GenImmedCheck(ConditionCode c_code, RegStorage reg, int imm_val, T return branch; } +void Mir2Lir::AddDivZeroSlowPath(ConditionCode c_code) { + LIR* branch = OpCondBranch(c_code, nullptr); + AddDivZeroCheckSlowPath(branch); +} + +void Mir2Lir::AddDivZeroSlowPath(ConditionCode c_code, RegStorage reg, int imm_val) { + LIR* branch; + if (c_code == kCondAl) { + branch = OpUnconditionalBranch(nullptr); + } else { + branch = OpCmpImmBranch(c_code, reg, imm_val, nullptr); + } + AddDivZeroCheckSlowPath(branch); +} + +void Mir2Lir::AddDivZeroCheckSlowPath(LIR* branch) { + class DivZeroCheckSlowPath : public Mir2Lir::LIRSlowPath { + public: + DivZeroCheckSlowPath(Mir2Lir* m2l, LIR* branch) + : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch) { + } + + void Compile() { + m2l_->ResetRegPool(); + m2l_->ResetDefTracking(); + GenerateTargetLabel(); + m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(4, pThrowDivZero), true); + } + }; + + AddSlowPath(new (arena_) DivZeroCheckSlowPath(this, branch)); +} /* Perform null-check on a register. */ LIR* Mir2Lir::GenNullCheck(RegStorage m_reg, int opt_flags) { @@ -689,9 +710,6 @@ void Mir2Lir::HandleThrowLaunchPads() { } func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds); break; - case kThrowDivZero: - func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowDivZero); - break; case kThrowNoSuchMethod: OpRegCopy(TargetReg(kArg0), RegStorage::Solo32(v1)); func_offset = @@ -1533,7 +1551,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, rl_src1 = LoadValue(rl_src1, kCoreReg); rl_src2 = LoadValue(rl_src2, kCoreReg); if (check_zero) { - GenImmedCheck(kCondEq, rl_src2.reg, 0, kThrowDivZero); + AddDivZeroSlowPath(kCondEq, rl_src2.reg, 0); } rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv); done = true; @@ -1544,7 +1562,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, rl_src1 = LoadValue(rl_src1, kCoreReg); rl_src2 = LoadValue(rl_src2, kCoreReg); if (check_zero) { - GenImmedCheck(kCondEq, rl_src2.reg, 0, kThrowDivZero); + AddDivZeroSlowPath(kCondEq, rl_src2.reg, 0); } rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv); done = true; @@ -1559,7 +1577,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, RegStorage r_tgt = CallHelperSetup(func_offset); LoadValueDirectFixed(rl_src1, TargetReg(kArg0)); if (check_zero) { - GenImmedCheck(kCondEq, TargetReg(kArg1), 0, kThrowDivZero); + AddDivZeroSlowPath(kCondEq, TargetReg(kArg1), 0); } // NOTE: callout here is not a safepoint. CallHelper(r_tgt, func_offset, false /* not a safepoint */); @@ -1784,7 +1802,7 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re case Instruction::REM_INT_LIT8: case Instruction::REM_INT_LIT16: { if (lit == 0) { - GenImmedCheck(kCondAl, RegStorage::InvalidReg(), 0, kThrowDivZero); + AddDivZeroSlowPath(kCondAl, RegStorage::InvalidReg(), 0); return; } if ((opcode == Instruction::DIV_INT) || diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index 396a709..d827568 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -87,6 +87,12 @@ LIR* Mir2Lir::CallHelper(RegStorage r_tgt, ThreadOffset<4> helper_offset, bool s return call_inst; } +void Mir2Lir::CallRuntimeHelper(ThreadOffset<4> helper_offset, bool safepoint_pc) { + RegStorage r_tgt = CallHelperSetup(helper_offset); + ClobberCallerSave(); + CallHelper(r_tgt, helper_offset, safepoint_pc); +} + void Mir2Lir::CallRuntimeHelperImm(ThreadOffset<4> helper_offset, int arg0, bool safepoint_pc) { RegStorage r_tgt = CallHelperSetup(helper_offset); LoadConstant(TargetReg(kArg0), arg0); diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc index 5fe96d2..0492fdb 100644 --- a/compiler/dex/quick/mips/int_mips.cc +++ b/compiler/dex/quick/mips/int_mips.cc @@ -346,7 +346,7 @@ void MipsMir2Lir::GenDivZeroCheck(RegStorage reg) { DCHECK(reg.IsPair()); // TODO: support k64BitSolo. RegStorage t_reg = AllocTemp(); OpRegRegReg(kOpOr, t_reg, reg.GetLow(), reg.GetHigh()); - GenImmedCheck(kCondEq, t_reg, 0, kThrowDivZero); + AddDivZeroSlowPath(kCondEq, t_reg, 0); FreeTemp(t_reg); } diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 35f948e..6dbeb34 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -562,7 +562,8 @@ class Mir2Lir : public Backend { void HandleThrowLaunchPads(); void HandleSlowPaths(); void GenBarrier(); - LIR* GenCheck(ConditionCode c_code, ThrowKind kind); + void AddDivZeroSlowPath(ConditionCode c_code); + void AddDivZeroSlowPath(ConditionCode c_code, RegStorage reg, int imm_val); void MarkPossibleNullPointerException(int opt_flags); void MarkPossibleStackOverflowException(); void ForceImplicitNullCheck(RegStorage reg, int opt_flags); @@ -619,6 +620,7 @@ class Mir2Lir : public Backend { LIR* CallHelper(RegStorage r_tgt, ThreadOffset<4> helper_offset, bool safepoint_pc, bool use_link = true); RegStorage CallHelperSetup(ThreadOffset<4> helper_offset); + void CallRuntimeHelper(ThreadOffset<4> helper_offset, bool safepoint_pc); void CallRuntimeHelperImm(ThreadOffset<4> helper_offset, int arg0, bool safepoint_pc); void CallRuntimeHelperReg(ThreadOffset<4> helper_offset, RegStorage arg0, bool safepoint_pc); void CallRuntimeHelperRegLocation(ThreadOffset<4> helper_offset, RegLocation arg0, @@ -1220,6 +1222,7 @@ class Mir2Lir : public Backend { */ bool GenSpecialIdentity(MIR* mir, const InlineMethod& special); + void AddDivZeroCheckSlowPath(LIR* branch); public: // TODO: add accessors for these. diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index c1d1e01..a5f3b61 100644 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -629,7 +629,7 @@ RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1, if (check_zero) { // Handle division by zero case. - GenImmedCheck(kCondEq, rs_r1, 0, kThrowDivZero); + AddDivZeroSlowPath(kCondEq, rs_r1, 0); } // Have to catch 0x80000000/-1 case, or we will get an exception! @@ -885,7 +885,7 @@ void X86Mir2Lir::GenDivZeroCheck(RegStorage reg) { OpRegRegReg(kOpOr, t_reg, reg.GetLow(), reg.GetHigh()); // In case of zero, throw ArithmeticException. - GenCheck(kCondEq, kThrowDivZero); + AddDivZeroSlowPath(kCondEq); // The temp is no longer needed so free it at this time. FreeTemp(t_reg); |