[heap] Use template specialization for MarkBit accessors

BUG=chromium:694255
R=hpayer@chromium.org

Change-Id: Ie8d23ec88e9b8f97ac094630f4e46e9b31f93cc5
Reviewed-on: https://chromium-review.googlesource.com/452817
Reviewed-by: Hannes Payer <hpayer@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43829}
This commit is contained in:
Michael Lippautz 2017-03-09 20:54:13 +01:00 committed by Commit Bot
parent 2b1ed94464
commit 9fca3ad71b

View File

@ -39,47 +39,13 @@ class MarkBit {
}
template <AccessMode mode = NON_ATOMIC>
inline bool Set() {
if (mode == ATOMIC) {
base::Atomic32 old_value;
base::Atomic32 new_value;
do {
old_value = base::NoBarrier_Load(cell_);
if (old_value & mask_) return false;
new_value = old_value | mask_;
} while (base::Release_CompareAndSwap(cell_, old_value, new_value) !=
old_value);
} else {
*cell_ |= mask_;
}
return true;
}
inline bool Set();
template <AccessMode mode = NON_ATOMIC>
inline bool Get() {
if (mode == ATOMIC) {
return (base::Acquire_Load(cell_) & mask_) != 0;
} else {
return (base::NoBarrier_Load(cell_) & mask_) != 0;
}
}
inline bool Get();
template <AccessMode mode = NON_ATOMIC>
inline bool Clear() {
if (mode == ATOMIC) {
base::Atomic32 old_value;
base::Atomic32 new_value;
do {
old_value = base::NoBarrier_Load(cell_);
if (!(old_value & mask_)) return false;
new_value = old_value & ~mask_;
} while (base::Release_CompareAndSwap(cell_, old_value, new_value) !=
old_value);
} else {
*cell_ &= ~mask_;
}
return true;
}
inline bool Clear();
base::Atomic32* cell_;
base::Atomic32 mask_;
@ -89,6 +55,54 @@ class MarkBit {
friend class Marking;
};
template <>
inline bool MarkBit::Set<MarkBit::NON_ATOMIC>() {
*cell_ |= mask_;
return true;
}
template <>
inline bool MarkBit::Set<MarkBit::ATOMIC>() {
base::Atomic32 old_value;
base::Atomic32 new_value;
do {
old_value = base::NoBarrier_Load(cell_);
if (old_value & mask_) return false;
new_value = old_value | mask_;
} while (base::Release_CompareAndSwap(cell_, old_value, new_value) !=
old_value);
return true;
}
template <>
inline bool MarkBit::Get<MarkBit::NON_ATOMIC>() {
return (base::NoBarrier_Load(cell_) & mask_) != 0;
}
template <>
inline bool MarkBit::Get<MarkBit::ATOMIC>() {
return (base::Acquire_Load(cell_) & mask_) != 0;
}
template <>
inline bool MarkBit::Clear<MarkBit::NON_ATOMIC>() {
*cell_ &= ~mask_;
return true;
}
template <>
inline bool MarkBit::Clear<MarkBit::ATOMIC>() {
base::Atomic32 old_value;
base::Atomic32 new_value;
do {
old_value = base::NoBarrier_Load(cell_);
if (!(old_value & mask_)) return false;
new_value = old_value & ~mask_;
} while (base::Release_CompareAndSwap(cell_, old_value, new_value) !=
old_value);
return true;
}
// Bitmap is a sequence of cells each containing fixed number of bits.
class Bitmap {
public: