summaryrefslogtreecommitdiffstats
path: root/runtime/gc/accounting
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2013-09-16 19:43:47 -0700
committerMathieu Chartier <mathieuc@google.com>2013-09-17 10:03:00 -0700
commitc4621985bdfc2b27494087e5dee65a6d0cc5a632 (patch)
treed8165f5b8d337e73942ee29d66fb40585dc7caf1 /runtime/gc/accounting
parent5666afd6854b5634ae741dc8a3a633fc47d52168 (diff)
downloadart-c4621985bdfc2b27494087e5dee65a6d0cc5a632.zip
art-c4621985bdfc2b27494087e5dee65a6d0cc5a632.tar.gz
art-c4621985bdfc2b27494087e5dee65a6d0cc5a632.tar.bz2
Fix race in root marking.
There was a race which caused the class linker / intern table to not become dirty after adding a root. We now guard the is dirty flag by the corresponding locks to prevent this from occuring. This was causing roots to be occasionally missed. Also fixes the bug where we occasionally scan more cards than needed. Bug: 10626133 Change-Id: I0f6e72d92035ff463954d66988ef610ea0df61be
Diffstat (limited to 'runtime/gc/accounting')
-rw-r--r--runtime/gc/accounting/card_table-inl.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/runtime/gc/accounting/card_table-inl.h b/runtime/gc/accounting/card_table-inl.h
index c5e8812..0cfbd6f 100644
--- a/runtime/gc/accounting/card_table-inl.h
+++ b/runtime/gc/accounting/card_table-inl.h
@@ -64,10 +64,9 @@ inline void CardTable::Scan(SpaceBitmap* bitmap, byte* scan_begin, byte* scan_en
byte* aligned_end = card_end -
(reinterpret_cast<uintptr_t>(card_end) & (sizeof(uintptr_t) - 1));
- // Now we have the words, we can send these to be processed in parallel.
- uintptr_t* word_cur = reinterpret_cast<uintptr_t*>(card_cur);
uintptr_t* word_end = reinterpret_cast<uintptr_t*>(aligned_end);
- for (;;) {
+ for (uintptr_t* word_cur = reinterpret_cast<uintptr_t*>(card_cur); word_cur < word_end;
+ ++word_cur) {
while (LIKELY(*word_cur == 0)) {
++word_cur;
if (UNLIKELY(word_cur >= word_end)) {
@@ -78,6 +77,8 @@ inline void CardTable::Scan(SpaceBitmap* bitmap, byte* scan_begin, byte* scan_en
// Find the first dirty card.
uintptr_t start_word = *word_cur;
uintptr_t start = reinterpret_cast<uintptr_t>(AddrFromCard(reinterpret_cast<byte*>(word_cur)));
+ // TODO: Investigate if processing continuous runs of dirty cards with a single bitmap visit is
+ // more efficient.
for (size_t i = 0; i < sizeof(uintptr_t); ++i) {
if (static_cast<byte>(start_word) >= minimum_age) {
auto* card = reinterpret_cast<byte*>(word_cur) + i;
@@ -88,7 +89,6 @@ inline void CardTable::Scan(SpaceBitmap* bitmap, byte* scan_begin, byte* scan_en
start_word >>= 8;
start += kCardSize;
}
- ++word_cur;
}
exit_for: