[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/527093 Reviewed-by: Hannes Payer <hpayer@chromium.org> Commit-Queue: Ulan Degenbaev <ulan@chromium.org> Cr-Commit-Position: refs/heads/master@{#45761}
This commit is contained in:
parent
f2cd359ac9
commit
25f970370a
@ -197,10 +197,9 @@ class Bitmap {
|
||||
// cell with 1s.
|
||||
SetBitsInCell<mode>(start_cell_index, ~(start_index_mask - 1));
|
||||
// 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++) {
|
||||
// The callers must ensure that the inner cells in the range are not
|
||||
// accessed concurrently.
|
||||
cells()[i] = ~0u;
|
||||
base::Relaxed_Store(cell_base + i, ~0u);
|
||||
}
|
||||
// Finally, fill all bits until the end address in the last cell with 1s.
|
||||
SetBitsInCell<mode>(end_cell_index, (end_index_mask - 1));
|
||||
@ -227,10 +226,9 @@ class Bitmap {
|
||||
// cell with 0s.
|
||||
ClearBitsInCell<mode>(start_cell_index, ~(start_index_mask - 1));
|
||||
// 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++) {
|
||||
// The callers must ensure that the inner cells in the range are not
|
||||
// accessed concurrently.
|
||||
cells()[i] = 0;
|
||||
base::Relaxed_Store(cell_base + i, 0);
|
||||
}
|
||||
// Finally, set all bits until the end address in the last cell with 0s.
|
||||
ClearBitsInCell<mode>(end_cell_index, (end_index_mask - 1));
|
||||
|
@ -1504,9 +1504,11 @@ void PagedSpace::EmptyAllocationInfo() {
|
||||
|
||||
// Clear the bits in the unused black area.
|
||||
if (current_top != current_limit) {
|
||||
MarkingState::Internal(page).bitmap()->ClearRange(
|
||||
page->AddressToMarkbitIndex(current_top),
|
||||
page->AddressToMarkbitIndex(current_limit));
|
||||
MarkingState::Internal(page)
|
||||
.bitmap()
|
||||
->ClearRange<IncrementalMarking::kAtomicity>(
|
||||
page->AddressToMarkbitIndex(current_top),
|
||||
page->AddressToMarkbitIndex(current_limit));
|
||||
MarkingState::Internal(page)
|
||||
.IncrementLiveBytes<IncrementalMarking::kAtomicity>(
|
||||
-static_cast<int>(current_limit - current_top));
|
||||
@ -1595,7 +1597,8 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
|
||||
CHECK(object->address() + size <= top);
|
||||
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);
|
||||
}
|
||||
|
@ -695,7 +695,9 @@ class MarkingState {
|
||||
}
|
||||
|
||||
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:
|
||||
Bitmap* bitmap_;
|
||||
@ -714,6 +716,16 @@ inline void MarkingState::IncrementLiveBytes<MarkBit::ATOMIC>(
|
||||
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.
|
||||
//
|
||||
|
@ -546,7 +546,7 @@ class SeqOneByteString::BodyDescriptor final : public BodyDescriptorBase {
|
||||
|
||||
static inline int SizeOf(Map* map, HeapObject* 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 {
|
||||
|
||||
static inline int SizeOf(Map* map, HeapObject* obj) {
|
||||
SeqTwoByteString* string = SeqTwoByteString::cast(obj);
|
||||
return string->SizeFor(string->length());
|
||||
return string->SizeFor(string->synchronized_length());
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user