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

Store buffer is used for writes that are coming from the mutator. Writes...

Store buffer is used for writes that are coming from the mutator. Writes coming from the GC are directly added to the remembered set.

BUG=chromium:648568

Review-Url: https://codereview.chromium.org/2528563003
Cr-Commit-Position: refs/heads/master@{#41263}
parent f447aeac
......@@ -502,9 +502,7 @@ void Heap::RecordWrite(Object* object, int offset, Object* o) {
if (!InNewSpace(o) || !object->IsHeapObject() || InNewSpace(object)) {
return;
}
RememberedSet<OLD_TO_NEW>::Insert(
Page::FromAddress(reinterpret_cast<Address>(object)),
HeapObject::cast(object)->address() + offset);
store_buffer()->InsertEntry(HeapObject::cast(object)->address() + offset);
}
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) {
if (InNewSpace(array)) return;
Page* page = Page::FromAddress(reinterpret_cast<Address>(array));
for (int i = 0; i < length; i++) {
if (!InNewSpace(array->get(offset + i))) continue;
RememberedSet<OLD_TO_NEW>::Insert(
page,
store_buffer()->InsertEntry(
reinterpret_cast<Address>(array->RawFieldOfElementAt(offset + i)));
}
}
......
......@@ -5885,8 +5885,7 @@ void Heap::ClearRecordedSlot(HeapObject* object, Object** slot) {
Address slot_addr = reinterpret_cast<Address>(slot);
Page* page = Page::FromAddress(slot_addr);
DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
store_buffer()->MoveAllEntriesToRememberedSet();
RememberedSet<OLD_TO_NEW>::Remove(page, slot_addr);
store_buffer()->DeleteEntry(slot_addr);
RememberedSet<OLD_TO_OLD>::Remove(page, slot_addr);
}
}
......@@ -5895,9 +5894,7 @@ void Heap::ClearRecordedSlotRange(Address start, Address end) {
Page* page = Page::FromAddress(start);
if (!page->InNewSpace()) {
DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
store_buffer()->MoveAllEntriesToRememberedSet();
RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end,
SlotSet::PREFREE_EMPTY_BUCKETS);
store_buffer()->DeleteEntry(start, end);
RememberedSet<OLD_TO_OLD>::RemoveRange(page, start, end,
SlotSet::FREE_EMPTY_BUCKETS);
}
......
......@@ -138,14 +138,28 @@ void StoreBuffer::ConcurrentlyProcessStoreBuffer() {
}
void StoreBuffer::DeleteEntry(Address start, Address end) {
if (top_ + sizeof(Address) * 2 > limit_[current_]) {
StoreBufferOverflow(heap_->isolate());
// 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_]) {
StoreBufferOverflow(heap_->isolate());
}
*top_ = MarkDeletionAddress(start);
top_++;
*top_ = end;
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);
}
}
*top_ = MarkDeletionAddress(start);
top_++;
*top_ = end;
top_++;
}
} // namespace internal
} // namespace v8
......@@ -10,6 +10,7 @@
#include "src/base/platform/platform.h"
#include "src/cancelable-task.h"
#include "src/globals.h"
#include "src/heap/remembered-set.h"
#include "src/heap/slot-set.h"
namespace v8 {
......@@ -28,7 +29,7 @@ class StoreBuffer {
static const int kStoreBuffers = 2;
static const intptr_t kDeletionTag = 1;
static void StoreBufferOverflow(Isolate* isolate);
V8_EXPORT_PRIVATE static void StoreBufferOverflow(Isolate* isolate);
explicit StoreBuffer(Heap* heap);
void SetUp();
......@@ -64,6 +65,23 @@ class StoreBuffer {
// the more efficient Remove method will be called in this case.
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
// store buffer to the remembered set.
void ConcurrentlyProcessStoreBuffer();
......
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