Commit a1e22519 authored by Dominik Inführ's avatar Dominik Inführ Committed by Commit Bot

[heap] Remove deletion entries from store buffer

Get rid of deletion entries in the store buffer. Clearing a slot now
first empties the store buffer and then directly deletes the slot
from the remembered set.

Bug: v8:9454
Change-Id: I656db593a0478db3fa63324d7f3c6862b4b5e776
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1766130Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63359}
parent b3d1fdcb
...@@ -5527,7 +5527,8 @@ void Heap::ClearRecordedSlot(HeapObject object, ObjectSlot slot) { ...@@ -5527,7 +5527,8 @@ void Heap::ClearRecordedSlot(HeapObject object, ObjectSlot slot) {
Page* page = Page::FromAddress(slot.address()); Page* page = Page::FromAddress(slot.address());
if (!page->InYoungGeneration()) { if (!page->InYoungGeneration()) {
DCHECK_EQ(page->owner_identity(), OLD_SPACE); DCHECK_EQ(page->owner_identity(), OLD_SPACE);
store_buffer()->DeleteEntry(slot.address()); store_buffer()->MoveAllEntriesToRememberedSet();
RememberedSet<OLD_TO_NEW>::Remove(page, slot.address());
} }
} }
...@@ -5550,7 +5551,9 @@ void Heap::ClearRecordedSlotRange(Address start, Address end) { ...@@ -5550,7 +5551,9 @@ void Heap::ClearRecordedSlotRange(Address start, Address end) {
DCHECK(!page->IsLargePage()); DCHECK(!page->IsLargePage());
if (!page->InYoungGeneration()) { if (!page->InYoungGeneration()) {
DCHECK_EQ(page->owner_identity(), OLD_SPACE); DCHECK_EQ(page->owner_identity(), OLD_SPACE);
store_buffer()->DeleteEntry(start, end); store_buffer()->MoveAllEntriesToRememberedSet();
RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end,
SlotSet::KEEP_EMPTY_BUCKETS);
} }
} }
......
...@@ -12,16 +12,6 @@ ...@@ -12,16 +12,6 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
void StoreBuffer::InsertDeletionIntoStoreBuffer(Address start, Address end) {
if (top_ + sizeof(Address) * 2 > limit_[current_]) {
StoreBufferOverflow(heap_->isolate());
}
*top_ = MarkDeletionAddress(start);
top_++;
*top_ = end;
top_++;
}
void StoreBuffer::InsertIntoStoreBuffer(Address slot) { void StoreBuffer::InsertIntoStoreBuffer(Address slot) {
if (top_ + sizeof(Address) > limit_[current_]) { if (top_ + sizeof(Address) > limit_[current_]) {
StoreBufferOverflow(heap_->isolate()); StoreBufferOverflow(heap_->isolate());
......
...@@ -28,7 +28,6 @@ StoreBuffer::StoreBuffer(Heap* heap) ...@@ -28,7 +28,6 @@ StoreBuffer::StoreBuffer(Heap* heap)
} }
task_running_ = false; task_running_ = false;
insertion_callback = &InsertDuringRuntime; insertion_callback = &InsertDuringRuntime;
deletion_callback = &DeleteDuringRuntime;
} }
void StoreBuffer::SetUp() { void StoreBuffer::SetUp() {
...@@ -91,22 +90,11 @@ void StoreBuffer::TearDown() { ...@@ -91,22 +90,11 @@ void StoreBuffer::TearDown() {
} }
} }
void StoreBuffer::DeleteDuringRuntime(StoreBuffer* store_buffer, Address start,
Address end) {
DCHECK(store_buffer->mode() == StoreBuffer::NOT_IN_GC);
store_buffer->InsertDeletionIntoStoreBuffer(start, end);
}
void StoreBuffer::InsertDuringRuntime(StoreBuffer* store_buffer, Address slot) { void StoreBuffer::InsertDuringRuntime(StoreBuffer* store_buffer, Address slot) {
DCHECK(store_buffer->mode() == StoreBuffer::NOT_IN_GC); DCHECK(store_buffer->mode() == StoreBuffer::NOT_IN_GC);
store_buffer->InsertIntoStoreBuffer(slot); store_buffer->InsertIntoStoreBuffer(slot);
} }
void StoreBuffer::DeleteDuringGarbageCollection(StoreBuffer* store_buffer,
Address start, Address end) {
UNREACHABLE();
}
void StoreBuffer::InsertDuringGarbageCollection(StoreBuffer* store_buffer, void StoreBuffer::InsertDuringGarbageCollection(StoreBuffer* store_buffer,
Address slot) { Address slot) {
DCHECK(store_buffer->mode() != StoreBuffer::NOT_IN_GC); DCHECK(store_buffer->mode() != StoreBuffer::NOT_IN_GC);
...@@ -117,10 +105,8 @@ void StoreBuffer::SetMode(StoreBufferMode mode) { ...@@ -117,10 +105,8 @@ void StoreBuffer::SetMode(StoreBufferMode mode) {
mode_ = mode; mode_ = mode;
if (mode == NOT_IN_GC) { if (mode == NOT_IN_GC) {
insertion_callback = &InsertDuringRuntime; insertion_callback = &InsertDuringRuntime;
deletion_callback = &DeleteDuringRuntime;
} else { } else {
insertion_callback = &InsertDuringGarbageCollection; insertion_callback = &InsertDuringGarbageCollection;
deletion_callback = &DeleteDuringGarbageCollection;
} }
} }
...@@ -160,24 +146,9 @@ void StoreBuffer::MoveEntriesToRememberedSet(int index) { ...@@ -160,24 +146,9 @@ void StoreBuffer::MoveEntriesToRememberedSet(int index) {
MemoryChunk::BaseAddress(addr) != chunk->address()) { MemoryChunk::BaseAddress(addr) != chunk->address()) {
chunk = MemoryChunk::FromAnyPointerAddress(addr); chunk = MemoryChunk::FromAnyPointerAddress(addr);
} }
if (IsDeletionAddress(addr)) { if (addr != last_inserted_addr) {
last_inserted_addr = kNullAddress; RememberedSet<OLD_TO_NEW>::Insert(chunk, addr);
current++; last_inserted_addr = addr;
Address end = *current;
DCHECK(!IsDeletionAddress(end));
addr = UnmarkDeletionAddress(addr);
if (end) {
RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, addr, end,
SlotSet::PREFREE_EMPTY_BUCKETS);
} else {
RememberedSet<OLD_TO_NEW>::Remove(chunk, addr);
}
} else {
DCHECK(!IsDeletionAddress(addr));
if (addr != last_inserted_addr) {
RememberedSet<OLD_TO_NEW>::Insert(chunk, addr);
last_inserted_addr = addr;
}
} }
} }
lazy_top_[index] = nullptr; lazy_top_[index] = nullptr;
......
...@@ -33,17 +33,11 @@ class StoreBuffer { ...@@ -33,17 +33,11 @@ class StoreBuffer {
Max(static_cast<int>(kMinExpectedOSPageSize / kStoreBuffers), Max(static_cast<int>(kMinExpectedOSPageSize / kStoreBuffers),
1 << (11 + kSystemPointerSizeLog2)); 1 << (11 + kSystemPointerSizeLog2));
static const int kStoreBufferMask = kStoreBufferSize - 1; static const int kStoreBufferMask = kStoreBufferSize - 1;
static const intptr_t kDeletionTag = 1;
V8_EXPORT_PRIVATE static int StoreBufferOverflow(Isolate* isolate); V8_EXPORT_PRIVATE static int StoreBufferOverflow(Isolate* isolate);
static void DeleteDuringGarbageCollection(StoreBuffer* store_buffer,
Address start, Address end);
static void InsertDuringGarbageCollection(StoreBuffer* store_buffer, static void InsertDuringGarbageCollection(StoreBuffer* store_buffer,
Address slot); Address slot);
static void DeleteDuringRuntime(StoreBuffer* store_buffer, Address start,
Address end);
static void InsertDuringRuntime(StoreBuffer* store_buffer, Address slot); static void InsertDuringRuntime(StoreBuffer* store_buffer, Address slot);
explicit StoreBuffer(Heap* heap); explicit StoreBuffer(Heap* heap);
...@@ -61,19 +55,6 @@ class StoreBuffer { ...@@ -61,19 +55,6 @@ class StoreBuffer {
// the remembered set. // the remembered set.
void MoveAllEntriesToRememberedSet(); void MoveAllEntriesToRememberedSet();
inline bool IsDeletionAddress(Address address) const {
return address & kDeletionTag;
}
inline Address MarkDeletionAddress(Address address) {
return address | kDeletionTag;
}
inline Address UnmarkDeletionAddress(Address address) {
return address & ~kDeletionTag;
}
inline void InsertDeletionIntoStoreBuffer(Address start, Address end);
inline void InsertIntoStoreBuffer(Address slot); inline void InsertIntoStoreBuffer(Address slot);
void InsertEntry(Address slot) { void InsertEntry(Address slot) {
...@@ -83,16 +64,6 @@ class StoreBuffer { ...@@ -83,16 +64,6 @@ class StoreBuffer {
insertion_callback(this, slot); insertion_callback(this, slot);
} }
// If we only want to delete a single slot, end should be set to null which
// will be written into the second field. When processing the store buffer
// the more efficient Remove method will be called in this case.
void DeleteEntry(Address start, Address end = kNullAddress) {
// 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.
deletion_callback(this, start, end);
}
void SetMode(StoreBufferMode mode); void SetMode(StoreBufferMode mode);
// Used by the concurrent processing thread to transfer entries from the // Used by the concurrent processing thread to transfer entries from the
...@@ -174,7 +145,6 @@ class StoreBuffer { ...@@ -174,7 +145,6 @@ class StoreBuffer {
// Callbacks are more efficient than reading out the gc state for every // Callbacks are more efficient than reading out the gc state for every
// store buffer operation. // store buffer operation.
void (*insertion_callback)(StoreBuffer*, Address); void (*insertion_callback)(StoreBuffer*, Address);
void (*deletion_callback)(StoreBuffer*, Address, Address);
}; };
} // namespace internal } // namespace internal
......
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