Skip card mark when storing known null reference
We don't need to mark the gc card if storing a null reference.
Change-Id: I445db196a097ed92b67b8bf1e6b486c6fac7d08f
diff --git a/src/compiler/codegen/arm/int_arm.cc b/src/compiler/codegen/arm/int_arm.cc
index 5a9786c..d908bf5 100644
--- a/src/compiler/codegen/arm/int_arm.cc
+++ b/src/compiler/codegen/arm/int_arm.cc
@@ -457,7 +457,7 @@
RegLocation rl_object = LoadValue(cu, rl_src_obj, kCoreReg);
RegLocation rl_new_value = LoadValue(cu, rl_src_new_value, kCoreReg);
- if (need_write_barrier) {
+ if (need_write_barrier && !IsConstantNullRef(cu, rl_new_value)) {
// Mark card for object assuming new value is stored.
MarkGCCard(cu, rl_new_value.low_reg, rl_object.low_reg);
}
@@ -946,7 +946,9 @@
StoreBaseIndexed(cu, r_ptr, r_index, r_value, scale, kWord);
FreeTemp(cu, r_ptr);
FreeTemp(cu, r_index);
- MarkGCCard(cu, r_value, r_array);
+ if (!IsConstantNullRef(cu, rl_src)) {
+ MarkGCCard(cu, r_value, r_array);
+ }
}
bool ArmCodegen::GenShiftImmOpLong(CompilationUnit* cu, Instruction::Code opcode,
diff --git a/src/compiler/codegen/gen_common.cc b/src/compiler/codegen/gen_common.cc
index a4c8d0c..40ec2bf 100644
--- a/src/compiler/codegen/gen_common.cc
+++ b/src/compiler/codegen/gen_common.cc
@@ -425,7 +425,7 @@
if (is_volatile) {
GenMemBarrier(cu, kStoreLoad);
}
- if (is_object) {
+ if (is_object && !IsConstantNullRef(cu, rl_src)) {
MarkGCCard(cu, rl_src.low_reg, rBase);
}
FreeTemp(cu, rBase);
@@ -766,7 +766,7 @@
if (is_volatile) {
GenMemBarrier(cu, kLoadLoad);
}
- if (is_object) {
+ if (is_object && !IsConstantNullRef(cu, rl_src)) {
MarkGCCard(cu, rl_src.low_reg, rl_obj.low_reg);
}
}
diff --git a/src/compiler/codegen/mips/int_mips.cc b/src/compiler/codegen/mips/int_mips.cc
index 675cf8d..41d289e 100644
--- a/src/compiler/codegen/mips/int_mips.cc
+++ b/src/compiler/codegen/mips/int_mips.cc
@@ -639,7 +639,9 @@
StoreBaseIndexed(cu, r_ptr, r_index, r_value, scale, kWord);
FreeTemp(cu, r_ptr);
FreeTemp(cu, r_index);
- MarkGCCard(cu, r_value, r_array);
+ if (!IsConstantNullRef(cu, rl_src)) {
+ MarkGCCard(cu, r_value, r_array);
+ }
}
bool MipsCodegen::GenShiftImmOpLong(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
diff --git a/src/compiler/codegen/x86/int_x86.cc b/src/compiler/codegen/x86/int_x86.cc
index d4a34f7..d47f3dc 100644
--- a/src/compiler/codegen/x86/int_x86.cc
+++ b/src/compiler/codegen/x86/int_x86.cc
@@ -587,7 +587,9 @@
StoreBaseIndexedDisp(cu, r_array, r_index, scale,
data_offset, r_value, INVALID_REG, kWord, INVALID_SREG);
FreeTemp(cu, r_index);
- MarkGCCard(cu, r_value, r_array);
+ if (!IsConstantNullRef(cu, rl_src)) {
+ MarkGCCard(cu, r_value, r_array);
+ }
}
bool X86Codegen::GenShiftImmOpLong(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
diff --git a/src/compiler/compiler_ir.h b/src/compiler/compiler_ir.h
index 056c308..2b2dabe 100644
--- a/src/compiler/compiler_ir.h
+++ b/src/compiler/compiler_ir.h
@@ -605,6 +605,11 @@
Low32Bits(static_cast<int64_t>(cu->constant_values[loc.orig_sreg]));
}
+static inline bool IsConstantNullRef(const CompilationUnit* cu, RegLocation loc)
+{
+ return loc.ref && loc.is_const && (ConstantValue(cu, loc) == 0);
+}
+
static inline bool MustFlushConstant(const CompilationUnit* cu, RegLocation loc)
{
DCHECK(IsConst(cu, loc));