X86: Optimize GenCAS
This commit adds a small optimization to GenCAS: skip the MarkGCCard if
the value was not set (cmpxchg fails).
Test: ART_HEAP_POISONING=true art/test.py --host --all-compiler -r --32
Test: ART_HEAP_POISONING=false art/test.py --host --all-compiler -r --32
Test: ART_USE_READ_BARRIER=true art/test.py --host --all-compiler -r --32
Test: ART_USE_READ_BARRIER=false art/test.py --host --all-compiler -r --32
Change-Id: Ic483c4ccb0a58f7c21e6fd9f3bc90ba8c56492b8
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index 73c1009..f10b511 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -2037,15 +2037,11 @@
// The address of the field within the holding object.
Address field_addr(base, offset, TIMES_1, 0);
+ Register value = new_value.AsRegister<Register>();
Register expected = expected_value.AsRegister<Register>();
DCHECK_EQ(expected, EAX);
DCHECK_NE(temp, temp2);
- // Mark card for object assuming new value is stored.
- bool value_can_be_null = true; // TODO: Worth finding out this information?
- Register value = new_value.AsRegister<Register>();
- codegen->MarkGCCard(temp, temp2, base, value, value_can_be_null);
-
if (kEmitCompilerReadBarrier && kUseBakerReadBarrier) {
// Need to make sure the reference stored in the field is a to-space
// one before attempting the CAS or the CAS could fail incorrectly.
@@ -2091,6 +2087,13 @@
__ setb(kZero, out.AsRegister<Register>());
__ movzxb(out.AsRegister<Register>(), out.AsRegister<ByteRegister>());
+ // Mark card for object if the new value is stored.
+ bool value_can_be_null = true; // TODO: Worth finding out this information?
+ NearLabel skip_mark_gc_card;
+ __ j(kNotZero, &skip_mark_gc_card);
+ codegen->MarkGCCard(temp, temp2, base, value, value_can_be_null);
+ __ Bind(&skip_mark_gc_card);
+
// If heap poisoning is enabled, we need to unpoison the values
// that were poisoned earlier.
if (kPoisonHeapReferences) {