Revert "Use LIRSlowPath for throwing ArrayOutOfBoundsException."
This reverts commit 9d46314a309aff327f9913789b5f61200c162609.
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 =