diff options
| author | 2014-04-17 23:11:17 -0700 | |
|---|---|---|
| committer | 2014-04-17 23:11:17 -0700 | |
| commit | 7fff544c38f0dec3a213236bb785c3ca13d21a0f (patch) | |
| tree | ac125fbdbf6f863562f6bb543a70ecab610e96e1 | |
| parent | 6b8a2674119a9251de4d713cd2d1ff10ae21a66c (diff) | |
Revert "Use LIRSlowPath for throwing ArrayOutOfBoundsException."
This reverts commit 9d46314a309aff327f9913789b5f61200c162609.
| -rw-r--r-- | compiler/dex/compiler_enums.h | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 12 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_common.cc | 107 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_invoke.cc | 25 | ||||
| -rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 8 | ||||
| -rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 6 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/int_x86.cc | 82 |
8 files changed, 75 insertions, 169 deletions
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h index 6f4fa3ab50..8a88d618cc 100644 --- a/compiler/dex/compiler_enums.h +++ b/compiler/dex/compiler_enums.h @@ -323,6 +323,8 @@ enum X86ConditionCode { 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 d5b34a5c39..c876b3ac69 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -1167,9 +1167,9 @@ void ArmMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, 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 @@ void ArmMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, 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 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, } 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 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, 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 bb19516b96..1847921ccb 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -91,62 +91,6 @@ void Mir2Lir::AddDivZeroCheckSlowPath(LIR* branch) { 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 @@ void Mir2Lir::HandleThrowLaunchPads() { 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 758096b954..4aae16d103 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -255,27 +255,12 @@ void Mir2Lir::CallRuntimeHelperRegLocationRegLocation(ThreadOffset<4> helper_off 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::CallRuntimeHelperRegReg(ThreadOffset<4> helper_offset, RegStorage 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 237572034d..60358b495c 100644 --- a/compiler/dex/quick/mips/int_mips.cc +++ b/compiler/dex/quick/mips/int_mips.cc @@ -513,7 +513,7 @@ void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, 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 @@ void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, 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 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, 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 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, } 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 a7a3635348..65910e9eb8 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -567,8 +567,6 @@ class Mir2Lir : public Backend { 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 @@ class Mir2Lir : public Backend { 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 7be7c23761..0b9823d667 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -136,8 +136,6 @@ class X86Mir2Lir FINAL : public Mir2Lir { 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 e45e7a870e..4ffb9a4c38 100644 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -891,78 +891,6 @@ void X86Mir2Lir::GenDivZeroCheckWide(RegStorage reg) { 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 @@ void X86Mir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, 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 @@ void X86Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, 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)) { |