Commit 25f97037 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Fix more data races in bitmap SetRange and ClearRange.

This patch also changes String body descriptor to use synchronized
length and adds atomic live_bytes accessor.

BUG=chromium:694255

Change-Id: I41233b2097ec5c6a4ea2c45d4b8febf7ffca155e
Reviewed-on: https://chromium-review.googlesource.com/527093Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45761}
parent f2cd359a
...@@ -197,10 +197,9 @@ class Bitmap { ...@@ -197,10 +197,9 @@ class Bitmap {
// cell with 1s. // cell with 1s.
SetBitsInCell<mode>(start_cell_index, ~(start_index_mask - 1)); SetBitsInCell<mode>(start_cell_index, ~(start_index_mask - 1));
// Then fill all in between cells with 1s. // Then fill all in between cells with 1s.
base::Atomic32* cell_base = reinterpret_cast<base::Atomic32*>(cells());
for (unsigned int i = start_cell_index + 1; i < end_cell_index; i++) { for (unsigned int i = start_cell_index + 1; i < end_cell_index; i++) {
// The callers must ensure that the inner cells in the range are not base::Relaxed_Store(cell_base + i, ~0u);
// accessed concurrently.
cells()[i] = ~0u;
} }
// Finally, fill all bits until the end address in the last cell with 1s. // Finally, fill all bits until the end address in the last cell with 1s.
SetBitsInCell<mode>(end_cell_index, (end_index_mask - 1)); SetBitsInCell<mode>(end_cell_index, (end_index_mask - 1));
...@@ -227,10 +226,9 @@ class Bitmap { ...@@ -227,10 +226,9 @@ class Bitmap {
// cell with 0s. // cell with 0s.
ClearBitsInCell<mode>(start_cell_index, ~(start_index_mask - 1)); ClearBitsInCell<mode>(start_cell_index, ~(start_index_mask - 1));
// Then fill all in between cells with 0s. // Then fill all in between cells with 0s.
base::Atomic32* cell_base = reinterpret_cast<base::Atomic32*>(cells());
for (unsigned int i = start_cell_index + 1; i < end_cell_index; i++) { for (unsigned int i = start_cell_index + 1; i < end_cell_index; i++) {
// The callers must ensure that the inner cells in the range are not base::Relaxed_Store(cell_base + i, 0);
// accessed concurrently.
cells()[i] = 0;
} }
// Finally, set all bits until the end address in the last cell with 0s. // Finally, set all bits until the end address in the last cell with 0s.
ClearBitsInCell<mode>(end_cell_index, (end_index_mask - 1)); ClearBitsInCell<mode>(end_cell_index, (end_index_mask - 1));
......
...@@ -1504,9 +1504,11 @@ void PagedSpace::EmptyAllocationInfo() { ...@@ -1504,9 +1504,11 @@ void PagedSpace::EmptyAllocationInfo() {
// Clear the bits in the unused black area. // Clear the bits in the unused black area.
if (current_top != current_limit) { if (current_top != current_limit) {
MarkingState::Internal(page).bitmap()->ClearRange( MarkingState::Internal(page)
page->AddressToMarkbitIndex(current_top), .bitmap()
page->AddressToMarkbitIndex(current_limit)); ->ClearRange<IncrementalMarking::kAtomicity>(
page->AddressToMarkbitIndex(current_top),
page->AddressToMarkbitIndex(current_limit));
MarkingState::Internal(page) MarkingState::Internal(page)
.IncrementLiveBytes<IncrementalMarking::kAtomicity>( .IncrementLiveBytes<IncrementalMarking::kAtomicity>(
-static_cast<int>(current_limit - current_top)); -static_cast<int>(current_limit - current_top));
...@@ -1595,7 +1597,8 @@ void PagedSpace::Verify(ObjectVisitor* visitor) { ...@@ -1595,7 +1597,8 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
CHECK(object->address() + size <= top); CHECK(object->address() + size <= top);
end_of_previous_object = object->address() + size; end_of_previous_object = object->address() + size;
} }
CHECK_LE(black_size, MarkingState::Internal(page).live_bytes()); CHECK_LE(black_size,
MarkingState::Internal(page).live_bytes<MarkBit::ATOMIC>());
} }
CHECK(allocation_pointer_found_in_space); CHECK(allocation_pointer_found_in_space);
} }
......
...@@ -695,7 +695,9 @@ class MarkingState { ...@@ -695,7 +695,9 @@ class MarkingState {
} }
Bitmap* bitmap() const { return bitmap_; } Bitmap* bitmap() const { return bitmap_; }
intptr_t live_bytes() const { return *live_bytes_; }
template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC>
inline intptr_t live_bytes() const;
private: private:
Bitmap* bitmap_; Bitmap* bitmap_;
...@@ -714,6 +716,16 @@ inline void MarkingState::IncrementLiveBytes<MarkBit::ATOMIC>( ...@@ -714,6 +716,16 @@ inline void MarkingState::IncrementLiveBytes<MarkBit::ATOMIC>(
reinterpret_cast<base::AtomicNumber<intptr_t>*>(live_bytes_)->Increment(by); reinterpret_cast<base::AtomicNumber<intptr_t>*>(live_bytes_)->Increment(by);
} }
template <>
inline intptr_t MarkingState::live_bytes<MarkBit::NON_ATOMIC>() const {
return *live_bytes_;
}
template <>
inline intptr_t MarkingState::live_bytes<MarkBit::ATOMIC>() const {
return reinterpret_cast<base::AtomicNumber<intptr_t>*>(live_bytes_)->Value();
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// A page is a memory chunk of a size 1MB. Large object pages may be larger. // A page is a memory chunk of a size 1MB. Large object pages may be larger.
// //
......
...@@ -546,7 +546,7 @@ class SeqOneByteString::BodyDescriptor final : public BodyDescriptorBase { ...@@ -546,7 +546,7 @@ class SeqOneByteString::BodyDescriptor final : public BodyDescriptorBase {
static inline int SizeOf(Map* map, HeapObject* obj) { static inline int SizeOf(Map* map, HeapObject* obj) {
SeqOneByteString* string = SeqOneByteString::cast(obj); SeqOneByteString* string = SeqOneByteString::cast(obj);
return string->SizeFor(string->length()); return string->SizeFor(string->synchronized_length());
} }
}; };
...@@ -563,7 +563,7 @@ class SeqTwoByteString::BodyDescriptor final : public BodyDescriptorBase { ...@@ -563,7 +563,7 @@ class SeqTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
static inline int SizeOf(Map* map, HeapObject* obj) { static inline int SizeOf(Map* map, HeapObject* obj) {
SeqTwoByteString* string = SeqTwoByteString::cast(obj); SeqTwoByteString* string = SeqTwoByteString::cast(obj);
return string->SizeFor(string->length()); return string->SizeFor(string->synchronized_length());
} }
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment