Revert "Use LIRSlowPath for throwing ArrayOutOfBoundsException."
This reverts commit 9d46314a309aff327f9913789b5f61200c162609.
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h
index 6f4fa3a..8a88d61 100644
--- a/compiler/dex/compiler_enums.h
+++ b/compiler/dex/compiler_enums.h
@@ -323,6 +323,8 @@
std::ostream& operator<<(std::ostream& os, const X86ConditionCode& kind);
enum ThrowKind {
+ kThrowArrayBounds,
+ kThrowConstantArrayBounds,
kThrowNoSuchMethod,
};
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index d5b34a5..c876b3a 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -1167,9 +1167,9 @@
if (needs_range_check) {
if (constant_index) {
- GenArrayBoundsCheck(mir_graph_->ConstantValue(rl_index), reg_len);
+ GenImmedCheck(kCondLs, reg_len, mir_graph_->ConstantValue(rl_index), kThrowConstantArrayBounds);
} else {
- GenArrayBoundsCheck(rl_index.reg, reg_len);
+ GenRegRegCheck(kCondLs, reg_len, rl_index.reg, kThrowArrayBounds);
}
FreeTemp(reg_len);
}
@@ -1196,7 +1196,7 @@
rl_result = EvalLoc(rl_dest, reg_class, true);
if (needs_range_check) {
- GenArrayBoundsCheck(rl_index.reg, reg_len);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
LoadBaseIndexed(reg_ptr, rl_index.reg, rl_result.reg, scale, size);
@@ -1271,9 +1271,9 @@
}
if (needs_range_check) {
if (constant_index) {
- GenArrayBoundsCheck(mir_graph_->ConstantValue(rl_index), reg_len);
+ GenImmedCheck(kCondLs, reg_len, mir_graph_->ConstantValue(rl_index), kThrowConstantArrayBounds);
} else {
- GenArrayBoundsCheck(rl_index.reg, reg_len);
+ GenRegRegCheck(kCondLs, reg_len, rl_index.reg, kThrowArrayBounds);
}
FreeTemp(reg_len);
}
@@ -1289,7 +1289,7 @@
OpRegRegImm(kOpAdd, reg_ptr, rl_array.reg, data_offset);
rl_src = LoadValue(rl_src, reg_class);
if (needs_range_check) {
- GenArrayBoundsCheck(rl_index.reg, reg_len);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
StoreBaseIndexed(reg_ptr, rl_index.reg, rl_src.reg, scale, size);
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index bb19516..1847921 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -91,62 +91,6 @@
AddSlowPath(new (arena_) DivZeroCheckSlowPath(this, branch));
}
-void Mir2Lir::GenArrayBoundsCheck(RegStorage index, RegStorage length) {
- class ArrayBoundsCheckSlowPath : public Mir2Lir::LIRSlowPath {
- public:
- ArrayBoundsCheckSlowPath(Mir2Lir* m2l, LIR* branch, RegStorage index, RegStorage length)
- : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch),
- index_(index), length_(length) {
- }
-
- void Compile() OVERRIDE {
- m2l_->ResetRegPool();
- m2l_->ResetDefTracking();
- GenerateTargetLabel();
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
- index_, length_, true);
- }
-
- private:
- RegStorage index_;
- RegStorage length_;
- };
-
- LIR* branch = OpCmpBranch(kCondUge, index, length, nullptr);
- AddSlowPath(new (arena_) ArrayBoundsCheckSlowPath(this, branch, index, length));
-}
-
-void Mir2Lir::GenArrayBoundsCheck(int index, RegStorage length) {
- class ArrayBoundsCheckSlowPath : public Mir2Lir::LIRSlowPath {
- public:
- ArrayBoundsCheckSlowPath(Mir2Lir* m2l, LIR* branch, int index, RegStorage length)
- : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch),
- index_(index), length_(length) {
- }
-
- void Compile() OVERRIDE {
- m2l_->ResetRegPool();
- m2l_->ResetDefTracking();
- GenerateTargetLabel();
- // kArg0 will be used to hold the constant index.
- if (length_.GetReg() == m2l_->TargetReg(kArg0).GetReg()) {
- m2l_->OpRegCopy(m2l_->TargetReg(kArg1), length_);
- length_ = m2l_->TargetReg(kArg1);
- }
- m2l_->LoadConstant(m2l_->TargetReg(kArg0), index_);
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
- m2l_->TargetReg(kArg0), length_, true);
- }
-
- private:
- int index_;
- RegStorage length_;
- };
-
- LIR* branch = OpCmpImmBranch(kCondLs, length, index, nullptr);
- AddSlowPath(new (arena_) ArrayBoundsCheckSlowPath(this, branch, index, length));
-}
-
LIR* Mir2Lir::GenNullCheck(RegStorage reg) {
class NullCheckSlowPath : public Mir2Lir::LIRSlowPath {
public:
@@ -741,7 +685,58 @@
AppendLIR(lab);
ThreadOffset<4> func_offset(-1);
int v1 = lab->operands[2];
+ int v2 = lab->operands[3];
+ const bool target_x86 = cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64;
switch (lab->operands[0]) {
+ 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) {
+ OpRegMem(kOpMov, TargetReg(kArg1), RegStorage::Solo32(v1),
+ mirror::Array::LengthOffset().Int32Value());
+ } else {
+ OpRegCopy(TargetReg(kArg1), RegStorage::Solo32(v1));
+ }
+ // Make sure the following LoadConstant doesn't mess with kArg1.
+ LockTemp(TargetReg(kArg1));
+ LoadConstant(TargetReg(kArg0), v2);
+ func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds);
+ break;
+ case kThrowArrayBounds:
+ // Move v1 (array index) to kArg0 and v2 (array length) to kArg1
+ if (v2 != TargetReg(kArg0).GetReg()) {
+ OpRegCopy(TargetReg(kArg0), RegStorage::Solo32(v1));
+ if (target_x86) {
+ // x86 leaves the array pointer in v2, so load the array length that the handler expects
+ OpRegMem(kOpMov, TargetReg(kArg1), RegStorage::Solo32(v2),
+ mirror::Array::LengthOffset().Int32Value());
+ } else {
+ OpRegCopy(TargetReg(kArg1), RegStorage::Solo32(v2));
+ }
+ } else {
+ if (v1 == TargetReg(kArg1).GetReg()) {
+ // Swap v1 and v2, using kArg2 as a temp
+ OpRegCopy(TargetReg(kArg2), RegStorage::Solo32(v1));
+ if (target_x86) {
+ // x86 leaves the array pointer in v2; load the array length that the handler expects
+ OpRegMem(kOpMov, TargetReg(kArg1), RegStorage::Solo32(v2),
+ mirror::Array::LengthOffset().Int32Value());
+ } else {
+ OpRegCopy(TargetReg(kArg1), RegStorage::Solo32(v2));
+ }
+ OpRegCopy(TargetReg(kArg0), TargetReg(kArg2));
+ } else {
+ if (target_x86) {
+ // x86 leaves the array pointer in v2; load the array length that the handler expects
+ OpRegMem(kOpMov, TargetReg(kArg1), RegStorage::Solo32(v2),
+ mirror::Array::LengthOffset().Int32Value());
+ } else {
+ OpRegCopy(TargetReg(kArg1), RegStorage::Solo32(v2));
+ }
+ OpRegCopy(TargetReg(kArg0), RegStorage::Solo32(v1));
+ }
+ }
+ func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds);
+ break;
case kThrowNoSuchMethod:
OpRegCopy(TargetReg(kArg0), RegStorage::Solo32(v1));
func_offset =
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 758096b..4aae16d 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -255,27 +255,12 @@
CallHelper(r_tgt, helper_offset, safepoint_pc);
}
-void Mir2Lir::CopyToArgumentRegs(RegStorage arg0, RegStorage arg1) {
- if (arg1.GetReg() == TargetReg(kArg0).GetReg()) {
- if (arg0.GetReg() == TargetReg(kArg1).GetReg()) {
- // Swap kArg0 and kArg1 with kArg2 as temp.
- OpRegCopy(TargetReg(kArg2), arg1);
- OpRegCopy(TargetReg(kArg0), arg0);
- OpRegCopy(TargetReg(kArg1), TargetReg(kArg2));
- } else {
- OpRegCopy(TargetReg(kArg1), arg1);
- OpRegCopy(TargetReg(kArg0), arg0);
- }
- } else {
- OpRegCopy(TargetReg(kArg0), arg0);
- OpRegCopy(TargetReg(kArg1), arg1);
- }
-}
-
void Mir2Lir::CallRuntimeHelperRegReg(ThreadOffset<4> helper_offset, RegStorage arg0,
RegStorage arg1, bool safepoint_pc) {
RegStorage r_tgt = CallHelperSetup(helper_offset);
- CopyToArgumentRegs(arg0, arg1);
+ DCHECK_NE(TargetReg(kArg0).GetReg(), arg1.GetReg()); // check copy into arg0 won't clobber arg1
+ OpRegCopy(TargetReg(kArg0), arg0);
+ OpRegCopy(TargetReg(kArg1), arg1);
ClobberCallerSave();
CallHelper(r_tgt, helper_offset, safepoint_pc);
}
@@ -283,7 +268,9 @@
void Mir2Lir::CallRuntimeHelperRegRegImm(ThreadOffset<4> helper_offset, RegStorage arg0,
RegStorage arg1, int arg2, bool safepoint_pc) {
RegStorage r_tgt = CallHelperSetup(helper_offset);
- CopyToArgumentRegs(arg0, arg1);
+ DCHECK_NE(TargetReg(kArg0).GetReg(), arg1.GetReg()); // check copy into arg0 won't clobber arg1
+ OpRegCopy(TargetReg(kArg0), arg0);
+ OpRegCopy(TargetReg(kArg1), arg1);
LoadConstant(TargetReg(kArg2), arg2);
ClobberCallerSave();
CallHelper(r_tgt, helper_offset, safepoint_pc);
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 2375720..60358b4 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -513,7 +513,7 @@
rl_result = EvalLoc(rl_dest, reg_class, true);
if (needs_range_check) {
- GenArrayBoundsCheck(rl_index.reg, reg_len);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
LoadBaseDispWide(reg_ptr, 0, rl_result.reg, INVALID_SREG);
@@ -524,7 +524,7 @@
rl_result = EvalLoc(rl_dest, reg_class, true);
if (needs_range_check) {
- GenArrayBoundsCheck(rl_index.reg, reg_len);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
LoadBaseIndexed(reg_ptr, rl_index.reg, rl_result.reg, scale, size);
@@ -590,7 +590,7 @@
rl_src = LoadValueWide(rl_src, reg_class);
if (needs_range_check) {
- GenArrayBoundsCheck(rl_index.reg, reg_len);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
@@ -598,7 +598,7 @@
} else {
rl_src = LoadValue(rl_src, reg_class);
if (needs_range_check) {
- GenArrayBoundsCheck(rl_index.reg, reg_len);
+ GenRegRegCheck(kCondUge, rl_index.reg, reg_len, kThrowArrayBounds);
FreeTemp(reg_len);
}
StoreBaseIndexed(reg_ptr, rl_index.reg, rl_src.reg, scale, size);
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index a7a3635..65910e9 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -567,8 +567,6 @@
void GenDivZeroCheck(ConditionCode c_code);
// reg holds divisor.
void GenDivZeroCheck(RegStorage reg);
- void GenArrayBoundsCheck(RegStorage index, RegStorage length);
- void GenArrayBoundsCheck(int index, RegStorage length);
LIR* GenNullCheck(RegStorage reg);
void MarkPossibleNullPointerException(int opt_flags);
void MarkPossibleStackOverflowException();
@@ -1229,10 +1227,6 @@
void AddDivZeroCheckSlowPath(LIR* branch);
- // Copy arg0 and arg1 to kArg0 and kArg1 safely, possibly using
- // kArg2 as temp.
- void CopyToArgumentRegs(RegStorage arg0, RegStorage arg1);
-
public:
// TODO: add accessors for these.
LIR* literal_list_; // Constants.
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index 7be7c23..0b9823d 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -136,8 +136,6 @@
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 GenDivZeroCheckWide(RegStorage reg);
- void GenArrayBoundsCheck(RegStorage index, RegStorage array_base, int len_offset);
- void GenArrayBoundsCheck(int index, RegStorage array_base, int len_offset);
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 e45e7a8..4ffb9a4 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -891,78 +891,6 @@
FreeTemp(t_reg);
}
-void X86Mir2Lir::GenArrayBoundsCheck(RegStorage index,
- RegStorage array_base,
- int len_offset) {
- class ArrayBoundsCheckSlowPath : public Mir2Lir::LIRSlowPath {
- public:
- ArrayBoundsCheckSlowPath(Mir2Lir* m2l, LIR* branch,
- RegStorage index, RegStorage array_base, int len_offset)
- : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch),
- index_(index), array_base_(array_base), len_offset_(len_offset) {
- }
-
- void Compile() OVERRIDE {
- m2l_->ResetRegPool();
- m2l_->ResetDefTracking();
- GenerateTargetLabel();
- // Load array length to array_base_.
- m2l_->OpRegMem(kOpMov, array_base_, array_base_, len_offset_);
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
- index_, array_base_, true);
- }
-
- private:
- RegStorage index_;
- RegStorage array_base_;
- int len_offset_;
- };
-
- OpRegMem(kOpCmp, index, array_base, len_offset);
- LIR* branch = OpCondBranch(kCondUge, nullptr);
- AddSlowPath(new (arena_) ArrayBoundsCheckSlowPath(this, branch,
- index, array_base, len_offset));
-}
-
-void X86Mir2Lir::GenArrayBoundsCheck(int index,
- RegStorage array_base,
- int len_offset) {
- class ArrayBoundsCheckSlowPath : public Mir2Lir::LIRSlowPath {
- public:
- ArrayBoundsCheckSlowPath(Mir2Lir* m2l, LIR* branch,
- int index, RegStorage array_base, int len_offset)
- : LIRSlowPath(m2l, m2l->GetCurrentDexPc(), branch),
- index_(index), array_base_(array_base), len_offset_(len_offset) {
- }
-
- void Compile() OVERRIDE {
- m2l_->ResetRegPool();
- m2l_->ResetDefTracking();
- GenerateTargetLabel();
- // kArg0 will be used to hold the constant index.
- if (array_base_.GetReg() == m2l_->TargetReg(kArg0).GetReg()) {
- m2l_->OpRegCopy(m2l_->TargetReg(kArg1), array_base_);
- array_base_ = m2l_->TargetReg(kArg1);
- }
- m2l_->LoadConstant(m2l_->TargetReg(kArg0), index_);
- // Load array length to kArg1.
- m2l_->OpRegMem(kOpMov, m2l_->TargetReg(kArg1), array_base_, len_offset_);
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
- m2l_->TargetReg(kArg0), m2l_->TargetReg(kArg1), true);
- }
-
- private:
- int index_;
- RegStorage array_base_;
- int len_offset_;
- };
-
- NewLIR3(IS_SIMM8(index) ? kX86Cmp32MI8 : kX86Cmp32MI, array_base.GetReg(), len_offset, index);
- LIR* branch = OpCondBranch(kCondLs, nullptr);
- AddSlowPath(new (arena_) ArrayBoundsCheckSlowPath(this, branch,
- index, array_base, len_offset));
-}
-
// Test suspend flag, return target of taken suspend branch
LIR* X86Mir2Lir::OpTestSuspend(LIR* target) {
OpTlsCmp(Thread::ThreadFlagsOffset<4>(), 0);
@@ -1420,9 +1348,10 @@
if (!(opt_flags & MIR_IGNORE_RANGE_CHECK)) {
if (constant_index) {
- GenArrayBoundsCheck(constant_index_value, rl_array.reg, len_offset);
+ GenMemImmedCheck(kCondLs, rl_array.reg, len_offset,
+ constant_index_value, kThrowConstantArrayBounds);
} else {
- GenArrayBoundsCheck(rl_index.reg, rl_array.reg, len_offset);
+ GenRegMemCheck(kCondUge, rl_index.reg, rl_array.reg, len_offset, kThrowArrayBounds);
}
}
rl_result = EvalLoc(rl_dest, reg_class, true);
@@ -1471,9 +1400,10 @@
if (!(opt_flags & MIR_IGNORE_RANGE_CHECK)) {
if (constant_index) {
- GenArrayBoundsCheck(constant_index_value, rl_array.reg, len_offset);
+ GenMemImmedCheck(kCondLs, rl_array.reg, len_offset,
+ constant_index_value, kThrowConstantArrayBounds);
} else {
- GenArrayBoundsCheck(rl_index.reg, rl_array.reg, len_offset);
+ GenRegMemCheck(kCondUge, rl_index.reg, rl_array.reg, len_offset, kThrowArrayBounds);
}
}
if ((size == kLong) || (size == kDouble)) {