summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2014-11-21 10:12:32 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-11-21 10:12:33 +0000
commit4514d2ac529064819d4f02699527764afa140008 (patch)
tree209631ac7f2826628e6a5c7ee30075d8760c7c1a /compiler/dex/quick
parent23442bea869747da0361e96ec2704956de54ded7 (diff)
parentbf535be514570fc33fc0a6347a87dcd9097d9bfd (diff)
downloadart-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.cc8
-rw-r--r--compiler/dex/quick/arm/codegen_arm.h4
-rw-r--r--compiler/dex/quick/arm64/call_arm64.cc8
-rw-r--r--compiler/dex/quick/arm64/codegen_arm64.h5
-rw-r--r--compiler/dex/quick/codegen_util.cc9
-rw-r--r--compiler/dex/quick/gen_common.cc19
-rw-r--r--compiler/dex/quick/mips/call_mips.cc8
-rw-r--r--compiler/dex/quick/mips/codegen_mips.h4
-rw-r--r--compiler/dex/quick/mir_to_lir.h14
-rw-r--r--compiler/dex/quick/x86/call_x86.cc9
-rw-r--r--compiler/dex/quick/x86/codegen_x86.h5
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.