Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(412)

Unified Diff: src/heap/remembered-set.h

Issue 2003553002: [heap] Introduce a new remembered set for typed pointers from old to new. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/heap/remembered-set.h
diff --git a/src/heap/remembered-set.h b/src/heap/remembered-set.h
index 801bdbfe8dd5f4b25e60817333549424863e28e0..548e4d4554c330bc9d71614e677a4dd8f0e3706c 100644
--- a/src/heap/remembered-set.h
+++ b/src/heap/remembered-set.h
@@ -5,6 +5,7 @@
#ifndef V8_REMEMBERED_SET_H
#define V8_REMEMBERED_SET_H
+#include "src/assembler.h"
#include "src/heap/heap.h"
#include "src/heap/slot-set.h"
#include "src/heap/spaces.h"
@@ -14,6 +15,7 @@ namespace internal {
enum PointerDirection { OLD_TO_OLD, OLD_TO_NEW };
+// TODO(ulan): Investigate performance of de-templatizing this class.
template <PointerDirection direction>
class RememberedSet {
public:
@@ -67,9 +69,7 @@ class RememberedSet {
// The callback should take (MemoryChunk* chunk) and return void.
template <typename Callback>
static void IterateMemoryChunks(Heap* heap, Callback callback) {
- MemoryChunkIterator it(heap, direction == OLD_TO_OLD
- ? MemoryChunkIterator::ALL
- : MemoryChunkIterator::ALL_BUT_CODE_SPACE);
+ MemoryChunkIterator it(heap);
MemoryChunk* chunk;
while ((chunk = it.next()) != nullptr) {
SlotSet* slots = GetSlotSet(chunk);
@@ -101,11 +101,10 @@ class RememberedSet {
// Given a page and a typed slot in that page, this function adds the slot
// to the remembered set.
static void InsertTyped(Page* page, SlotType slot_type, Address slot_addr) {
- STATIC_ASSERT(direction == OLD_TO_OLD);
- TypedSlotSet* slot_set = page->typed_old_to_old_slots();
+ TypedSlotSet* slot_set = GetTypedSlotSet(page);
if (slot_set == nullptr) {
- page->AllocateTypedOldToOldSlots();
- slot_set = page->typed_old_to_old_slots();
+ AllocateTypedSlotSet(page);
+ slot_set = GetTypedSlotSet(page);
}
uintptr_t offset = slot_addr - page->address();
DCHECK_LT(offset, static_cast<uintptr_t>(TypedSlotSet::kMaxOffset));
@@ -115,7 +114,7 @@ class RememberedSet {
// Given a page and a range of typed slots in that page, this function removes
// the slots from the remembered set.
static void RemoveRangeTyped(Page* page, Address start, Address end) {
- TypedSlotSet* slots = page->typed_old_to_old_slots();
+ TypedSlotSet* slots = GetTypedSlotSet(page);
if (slots != nullptr) {
slots->Iterate([start, end](SlotType slot_type, Address slot_addr) {
return start <= slot_addr && slot_addr < end ? REMOVE_SLOT : KEEP_SLOT;
@@ -123,15 +122,26 @@ class RememberedSet {
}
}
+ // Iterates and filters the remembered set with the given callback.
+ // The callback should take (SlotType slot_type, SlotAddress slot) and return
+ // SlotCallbackResult.
+ template <typename Callback>
+ static void IterateTyped(Heap* heap, Callback callback) {
+ IterateMemoryChunks(heap, [callback](MemoryChunk* chunk) {
+ IterateTyped(chunk, callback);
+ });
+ }
+
// Iterates and filters typed old to old pointers in the given memory chunk
// with the given callback. The callback should take (SlotType slot_type,
// Address slot_addr) and return SlotCallbackResult.
template <typename Callback>
static void IterateTyped(MemoryChunk* chunk, Callback callback) {
- TypedSlotSet* slots = chunk->typed_old_to_old_slots();
+ TypedSlotSet* slots = GetTypedSlotSet(chunk);
if (slots != nullptr) {
int new_count = slots->Iterate(callback);
if (new_count == 0) {
+ ReleaseTypedSlotSet(chunk);
chunk->ReleaseTypedOldToOldSlots();
}
}
@@ -140,7 +150,7 @@ class RememberedSet {
// Clear all old to old slots from the remembered set.
static void ClearAll(Heap* heap) {
STATIC_ASSERT(direction == OLD_TO_OLD);
- MemoryChunkIterator it(heap, MemoryChunkIterator::ALL);
+ MemoryChunkIterator it(heap);
MemoryChunk* chunk;
while ((chunk = it.next()) != nullptr) {
chunk->ReleaseOldToOldSlots();
@@ -169,7 +179,7 @@ class RememberedSet {
if (direction == OLD_TO_OLD) {
return chunk->typed_old_to_old_slots();
} else {
- return nullptr;
+ return chunk->typed_old_to_new_slots();
}
}
@@ -181,6 +191,14 @@ class RememberedSet {
}
}
+ static void ReleaseTypedSlotSet(MemoryChunk* chunk) {
+ if (direction == OLD_TO_OLD) {
+ chunk->ReleaseTypedOldToOldSlots();
+ } else {
+ chunk->ReleaseTypedOldToNewSlots();
+ }
+ }
+
static SlotSet* AllocateSlotSet(MemoryChunk* chunk) {
if (direction == OLD_TO_OLD) {
chunk->AllocateOldToOldSlots();
@@ -191,9 +209,135 @@ class RememberedSet {
}
}
+ static TypedSlotSet* AllocateTypedSlotSet(MemoryChunk* chunk) {
+ if (direction == OLD_TO_OLD) {
+ chunk->AllocateTypedOldToOldSlots();
+ return chunk->typed_old_to_old_slots();
+ } else {
+ chunk->AllocateTypedOldToNewSlots();
+ return chunk->typed_old_to_new_slots();
+ }
+ }
+
static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, Object** slot);
};
+class UpdateTypedSlotHelper {
+ public:
+ // Updates a cell slot using an untyped slot callback.
+ // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+ template <typename Callback>
+ static SlotCallbackResult UpdateCell(RelocInfo* rinfo, Callback callback) {
+ DCHECK(rinfo->rmode() == RelocInfo::CELL);
+ Object* cell = rinfo->target_cell();
+ Object* old_cell = cell;
+ SlotCallbackResult result = callback(&cell);
+ if (cell != old_cell) {
+ rinfo->set_target_cell(reinterpret_cast<Cell*>(cell));
+ }
+ return result;
+ }
+
+ // Updates a code entry slot using an untyped slot callback.
+ // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+ template <typename Callback>
+ static SlotCallbackResult UpdateCodeEntry(Address entry_address,
+ Callback callback) {
+ Object* code = Code::GetObjectFromEntryAddress(entry_address);
+ Object* old_code = code;
+ SlotCallbackResult result = callback(&code);
+ if (code != old_code) {
+ Memory::Address_at(entry_address) =
+ reinterpret_cast<Code*>(code)->entry();
+ }
+ return result;
+ }
+
+ // Updates a code target slot using an untyped slot callback.
+ // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+ template <typename Callback>
+ static SlotCallbackResult UpdateCodeTarget(RelocInfo* rinfo,
+ Callback callback) {
+ DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
+ Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+ Object* old_target = target;
+ SlotCallbackResult result = callback(&target);
+ if (target != old_target) {
+ rinfo->set_target_address(Code::cast(target)->instruction_start());
+ }
+ return result;
+ }
+
+ // Updates an embedded pointer slot using an untyped slot callback.
+ // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+ template <typename Callback>
+ static SlotCallbackResult UpdateEmbeddedPointer(RelocInfo* rinfo,
+ Callback callback) {
+ DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
+ Object* target = rinfo->target_object();
+ Object* old_target = target;
+ SlotCallbackResult result = callback(&target);
+ if (target != old_target) {
+ rinfo->set_target_object(target);
+ }
+ return result;
+ }
+
+ // Updates a debug target slot using an untyped slot callback.
+ // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+ template <typename Callback>
+ static SlotCallbackResult UpdateDebugTarget(RelocInfo* rinfo,
+ Callback callback) {
+ DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
+ rinfo->IsPatchedDebugBreakSlotSequence());
+ Object* target =
+ Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
+ SlotCallbackResult result = callback(&target);
+ rinfo->set_debug_call_address(Code::cast(target)->instruction_start());
+ return result;
+ }
+
+ // Updates a typed slot using an untyped slot callback.
+ // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
+ template <typename Callback>
+ static SlotCallbackResult UpdateTypedSlot(Isolate* isolate,
+ SlotType slot_type, Address addr,
+ Callback callback) {
+ switch (slot_type) {
+ case CODE_TARGET_SLOT: {
+ RelocInfo rinfo(isolate, addr, RelocInfo::CODE_TARGET, 0, NULL);
+ return UpdateCodeTarget(&rinfo, callback);
+ }
+ case CELL_TARGET_SLOT: {
+ RelocInfo rinfo(isolate, addr, RelocInfo::CELL, 0, NULL);
+ return UpdateCell(&rinfo, callback);
+ }
+ case CODE_ENTRY_SLOT: {
+ return UpdateCodeEntry(addr, callback);
+ }
+ case DEBUG_TARGET_SLOT: {
+ RelocInfo rinfo(isolate, addr, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION,
+ 0, NULL);
+ if (rinfo.IsPatchedDebugBreakSlotSequence()) {
+ return UpdateDebugTarget(&rinfo, callback);
+ }
+ return REMOVE_SLOT;
+ }
+ case EMBEDDED_OBJECT_SLOT: {
+ RelocInfo rinfo(isolate, addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL);
+ return UpdateEmbeddedPointer(&rinfo, callback);
+ }
+ case OBJECT_SLOT: {
+ return callback(reinterpret_cast<Object**>(addr));
+ }
+ case NUMBER_OF_SLOT_TYPES:
+ break;
+ }
+ UNREACHABLE();
+ return REMOVE_SLOT;
+ }
+};
+
} // namespace internal
} // namespace v8
« src/heap/mark-compact.cc ('K') | « src/heap/mark-compact.cc ('k') | src/heap/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698