Fix byte_cas to use uintptr_t Atomic.
Previously we used int32_t Atomic with a uintptr_t bit shift.
This was a mismatch on 64 bit and resulted in occasionally
having the cas return without having succeeded.
Bug: 16819816
Change-Id: I10fa9c2f09ae8fe0997a4c9293fa123c6bde5920
diff --git a/runtime/gc/accounting/card_table-inl.h b/runtime/gc/accounting/card_table-inl.h
index 46b9363..217360f 100644
--- a/runtime/gc/accounting/card_table-inl.h
+++ b/runtime/gc/accounting/card_table-inl.h
@@ -37,12 +37,13 @@
// Align the address down.
address -= shift_in_bytes;
const size_t shift_in_bits = shift_in_bytes * kBitsPerByte;
- AtomicInteger* word_atomic = reinterpret_cast<AtomicInteger*>(address);
+ Atomic<uintptr_t>* word_atomic = reinterpret_cast<Atomic<uintptr_t>*>(address);
// Word with the byte we are trying to cas cleared.
- const int32_t cur_word = word_atomic->LoadRelaxed() & ~(0xFF << shift_in_bits);
- const int32_t old_word = cur_word | (static_cast<int32_t>(old_value) << shift_in_bits);
- const int32_t new_word = cur_word | (static_cast<int32_t>(new_value) << shift_in_bits);
+ const uintptr_t cur_word = word_atomic->LoadRelaxed() &
+ ~(static_cast<uintptr_t>(0xFF) << shift_in_bits);
+ const uintptr_t old_word = cur_word | (static_cast<uintptr_t>(old_value) << shift_in_bits);
+ const uintptr_t new_word = cur_word | (static_cast<uintptr_t>(new_value) << shift_in_bits);
return word_atomic->CompareExchangeWeakRelaxed(old_word, new_word);
#endif
}