Chromium Code Reviews| Index: src/heap/store-buffer.cc |
| diff --git a/src/heap/store-buffer.cc b/src/heap/store-buffer.cc |
| index 6c8a457af811e925ca295477497da5fa311c4a13..1bc0ca6a44202eb331bd1771ba066cbe2d7f278c 100644 |
| --- a/src/heap/store-buffer.cc |
| +++ b/src/heap/store-buffer.cc |
| @@ -115,6 +115,7 @@ void StoreBuffer::Uniq() { |
| DCHECK(may_move_store_buffer_entries_); |
| for (Address* read = old_start_; read < old_top_; read++) { |
| Address current = *read; |
| + DCHECK_NOT_NULL(current); |
| if (current != previous) { |
| Object* object = reinterpret_cast<Object*>( |
| base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(current))); |
| @@ -202,6 +203,7 @@ void StoreBuffer::ExemptPopularPages(int prime_sample_step, int threshold) { |
| MemoryChunk* previous_chunk = NULL; |
| for (Address* p = old_start_; p < old_top_; p += prime_sample_step) { |
| Address addr = *p; |
| + if (addr == NULL) continue; |
| MemoryChunk* containing_chunk = NULL; |
| if (previous_chunk != NULL && previous_chunk->Contains(addr)) { |
| containing_chunk = previous_chunk; |
| @@ -228,6 +230,7 @@ void StoreBuffer::Filter(int flag) { |
| MemoryChunk* previous_chunk = NULL; |
| for (Address* p = old_start_; p < old_top_; p++) { |
| Address addr = *p; |
| + if (addr == NULL) continue; |
| MemoryChunk* containing_chunk = NULL; |
| if (previous_chunk != NULL && previous_chunk->Contains(addr)) { |
| containing_chunk = previous_chunk; |
| @@ -247,6 +250,49 @@ void StoreBuffer::Filter(int flag) { |
| } |
| +void StoreBuffer::RemoveSlots(Address start_address, Address end_address) { |
| + struct IsValueInRangePredicate { |
| + Address start_address_; |
| + Address end_address_; |
| + |
| + IsValueInRangePredicate(Address start_address, Address end_address) |
| + : start_address_(start_address), end_address_(end_address) {} |
| + |
| + bool operator()(Address addr) { |
| + return start_address_ <= addr && addr < end_address_; |
| + } |
| + }; |
| + |
| + IsValueInRangePredicate predicate(start_address, end_address); |
| + const Address kRemovedSlot = NULL; |
|
Hannes Payer (out of office)
2015/03/05 21:34:43
The NULL value is not much fun. Maybe we should po
Igor Sheludko
2015/03/06 09:06:59
Good point!
|
| + |
| + { |
| + Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top()); |
| + std::replace_if(start_, top, predicate, kRemovedSlot); |
| + } |
| + |
| + if (old_buffer_is_sorted_) { |
| + // Remove slots from an old buffer preserving the order. |
| + Address* lower = std::lower_bound(old_start_, old_top_, start_address); |
| + if (lower != old_top_) { |
| + Address* upper = std::lower_bound(lower, old_top_, end_address); |
| + // Remove [lower, upper) from the buffer. |
| + if (upper == old_top_) { |
| + old_top_ = lower; |
| + } else { |
| + Address* new_top = lower; |
| + for (Address* p = upper; p < old_top_; p++) { |
| + *new_top++ = *p; |
| + } |
| + old_top_ = new_top; |
|
Hannes Payer (out of office)
2015/03/05 21:34:43
Why do you set old_top_ here, the old top should r
Igor Sheludko
2015/03/06 09:06:59
Sorry, I didn't get the question. Added more comme
|
| + } |
| + } |
| + } else { |
| + std::replace_if(old_start_, old_top_, predicate, kRemovedSlot); |
| + } |
| +} |
| + |
| + |
| void StoreBuffer::SortUniq() { |
| Compact(); |
| if (old_buffer_is_sorted_) return; |
| @@ -297,12 +343,18 @@ static Address* in_store_buffer_1_element_cache = NULL; |
| bool StoreBuffer::CellIsInStoreBuffer(Address cell_address) { |
| - if (!FLAG_enable_slow_asserts) return true; |
| + DCHECK_NOT_NULL(cell_address); |
| + Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top()); |
| if (in_store_buffer_1_element_cache != NULL && |
| *in_store_buffer_1_element_cache == cell_address) { |
| - return true; |
| + // Check if the cache still points into the active part of the buffer. |
| + if ((start_ <= in_store_buffer_1_element_cache && |
| + in_store_buffer_1_element_cache < top) || |
| + (old_start_ <= in_store_buffer_1_element_cache && |
| + in_store_buffer_1_element_cache < old_top_)) { |
| + return true; |
| + } |
| } |
| - Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top()); |
| for (Address* current = top - 1; current >= start_; current--) { |
| if (*current == cell_address) { |
| in_store_buffer_1_element_cache = current; |
| @@ -424,10 +476,12 @@ void StoreBuffer::IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback, |
| { |
| DontMoveStoreBufferEntriesScope scope(this); |
| for (Address* current = old_start_; current < limit; current++) { |
| + Address addr = *current; |
| + if (addr == NULL) continue; |
| #ifdef DEBUG |
| Address* saved_top = old_top_; |
| #endif |
| - ProcessOldToNewSlot(*current, slot_callback, clear_maps); |
| + ProcessOldToNewSlot(addr, slot_callback, clear_maps); |
| DCHECK(old_top_ == saved_top + 1 || old_top_ == saved_top); |
| } |
| } |
| @@ -582,10 +636,12 @@ void StoreBuffer::Compact() { |
| // functions to reduce the number of unnecessary clashes. |
| hash_sets_are_empty_ = false; // Hash sets are in use. |
| for (Address* current = start_; current < top; current++) { |
| - DCHECK(!heap_->cell_space()->Contains(*current)); |
| - DCHECK(!heap_->code_space()->Contains(*current)); |
| - DCHECK(!heap_->old_data_space()->Contains(*current)); |
| - uintptr_t int_addr = reinterpret_cast<uintptr_t>(*current); |
| + Address addr = *current; |
| + if (addr == NULL) continue; |
| + DCHECK(!heap_->cell_space()->Contains(addr)); |
| + DCHECK(!heap_->code_space()->Contains(addr)); |
| + DCHECK(!heap_->old_data_space()->Contains(addr)); |
| + uintptr_t int_addr = reinterpret_cast<uintptr_t>(addr); |
| // Shift out the last bits including any tags. |
| int_addr >>= kPointerSizeLog2; |
| // The upper part of an address is basically random because of ASLR and OS |