summaryrefslogtreecommitdiffstats
path: root/runtime/gc/accounting
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-07-08 22:55:18 -0700
committerIan Rogers <irogers@google.com>2014-07-10 00:09:07 +0000
commit1461144e95f7798c33cfbada49b288f0cdf28157 (patch)
tree17411eea761ffc594cfc5660592bd79de30dbed1 /runtime/gc/accounting
parent5472edce3697721099ead9e16427e0e7ace90754 (diff)
downloadart-1461144e95f7798c33cfbada49b288f0cdf28157.tar.gz
art-1461144e95f7798c33cfbada49b288f0cdf28157.tar.bz2
art-1461144e95f7798c33cfbada49b288f0cdf28157.zip
Move card table away from android_atomic_cas.
For x86 use byte CAS operations for byte CAS. Fix bug in ModifyCardsAtomic where CAS was 32-bit instead of 64-bit. Change-Id: Ieb3fe695b4699750abf04642b0abe94103976817
Diffstat (limited to 'runtime/gc/accounting')
-rw-r--r--runtime/gc/accounting/card_table-inl.h19
1 files changed, 12 insertions, 7 deletions
diff --git a/runtime/gc/accounting/card_table-inl.h b/runtime/gc/accounting/card_table-inl.h
index a1d001ebda..ad0a4f438a 100644
--- a/runtime/gc/accounting/card_table-inl.h
+++ b/runtime/gc/accounting/card_table-inl.h
@@ -17,9 +17,9 @@
#ifndef ART_RUNTIME_GC_ACCOUNTING_CARD_TABLE_INL_H_
#define ART_RUNTIME_GC_ACCOUNTING_CARD_TABLE_INL_H_
+#include "atomic.h"
#include "base/logging.h"
#include "card_table.h"
-#include "cutils/atomic-inline.h"
#include "space_bitmap.h"
#include "utils.h"
@@ -28,18 +28,23 @@ namespace gc {
namespace accounting {
static inline bool byte_cas(byte old_value, byte new_value, byte* address) {
+#if defined(__i386__) || defined(__x86_64__)
+ Atomic<byte>* byte_atomic = reinterpret_cast<Atomic<byte>*>(address);
+ return byte_atomic->CompareExchangeWeakRelaxed(old_value, new_value);
+#else
// Little endian means most significant byte is on the left.
const size_t shift_in_bytes = reinterpret_cast<uintptr_t>(address) % sizeof(uintptr_t);
// Align the address down.
address -= shift_in_bytes;
const size_t shift_in_bits = shift_in_bytes * kBitsPerByte;
- int32_t* word_address = reinterpret_cast<int32_t*>(address);
+ AtomicInteger* word_atomic = reinterpret_cast<AtomicInteger*>(address);
+
// Word with the byte we are trying to cas cleared.
- const int32_t cur_word = *word_address & ~(0xFF << shift_in_bits);
+ 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);
- bool success = android_atomic_cas(old_word, new_word, word_address) == 0;
- return success;
+ return word_atomic->CompareExchangeWeakRelaxed(old_word, new_word);
+#endif
}
template <typename Visitor>
@@ -174,8 +179,8 @@ inline void CardTable::ModifyCardsAtomic(byte* scan_begin, byte* scan_end, const
for (size_t i = 0; i < sizeof(uintptr_t); ++i) {
new_bytes[i] = visitor(expected_bytes[i]);
}
- if (LIKELY(android_atomic_cas(expected_word, new_word,
- reinterpret_cast<int32_t*>(word_cur)) == 0)) {
+ Atomic<uintptr_t>* atomic_word = reinterpret_cast<Atomic<uintptr_t>*>(word_cur);
+ if (LIKELY(atomic_word->CompareExchangeWeakRelaxed(expected_word, new_word))) {
for (size_t i = 0; i < sizeof(uintptr_t); ++i) {
const byte expected_byte = expected_bytes[i];
const byte new_byte = new_bytes[i];