diff options
author | Vladimir Marko <vmarko@google.com> | 2014-11-21 10:12:32 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-11-21 10:12:33 +0000 |
commit | 4514d2ac529064819d4f02699527764afa140008 (patch) | |
tree | 209631ac7f2826628e6a5c7ee30075d8760c7c1a /compiler/dex/quick | |
parent | 23442bea869747da0361e96ec2704956de54ded7 (diff) | |
parent | bf535be514570fc33fc0a6347a87dcd9097d9bfd (diff) | |
download | art-4514d2ac529064819d4f02699527764afa140008.zip art-4514d2ac529064819d4f02699527764afa140008.tar.gz art-4514d2ac529064819d4f02699527764afa140008.tar.bz2 |
Merge "Add card mark to filled-new-array."
Diffstat (limited to 'compiler/dex/quick')
-rw-r--r-- | compiler/dex/quick/arm/call_arm.cc | 8 | ||||
-rw-r--r-- | compiler/dex/quick/arm/codegen_arm.h | 4 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/call_arm64.cc | 8 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/codegen_arm64.h | 5 | ||||
-rw-r--r-- | compiler/dex/quick/codegen_util.cc | 9 | ||||
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 19 | ||||
-rw-r--r-- | compiler/dex/quick/mips/call_mips.cc | 8 | ||||
-rw-r--r-- | compiler/dex/quick/mips/codegen_mips.h | 4 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 14 | ||||
-rw-r--r-- | compiler/dex/quick/x86/call_x86.cc | 9 | ||||
-rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 5 |
11 files changed, 56 insertions, 37 deletions
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc index a3b4df3..f15d707 100644 --- a/compiler/dex/quick/arm/call_arm.cc +++ b/compiler/dex/quick/arm/call_arm.cc @@ -288,18 +288,12 @@ void ArmMir2Lir::GenMoveException(RegLocation rl_dest) { StoreValue(rl_dest, rl_result); } -/* - * Mark garbage collection card. Skip if the value we're storing is null. - */ -void ArmMir2Lir::MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) { +void ArmMir2Lir::UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) { RegStorage reg_card_base = AllocTemp(); RegStorage reg_card_no = AllocTemp(); - LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, NULL); LoadWordDisp(rs_rARM_SELF, Thread::CardTableOffset<4>().Int32Value(), reg_card_base); OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift); StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0, kUnsignedByte); - LIR* target = NewLIR0(kPseudoTargetLabel); - branch_over->target = target; FreeTemp(reg_card_base); FreeTemp(reg_card_no); } diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h index d235199..e8d0c32 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -106,7 +106,9 @@ class ArmMir2Lir FINAL : public Mir2Lir { OpSize size, VolatileKind is_volatile) OVERRIDE; LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale, OpSize size) OVERRIDE; - void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg); + + /// @copydoc Mir2Lir::UnconditionallyMarkGCCard(RegStorage) + void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE; // Required for target - register utilities. RegStorage TargetReg(SpecialTargetRegister reg) OVERRIDE; diff --git a/compiler/dex/quick/arm64/call_arm64.cc b/compiler/dex/quick/arm64/call_arm64.cc index 3e5b7bf..089e4b6 100644 --- a/compiler/dex/quick/arm64/call_arm64.cc +++ b/compiler/dex/quick/arm64/call_arm64.cc @@ -251,20 +251,14 @@ void Arm64Mir2Lir::GenMoveException(RegLocation rl_dest) { StoreValue(rl_dest, rl_result); } -/* - * Mark garbage collection card. Skip if the value we're storing is null. - */ -void Arm64Mir2Lir::MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) { +void Arm64Mir2Lir::UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) { RegStorage reg_card_base = AllocTempWide(); RegStorage reg_card_no = AllocTempWide(); // Needs to be wide as addr is ref=64b - LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, NULL); LoadWordDisp(rs_xSELF, Thread::CardTableOffset<8>().Int32Value(), reg_card_base); OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift); // TODO(Arm64): generate "strb wB, [xB, wC, uxtw]" rather than "strb wB, [xB, xC]"? StoreBaseIndexed(reg_card_base, reg_card_no, As32BitReg(reg_card_base), 0, kUnsignedByte); - LIR* target = NewLIR0(kPseudoTargetLabel); - branch_over->target = target; FreeTemp(reg_card_base); FreeTemp(reg_card_no); } diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h index 5182a89..5e10f80 100644 --- a/compiler/dex/quick/arm64/codegen_arm64.h +++ b/compiler/dex/quick/arm64/codegen_arm64.h @@ -94,7 +94,10 @@ class Arm64Mir2Lir FINAL : public Mir2Lir { LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale, OpSize size) OVERRIDE; LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale) OVERRIDE; - void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) OVERRIDE; + + /// @copydoc Mir2Lir::UnconditionallyMarkGCCard(RegStorage) + void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE; + LIR* OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg, int offset, int check_value, LIR* target, LIR** compare) OVERRIDE; diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index 9403516..80cb535 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -314,6 +314,15 @@ void Mir2Lir::UpdateLIROffsets() { } } +void Mir2Lir::MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) { + DCHECK(val_reg.Valid()); + DCHECK_EQ(val_reg.Is64Bit(), cu_->target64); + LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, nullptr); + UnconditionallyMarkGCCard(tgt_addr_reg); + LIR* target = NewLIR0(kPseudoTargetLabel); + branch_over->target = target; +} + /* Dump instructions and constant pool contents */ void Mir2Lir::CodegenDump() { LOG(INFO) << "Dumping LIR insns for " diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 98ddc36..c00f90b 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -416,8 +416,8 @@ void Mir2Lir::GenFilledNewArray(CallInfo* info) { // share array alignment with ints (see comment at head of function) size_t component_size = sizeof(int32_t); - // Having a range of 0 is legal - if (info->is_range && (elems > 0)) { + if (elems > 5) { + DCHECK(info->is_range); // Non-range insn can't encode more than 5 elems. /* * Bit of ugliness here. We're going generate a mem copy loop * on the register range, but it is possible that some regs @@ -487,7 +487,11 @@ void Mir2Lir::GenFilledNewArray(CallInfo* info) { OpRegRegImm(kOpAdd, ref_reg, r_dst, -mirror::Array::DataOffset(component_size).Int32Value()); } - } else if (!info->is_range) { + FreeTemp(r_idx); + FreeTemp(r_dst); + FreeTemp(r_src); + } else { + DCHECK_LE(elems, 5); // Usually but not necessarily non-range. // TUNING: interleave for (int i = 0; i < elems; i++) { RegLocation rl_arg; @@ -507,6 +511,15 @@ void Mir2Lir::GenFilledNewArray(CallInfo* info) { } } } + if (elems != 0 && info->args[0].ref) { + // If there is at least one potentially non-null value, unconditionally mark the GC card. + for (int i = 0; i < elems; i++) { + if (!mir_graph_->IsConstantNullRef(info->args[i])) { + UnconditionallyMarkGCCard(ref_reg); + break; + } + } + } if (info->result.location != kLocInvalid) { StoreValue(info->result, GetReturn(kRefReg)); } diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc index ed73ef0..3bb81bf 100644 --- a/compiler/dex/quick/mips/call_mips.cc +++ b/compiler/dex/quick/mips/call_mips.cc @@ -222,19 +222,13 @@ void MipsMir2Lir::GenMoveException(RegLocation rl_dest) { StoreValue(rl_dest, rl_result); } -/* - * Mark garbage collection card. Skip if the value we're storing is null. - */ -void MipsMir2Lir::MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) { +void MipsMir2Lir::UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) { RegStorage reg_card_base = AllocTemp(); RegStorage reg_card_no = AllocTemp(); - LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, NULL); // NOTE: native pointer. LoadWordDisp(rs_rMIPS_SELF, Thread::CardTableOffset<4>().Int32Value(), reg_card_base); OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift); StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0, kUnsignedByte); - LIR* target = NewLIR0(kPseudoTargetLabel); - branch_over->target = target; FreeTemp(reg_card_base); FreeTemp(reg_card_no); } diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h index 7e9d80d..e08846c 100644 --- a/compiler/dex/quick/mips/codegen_mips.h +++ b/compiler/dex/quick/mips/codegen_mips.h @@ -49,7 +49,9 @@ class MipsMir2Lir FINAL : public Mir2Lir { OpSize size) OVERRIDE; LIR* GenAtomic64Load(RegStorage r_base, int displacement, RegStorage r_dest); LIR* GenAtomic64Store(RegStorage r_base, int displacement, RegStorage r_src); - void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg); + + /// @copydoc Mir2Lir::UnconditionallyMarkGCCard(RegStorage) + void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE; // Required for target - register utilities. RegStorage Solo64ToPair64(RegStorage reg); diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 13ebc1e..886b238 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -1071,6 +1071,13 @@ class Mir2Lir : public Backend { // Update LIR for verbose listings. void UpdateLIROffsets(); + /** + * @brief Mark a garbage collection card. Skip if the stored value is null. + * @param val_reg the register holding the stored value to check against null. + * @param tgt_addr_reg the address of the object or array where the value was stored. + */ + void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg); + /* * @brief Load the address of the dex method into the register. * @param target_method The MethodReference of the method to be invoked. @@ -1139,7 +1146,12 @@ class Mir2Lir : public Backend { OpSize size, VolatileKind is_volatile) = 0; virtual LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale, OpSize size) = 0; - virtual void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) = 0; + + /** + * @brief Unconditionally mark a garbage collection card. + * @param tgt_addr_reg the address of the object or array where the value was stored. + */ + virtual void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) = 0; // Required for target - register utilities. diff --git a/compiler/dex/quick/x86/call_x86.cc b/compiler/dex/quick/x86/call_x86.cc index 61dcc28..a808459 100644 --- a/compiler/dex/quick/x86/call_x86.cc +++ b/compiler/dex/quick/x86/call_x86.cc @@ -136,23 +136,16 @@ void X86Mir2Lir::GenMoveException(RegLocation rl_dest) { StoreValue(rl_dest, rl_result); } -/* - * Mark garbage collection card. Skip if the value we're storing is null. - */ -void X86Mir2Lir::MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) { +void X86Mir2Lir::UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) { DCHECK_EQ(tgt_addr_reg.Is64Bit(), cu_->target64); - DCHECK_EQ(val_reg.Is64Bit(), cu_->target64); RegStorage reg_card_base = AllocTempRef(); RegStorage reg_card_no = AllocTempRef(); - LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, NULL); int ct_offset = cu_->target64 ? Thread::CardTableOffset<8>().Int32Value() : Thread::CardTableOffset<4>().Int32Value(); NewLIR2(cu_->target64 ? kX86Mov64RT : kX86Mov32RT, reg_card_base.GetReg(), ct_offset); OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift); StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0, kUnsignedByte); - LIR* target = NewLIR0(kPseudoTargetLabel); - branch_over->target = target; FreeTemp(reg_card_base); FreeTemp(reg_card_no); } diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h index d57dffb..26641f8 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -94,7 +94,10 @@ class X86Mir2Lir : public Mir2Lir { OpSize size, VolatileKind is_volatile) OVERRIDE; LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale, OpSize size) OVERRIDE; - void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) OVERRIDE; + + /// @copydoc Mir2Lir::UnconditionallyMarkGCCard(RegStorage) + void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE; + void GenImplicitNullCheck(RegStorage reg, int opt_flags) OVERRIDE; // Required for target - register utilities. |