summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorMingyao Yang <mingyao@google.com>2014-04-17 17:31:48 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-04-17 17:31:48 +0000
commit425640d6fac3432a44e236a002e8401a7cd59c5c (patch)
tree0d5e53555369cb0be7239dc8b9f1f779a5ecb97d /compiler
parent79f2c53f3cb8649c19aeded82f7b8dcc96015808 (diff)
parente643a179cf5585ba6bafdd4fa51730d9f50c06f6 (diff)
downloadart-425640d6fac3432a44e236a002e8401a7cd59c5c.tar.gz
art-425640d6fac3432a44e236a002e8401a7cd59c5c.tar.bz2
art-425640d6fac3432a44e236a002e8401a7cd59c5c.zip
Merge "Use LIRSlowPath for throwing NPE."
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/compiler_enums.h1
-rw-r--r--compiler/dex/quick/arm/codegen_arm.h2
-rw-r--r--compiler/dex/quick/arm/int_arm.cc4
-rw-r--r--compiler/dex/quick/gen_common.cc53
-rw-r--r--compiler/dex/quick/gen_invoke.cc2
-rw-r--r--compiler/dex/quick/mips/codegen_mips.h2
-rw-r--r--compiler/dex/quick/mips/int_mips.cc4
-rw-r--r--compiler/dex/quick/mir_to_lir.h13
-rw-r--r--compiler/dex/quick/x86/codegen_x86.h2
-rw-r--r--compiler/dex/quick/x86/int_x86.cc6
10 files changed, 54 insertions, 35 deletions
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h
index 38d37b0700..8a88d618cc 100644
--- a/compiler/dex/compiler_enums.h
+++ b/compiler/dex/compiler_enums.h
@@ -323,7 +323,6 @@ enum X86ConditionCode {
std::ostream& operator<<(std::ostream& os, const X86ConditionCode& kind);
enum ThrowKind {
- kThrowNullPointer,
kThrowArrayBounds,
kThrowConstantArrayBounds,
kThrowNoSuchMethod,
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h
index 13fa6353b0..b0bc11d458 100644
--- a/compiler/dex/quick/arm/codegen_arm.h
+++ b/compiler/dex/quick/arm/codegen_arm.h
@@ -131,7 +131,7 @@ class ArmMir2Lir FINAL : public Mir2Lir {
RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div);
RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div);
void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenDivZeroCheck(RegStorage reg);
+ void GenDivZeroCheckWide(RegStorage reg);
void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method);
void GenExitSequence();
void GenSpecialExitSequence();
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 8b4171de12..c876b3ac69 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -911,12 +911,12 @@ void ArmMir2Lir::GenMultiplyByTwoBitMultiplier(RegLocation rl_src,
}
}
-void ArmMir2Lir::GenDivZeroCheck(RegStorage reg) {
+void ArmMir2Lir::GenDivZeroCheckWide(RegStorage reg) {
DCHECK(reg.IsPair()); // TODO: support k64BitSolo.
RegStorage t_reg = AllocTemp();
NewLIR4(kThumb2OrrRRRs, t_reg.GetReg(), reg.GetLowReg(), reg.GetHighReg(), 0);
FreeTemp(t_reg);
- AddDivZeroSlowPath(kCondEq);
+ GenDivZeroCheck(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 73a123e575..055f60c1c8 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -58,18 +58,18 @@ LIR* Mir2Lir::GenImmedCheck(ConditionCode c_code, RegStorage reg, int imm_val, T
return branch;
}
-void Mir2Lir::AddDivZeroSlowPath(ConditionCode c_code) {
+void Mir2Lir::GenDivZeroException() {
+ LIR* branch = OpUnconditionalBranch(nullptr);
+ AddDivZeroCheckSlowPath(branch);
+}
+
+void Mir2Lir::GenDivZeroCheck(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);
- }
+void Mir2Lir::GenDivZeroCheck(RegStorage reg) {
+ LIR* branch = OpCmpImmBranch(kCondEq, reg, 0, nullptr);
AddDivZeroCheckSlowPath(branch);
}
@@ -80,7 +80,7 @@ void Mir2Lir::AddDivZeroCheckSlowPath(LIR* branch) {
: LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch) {
}
- void Compile() {
+ void Compile() OVERRIDE {
m2l_->ResetRegPool();
m2l_->ResetDefTracking();
GenerateTargetLabel();
@@ -91,6 +91,26 @@ void Mir2Lir::AddDivZeroCheckSlowPath(LIR* branch) {
AddSlowPath(new (arena_) DivZeroCheckSlowPath(this, branch));
}
+LIR* Mir2Lir::GenNullCheck(RegStorage reg) {
+ class NullCheckSlowPath : public Mir2Lir::LIRSlowPath {
+ public:
+ NullCheckSlowPath(Mir2Lir* m2l, LIR* branch)
+ : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch) {
+ }
+
+ void Compile() OVERRIDE {
+ m2l_->ResetRegPool();
+ m2l_->ResetDefTracking();
+ GenerateTargetLabel();
+ m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(4, pThrowNullPointer), true);
+ }
+ };
+
+ LIR* branch = OpCmpImmBranch(kCondEq, reg, 0, nullptr);
+ AddSlowPath(new (arena_) NullCheckSlowPath(this, branch));
+ return branch;
+}
+
/* Perform null-check on a register. */
LIR* Mir2Lir::GenNullCheck(RegStorage m_reg, int opt_flags) {
if (Runtime::Current()->ExplicitNullChecks()) {
@@ -104,7 +124,7 @@ LIR* Mir2Lir::GenExplicitNullCheck(RegStorage m_reg, int opt_flags) {
if (!(cu_->disable_opt & (1 << kNullCheckElimination)) && (opt_flags & MIR_IGNORE_NULL_CHECK)) {
return NULL;
}
- return GenImmedCheck(kCondEq, m_reg, 0, kThrowNullPointer);
+ return GenNullCheck(m_reg);
}
void Mir2Lir::MarkPossibleNullPointerException(int opt_flags) {
@@ -668,9 +688,6 @@ void Mir2Lir::HandleThrowLaunchPads() {
int v2 = lab->operands[3];
const bool target_x86 = cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64;
switch (lab->operands[0]) {
- case kThrowNullPointer:
- func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowNullPointer);
- break;
case kThrowConstantArrayBounds: // v1 is length reg (for Arm/Mips), v2 constant index
// v1 holds the constant array index. Mips/Arm uses v2 for length, x86 reloads.
if (target_x86) {
@@ -1569,7 +1586,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) {
- AddDivZeroSlowPath(kCondEq, rl_src2.reg, 0);
+ GenDivZeroCheck(rl_src2.reg);
}
rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv);
done = true;
@@ -1580,7 +1597,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) {
- AddDivZeroSlowPath(kCondEq, rl_src2.reg, 0);
+ GenDivZeroCheck(rl_src2.reg);
}
rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv);
done = true;
@@ -1595,7 +1612,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest,
RegStorage r_tgt = CallHelperSetup(func_offset);
LoadValueDirectFixed(rl_src1, TargetReg(kArg0));
if (check_zero) {
- AddDivZeroSlowPath(kCondEq, TargetReg(kArg1), 0);
+ GenDivZeroCheck(TargetReg(kArg1));
}
// NOTE: callout here is not a safepoint.
CallHelper(r_tgt, func_offset, false /* not a safepoint */);
@@ -1820,7 +1837,7 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re
case Instruction::REM_INT_LIT8:
case Instruction::REM_INT_LIT16: {
if (lit == 0) {
- AddDivZeroSlowPath(kCondAl, RegStorage::InvalidReg(), 0);
+ GenDivZeroException();
return;
}
if ((opcode == Instruction::DIV_INT) ||
@@ -1994,7 +2011,7 @@ void Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
RegStorage r_tmp2 = RegStorage::MakeRegPair(TargetReg(kArg2), TargetReg(kArg3));
LoadValueDirectWideFixed(rl_src2, r_tmp2);
RegStorage r_tgt = CallHelperSetup(func_offset);
- GenDivZeroCheck(RegStorage::MakeRegPair(TargetReg(kArg2), TargetReg(kArg3)));
+ GenDivZeroCheckWide(RegStorage::MakeRegPair(TargetReg(kArg2), TargetReg(kArg3)));
LoadValueDirectWideFixed(rl_src1, r_tmp1);
// NOTE: callout here is not a safepoint
CallHelper(r_tgt, func_offset, false /* not safepoint */);
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index d827568012..4aae16d103 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -1496,7 +1496,7 @@ void Mir2Lir::GenInvoke(CallInfo* info) {
((cu_->disable_opt & (1 << kNullCheckElimination)) != 0 ||
(info->opt_flags & MIR_IGNORE_NULL_CHECK) == 0)) {
RegLocation rl_obj = LoadValue(info->args[0], kCoreReg);
- GenImmedCheck(kCondEq, rl_obj.reg, 0, kThrowNullPointer);
+ GenNullCheck(rl_obj.reg);
}
return;
}
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index 5089111cc3..40641d670d 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -131,7 +131,7 @@ class MipsMir2Lir FINAL : public Mir2Lir {
RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div);
RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div);
void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenDivZeroCheck(RegStorage reg);
+ void GenDivZeroCheckWide(RegStorage reg);
void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method);
void GenExitSequence();
void GenSpecialExitSequence();
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 0492fdb451..ac0847f22d 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -342,11 +342,11 @@ void MipsMir2Lir::GenMultiplyByTwoBitMultiplier(RegLocation rl_src,
}
}
-void MipsMir2Lir::GenDivZeroCheck(RegStorage reg) {
+void MipsMir2Lir::GenDivZeroCheckWide(RegStorage reg) {
DCHECK(reg.IsPair()); // TODO: support k64BitSolo.
RegStorage t_reg = AllocTemp();
OpRegRegReg(kOpOr, t_reg, reg.GetLow(), reg.GetHigh());
- AddDivZeroSlowPath(kCondEq, t_reg, 0);
+ GenDivZeroCheck(kCondEq);
FreeTemp(t_reg);
}
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 6dbeb34205..65910e9eb8 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -562,8 +562,12 @@ class Mir2Lir : public Backend {
void HandleThrowLaunchPads();
void HandleSlowPaths();
void GenBarrier();
- void AddDivZeroSlowPath(ConditionCode c_code);
- void AddDivZeroSlowPath(ConditionCode c_code, RegStorage reg, int imm_val);
+ void GenDivZeroException();
+ // c_code holds condition code that's generated from testing divisor against 0.
+ void GenDivZeroCheck(ConditionCode c_code);
+ // reg holds divisor.
+ void GenDivZeroCheck(RegStorage reg);
+ LIR* GenNullCheck(RegStorage reg);
void MarkPossibleNullPointerException(int opt_flags);
void MarkPossibleStackOverflowException();
void ForceImplicitNullCheck(RegStorage reg, int opt_flags);
@@ -960,10 +964,9 @@ class Mir2Lir : public Backend {
* @brief Used for generating code that throws ArithmeticException if both registers are zero.
* @details This is used for generating DivideByZero checks when divisor is held in two
* separate registers.
- * @param reg_lo The register holding the lower 32-bits.
- * @param reg_hi The register holding the upper 32-bits.
+ * @param reg The register holding the pair of 32-bit values.
*/
- virtual void GenDivZeroCheck(RegStorage reg) = 0;
+ virtual void GenDivZeroCheckWide(RegStorage reg) = 0;
virtual void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) = 0;
virtual void GenExitSequence() = 0;
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index af2a140296..0b9823d667 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -135,7 +135,7 @@ class X86Mir2Lir FINAL : public Mir2Lir {
RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div);
RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div);
void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
- void GenDivZeroCheck(RegStorage reg);
+ void GenDivZeroCheckWide(RegStorage reg);
void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method);
void GenExitSequence();
void GenSpecialExitSequence();
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index a5f3b61685..4ffb9a4c38 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.
- AddDivZeroSlowPath(kCondEq, rs_r1, 0);
+ GenDivZeroCheck(rs_r1);
}
// Have to catch 0x80000000/-1 case, or we will get an exception!
@@ -876,7 +876,7 @@ void X86Mir2Lir::GenMultiplyByTwoBitMultiplier(RegLocation rl_src,
}
}
-void X86Mir2Lir::GenDivZeroCheck(RegStorage reg) {
+void X86Mir2Lir::GenDivZeroCheckWide(RegStorage reg) {
DCHECK(reg.IsPair()); // TODO: allow 64BitSolo.
// We are not supposed to clobber the incoming storage, so allocate a temporary.
RegStorage t_reg = AllocTemp();
@@ -885,7 +885,7 @@ void X86Mir2Lir::GenDivZeroCheck(RegStorage reg) {
OpRegRegReg(kOpOr, t_reg, reg.GetLow(), reg.GetHigh());
// In case of zero, throw ArithmeticException.
- AddDivZeroSlowPath(kCondEq);
+ GenDivZeroCheck(kCondEq);
// The temp is no longer needed so free it at this time.
FreeTemp(t_reg);