Commit f3d119b9 authored by hpayer's avatar hpayer Committed by Commit bot

[heap] Reland: Use store buffer for writes coming from mutator.

This reverts commit 810fcb28.

BUG=chromium:648568, chromium:669270

Review-Url: https://codereview.chromium.org/2530383003
Cr-Commit-Position: refs/heads/master@{#41350}
parent 0f607182
...@@ -502,9 +502,7 @@ void Heap::RecordWrite(Object* object, int offset, Object* o) { ...@@ -502,9 +502,7 @@ void Heap::RecordWrite(Object* object, int offset, Object* o) {
if (!InNewSpace(o) || !object->IsHeapObject() || InNewSpace(object)) { if (!InNewSpace(o) || !object->IsHeapObject() || InNewSpace(object)) {
return; return;
} }
RememberedSet<OLD_TO_NEW>::Insert( store_buffer()->InsertEntry(HeapObject::cast(object)->address() + offset);
Page::FromAddress(reinterpret_cast<Address>(object)),
HeapObject::cast(object)->address() + offset);
} }
void Heap::RecordWriteIntoCode(Code* host, RelocInfo* rinfo, Object* value) { void Heap::RecordWriteIntoCode(Code* host, RelocInfo* rinfo, Object* value) {
...@@ -515,11 +513,9 @@ void Heap::RecordWriteIntoCode(Code* host, RelocInfo* rinfo, Object* value) { ...@@ -515,11 +513,9 @@ void Heap::RecordWriteIntoCode(Code* host, RelocInfo* rinfo, Object* value) {
void Heap::RecordFixedArrayElements(FixedArray* array, int offset, int length) { void Heap::RecordFixedArrayElements(FixedArray* array, int offset, int length) {
if (InNewSpace(array)) return; if (InNewSpace(array)) return;
Page* page = Page::FromAddress(reinterpret_cast<Address>(array));
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if (!InNewSpace(array->get(offset + i))) continue; if (!InNewSpace(array->get(offset + i))) continue;
RememberedSet<OLD_TO_NEW>::Insert( store_buffer()->InsertEntry(
page,
reinterpret_cast<Address>(array->RawFieldOfElementAt(offset + i))); reinterpret_cast<Address>(array->RawFieldOfElementAt(offset + i)));
} }
} }
......
...@@ -5885,8 +5885,7 @@ void Heap::ClearRecordedSlot(HeapObject* object, Object** slot) { ...@@ -5885,8 +5885,7 @@ void Heap::ClearRecordedSlot(HeapObject* object, Object** slot) {
Address slot_addr = reinterpret_cast<Address>(slot); Address slot_addr = reinterpret_cast<Address>(slot);
Page* page = Page::FromAddress(slot_addr); Page* page = Page::FromAddress(slot_addr);
DCHECK_EQ(page->owner()->identity(), OLD_SPACE); DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
store_buffer()->MoveAllEntriesToRememberedSet(); store_buffer()->DeleteEntry(slot_addr);
RememberedSet<OLD_TO_NEW>::Remove(page, slot_addr);
RememberedSet<OLD_TO_OLD>::Remove(page, slot_addr); RememberedSet<OLD_TO_OLD>::Remove(page, slot_addr);
} }
} }
...@@ -5907,9 +5906,7 @@ void Heap::ClearRecordedSlotRange(Address start, Address end) { ...@@ -5907,9 +5906,7 @@ void Heap::ClearRecordedSlotRange(Address start, Address end) {
Page* page = Page::FromAddress(start); Page* page = Page::FromAddress(start);
if (!page->InNewSpace()) { if (!page->InNewSpace()) {
DCHECK_EQ(page->owner()->identity(), OLD_SPACE); DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
store_buffer()->MoveAllEntriesToRememberedSet(); store_buffer()->DeleteEntry(start, end);
RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end,
SlotSet::PREFREE_EMPTY_BUCKETS);
RememberedSet<OLD_TO_OLD>::RemoveRange(page, start, end, RememberedSet<OLD_TO_OLD>::RemoveRange(page, start, end,
SlotSet::FREE_EMPTY_BUCKETS); SlotSet::FREE_EMPTY_BUCKETS);
} }
......
...@@ -138,6 +138,10 @@ void StoreBuffer::ConcurrentlyProcessStoreBuffer() { ...@@ -138,6 +138,10 @@ void StoreBuffer::ConcurrentlyProcessStoreBuffer() {
} }
void StoreBuffer::DeleteEntry(Address start, Address end) { void StoreBuffer::DeleteEntry(Address start, Address end) {
// Deletions coming from the GC are directly deleted from the remembered
// set. Deletions coming from the runtime are added to the store buffer
// to allow concurrent processing.
if (heap_->gc_state() == Heap::NOT_IN_GC) {
if (top_ + sizeof(Address) * 2 > limit_[current_]) { if (top_ + sizeof(Address) * 2 > limit_[current_]) {
StoreBufferOverflow(heap_->isolate()); StoreBufferOverflow(heap_->isolate());
} }
...@@ -145,7 +149,17 @@ void StoreBuffer::DeleteEntry(Address start, Address end) { ...@@ -145,7 +149,17 @@ void StoreBuffer::DeleteEntry(Address start, Address end) {
top_++; top_++;
*top_ = end; *top_ = end;
top_++; top_++;
} else {
// In GC the store buffer has to be empty at any time.
DCHECK(Empty());
Page* page = Page::FromAddress(start);
if (end) {
RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end,
SlotSet::PREFREE_EMPTY_BUCKETS);
} else {
RememberedSet<OLD_TO_NEW>::Remove(page, start);
}
}
} }
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#include "src/cancelable-task.h" #include "src/cancelable-task.h"
#include "src/globals.h" #include "src/globals.h"
#include "src/heap/remembered-set.h"
#include "src/heap/slot-set.h" #include "src/heap/slot-set.h"
namespace v8 { namespace v8 {
...@@ -28,7 +29,7 @@ class StoreBuffer { ...@@ -28,7 +29,7 @@ class StoreBuffer {
static const int kStoreBuffers = 2; static const int kStoreBuffers = 2;
static const intptr_t kDeletionTag = 1; static const intptr_t kDeletionTag = 1;
static void StoreBufferOverflow(Isolate* isolate); V8_EXPORT_PRIVATE static void StoreBufferOverflow(Isolate* isolate);
explicit StoreBuffer(Heap* heap); explicit StoreBuffer(Heap* heap);
void SetUp(); void SetUp();
...@@ -64,6 +65,23 @@ class StoreBuffer { ...@@ -64,6 +65,23 @@ class StoreBuffer {
// the more efficient Remove method will be called in this case. // the more efficient Remove method will be called in this case.
void DeleteEntry(Address start, Address end = nullptr); void DeleteEntry(Address start, Address end = nullptr);
void InsertEntry(Address slot) {
// Insertions coming from the GC are directly inserted into the remembered
// set. Insertions coming from the runtime are added to the store buffer to
// allow concurrent processing.
if (heap_->gc_state() == Heap::NOT_IN_GC) {
if (top_ + sizeof(Address) > limit_[current_]) {
StoreBufferOverflow(heap_->isolate());
}
*top_ = slot;
top_++;
} else {
// In GC the store buffer has to be empty at any time.
DCHECK(Empty());
RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot);
}
}
// Used by the concurrent processing thread to transfer entries from the // Used by the concurrent processing thread to transfer entries from the
// store buffer to the remembered set. // store buffer to the remembered set.
void ConcurrentlyProcessStoreBuffer(); void ConcurrentlyProcessStoreBuffer();
......
...@@ -2604,7 +2604,7 @@ void FixedArray::set(int index, ...@@ -2604,7 +2604,7 @@ void FixedArray::set(int index,
DCHECK_GE(index, 0); DCHECK_GE(index, 0);
DCHECK_LT(index, this->length()); DCHECK_LT(index, this->length());
int offset = kHeaderSize + index * kPointerSize; int offset = kHeaderSize + index * kPointerSize;
WRITE_FIELD(this, offset, value); NOBARRIER_WRITE_FIELD(this, offset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
} }
...@@ -2616,7 +2616,7 @@ void FixedArray::NoWriteBarrierSet(FixedArray* array, ...@@ -2616,7 +2616,7 @@ void FixedArray::NoWriteBarrierSet(FixedArray* array,
DCHECK_GE(index, 0); DCHECK_GE(index, 0);
DCHECK_LT(index, array->length()); DCHECK_LT(index, array->length());
DCHECK(!array->GetHeap()->InNewSpace(value)); DCHECK(!array->GetHeap()->InNewSpace(value));
WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); NOBARRIER_WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
} }
void FixedArray::set_undefined(int index) { void FixedArray::set_undefined(int index) {
......
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