Index: src/heap/store-buffer.cc |
diff --git a/src/heap/store-buffer.cc b/src/heap/store-buffer.cc |
index 6c8a457af811e925ca295477497da5fa311c4a13..132a664ad74285faada8153bf8312d511f07e829 100644 |
--- a/src/heap/store-buffer.cc |
+++ b/src/heap/store-buffer.cc |
@@ -247,6 +247,57 @@ void StoreBuffer::Filter(int flag) { |
} |
+// Returns number of slots stored in the slots buffer. |
Hannes Payer (out of office)
2015/03/03 09:48:53
store buffer
Igor Sheludko
2015/03/04 14:54:20
Done.
|
+int StoreBuffer::SizeForTesting() { |
Hannes Payer (out of office)
2015/03/03 09:48:53
Why is it called SizeForTesting? Why don't call it
Igor Sheludko
2015/03/04 14:54:19
Actually it doesn't make sense. Removed.
|
+ intptr_t size = old_top_ - old_start_; |
+ size += reinterpret_cast<Address*>(heap_->store_buffer_top()) - start_; |
+ DCHECK(size <= kStoreBufferSize); |
+ return static_cast<int>(size / kPointerSize); |
+} |
+ |
+ |
+void StoreBuffer::RemoveSlots(Address start_address, Address end_address) { |
Hannes Payer (out of office)
2015/03/03 09:48:53
How often do you think is this function called. If
Igor Sheludko
2015/03/04 14:54:20
Good point.
|
+ 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); |
+ |
+ { |
+ Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top()); |
+ Address* new_top = std::remove_if(start_, top, predicate); |
+ heap_->public_set_store_buffer_top(new_top); |
+ } |
+ |
+ if (old_buffer_is_sorted_) { |
+ 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; |
+ } |
+ } |
+ } else { |
+ old_top_ = std::remove_if(old_start_, old_top_, predicate); |
+ } |
+} |
+ |
+ |
void StoreBuffer::SortUniq() { |
Compact(); |
if (old_buffer_is_sorted_) return; |
@@ -297,12 +348,17 @@ static Address* in_store_buffer_1_element_cache = NULL; |
bool StoreBuffer::CellIsInStoreBuffer(Address cell_address) { |
- if (!FLAG_enable_slow_asserts) return true; |
+ 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; |