diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-01-17 10:27:09 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-01-17 13:10:34 -0800 |
commit | 2ef33c3dce17dabd9342ccf15cca5700487f2045 (patch) | |
tree | 830c4d51b1bf95604e8a27800a0fab9443dc91b0 /runtime/gc/accounting | |
parent | 0ab4c5c05f0b38a13d2897dc50143f00811529d1 (diff) | |
download | art-2ef33c3dce17dabd9342ccf15cca5700487f2045.zip art-2ef33c3dce17dabd9342ccf15cca5700487f2045.tar.gz art-2ef33c3dce17dabd9342ccf15cca5700487f2045.tar.bz2 |
Fix bug in CardTable::ModifyCardsAtomic.
We were passing in the wrong card address when handling unaligned
cards near the end of the scan range. This resulted in occasional
heap corruption according to heap verification. Also added
rounding to handle non card aligned scan end.
Change-Id: I1ff13c35bacb89716dac5826fdb5919d1c00e0e3
Diffstat (limited to 'runtime/gc/accounting')
-rw-r--r-- | runtime/gc/accounting/card_table-inl.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/runtime/gc/accounting/card_table-inl.h b/runtime/gc/accounting/card_table-inl.h index 7bd53df..f0c4d0d 100644 --- a/runtime/gc/accounting/card_table-inl.h +++ b/runtime/gc/accounting/card_table-inl.h @@ -121,7 +121,7 @@ template <typename Visitor, typename ModifiedVisitor> inline void CardTable::ModifyCardsAtomic(byte* scan_begin, byte* scan_end, const Visitor& visitor, const ModifiedVisitor& modified) { byte* card_cur = CardFromAddr(scan_begin); - byte* card_end = CardFromAddr(scan_end); + byte* card_end = CardFromAddr(AlignUp(scan_end, kCardSize)); CheckCardValid(card_cur); CheckCardValid(card_end); @@ -147,7 +147,7 @@ inline void CardTable::ModifyCardsAtomic(byte* scan_begin, byte* scan_end, const new_value = visitor(expected); } while (expected != new_value && UNLIKELY(!byte_cas(expected, new_value, card_end))); if (expected != new_value) { - modified(card_cur, expected, new_value); + modified(card_end, expected, new_value); } } |