summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorMingyao Yang <mingyao@google.com>2014-04-07 12:42:16 -0700
committerMingyao Yang <mingyao@google.com>2014-04-07 13:49:40 -0700
commit4289456fa265b833434c2a8eee9e7a16da31c524 (patch)
tree56aa57f5d8cd4621c0b3d48c6825632966995765 /compiler
parentb7a691f6398c55dacb3531d921e8cb298c3c8b8d (diff)
downloadart-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.h1
-rw-r--r--compiler/dex/quick/arm/int_arm.cc2
-rw-r--r--compiler/dex/quick/gen_common.cc54
-rw-r--r--compiler/dex/quick/gen_invoke.cc6
-rw-r--r--compiler/dex/quick/mips/int_mips.cc2
-rw-r--r--compiler/dex/quick/mir_to_lir.h5
-rw-r--r--compiler/dex/quick/x86/int_x86.cc4
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);