Commit 3ddb2249 authored by ahaas's avatar ahaas Committed by Commit bot

[heap] Get rid of the wrapper in remembered-set.h

This patch moves the wrapper code from the remembered-set to the
scavenger and the mark-compact code.

The wrapper code inspected a slot address to see if the object that
belongs to the address is in the from-space. If it was in the
from-space, then some callback was executed on the object. If the object
got move to the to-space, then the wrapper returned KEEP_SLOT, otherwise
REMOVE_SLOT.

This logic does not really belong to the remembered set, so I moved it
away from there.

R=ulan@chromium.org

Review-Url: https://codereview.chromium.org/1994933002
Cr-Commit-Position: refs/heads/master@{#36364}
parent 80673927
......@@ -1669,8 +1669,9 @@ void Heap::Scavenge() {
{
// Copy objects reachable from the old generation.
TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_OLD_TO_NEW_POINTERS);
RememberedSet<OLD_TO_NEW>::IterateWithWrapper(this,
Scavenger::ScavengeObject);
RememberedSet<OLD_TO_NEW>::Iterate(this, [this](Address addr) {
return Scavenger::CheckAndScavengeObject(this, addr);
});
}
{
......
......@@ -3666,8 +3666,9 @@ class PointerUpdateJobTraits {
private:
static void UpdateUntypedPointers(Heap* heap, MemoryChunk* chunk) {
if (direction == OLD_TO_NEW) {
RememberedSet<OLD_TO_NEW>::IterateWithWrapper(heap, chunk,
UpdateOldToNewSlot);
RememberedSet<OLD_TO_NEW>::Iterate(chunk, [heap, chunk](Address slot) {
return CheckAndUpdateOldToNewSlot(heap, slot);
});
} else {
RememberedSet<OLD_TO_OLD>::Iterate(chunk, [](Address slot) {
return UpdateSlot(reinterpret_cast<Object**>(slot));
......@@ -3685,14 +3686,30 @@ class PointerUpdateJobTraits {
}
}
static void UpdateOldToNewSlot(HeapObject** address, HeapObject* object) {
MapWord map_word = object->map_word();
// There could still be stale pointers in large object space, map space,
// and old space for pages that have been promoted.
if (map_word.IsForwardingAddress()) {
// Update the corresponding slot.
*address = map_word.ToForwardingAddress();
static SlotCallbackResult CheckAndUpdateOldToNewSlot(Heap* heap,
Address slot_address) {
Object** slot = reinterpret_cast<Object**>(slot_address);
if (heap->InFromSpace(*slot)) {
HeapObject* heap_object = reinterpret_cast<HeapObject*>(*slot);
DCHECK(heap_object->IsHeapObject());
MapWord map_word = heap_object->map_word();
// There could still be stale pointers in large object space, map space,
// and old space for pages that have been promoted.
if (map_word.IsForwardingAddress()) {
// Update the corresponding slot.
*slot = map_word.ToForwardingAddress();
}
// If the object was in from space before and is after executing the
// callback in to space, the object is still live.
// Unfortunately, we do not know about the slot. It could be in a
// just freed free space object.
if (heap->InToSpace(*slot)) {
return KEEP_SLOT;
}
} else {
DCHECK(!heap->InNewSpace(*slot));
}
return REMOVE_SLOT;
}
};
......
......@@ -98,27 +98,6 @@ class RememberedSet {
}
}
// Iterates and filters the remembered set with the given callback.
// The callback should take (HeapObject** slot, HeapObject* target) and
// update the slot.
// A special wrapper takes care of filtering the slots based on their values.
// For OLD_TO_NEW case: slots that do not point to the ToSpace after
// callback invocation will be removed from the set.
template <typename Callback>
static void IterateWithWrapper(Heap* heap, Callback callback) {
Iterate(heap, [heap, callback](Address addr) {
return Wrapper(heap, addr, callback);
});
}
template <typename Callback>
static void IterateWithWrapper(Heap* heap, MemoryChunk* chunk,
Callback callback) {
Iterate(chunk, [heap, callback](Address addr) {
return Wrapper(heap, addr, callback);
});
}
// 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) {
......@@ -212,30 +191,6 @@ class RememberedSet {
}
}
template <typename Callback>
static SlotCallbackResult Wrapper(Heap* heap, Address slot_address,
Callback slot_callback) {
STATIC_ASSERT(direction == OLD_TO_NEW);
Object** slot = reinterpret_cast<Object**>(slot_address);
Object* object = *slot;
if (heap->InFromSpace(object)) {
HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
DCHECK(heap_object->IsHeapObject());
slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object);
object = *slot;
// If the object was in from space before and is after executing the
// callback in to space, the object is still live.
// Unfortunately, we do not know about the slot. It could be in a
// just freed free space object.
if (heap->InToSpace(object)) {
return KEEP_SLOT;
}
} else {
DCHECK(!heap->InNewSpace(object));
}
return REMOVE_SLOT;
}
static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, Object** slot);
};
......
......@@ -37,6 +37,29 @@ void Scavenger::ScavengeObject(HeapObject** p, HeapObject* object) {
return ScavengeObjectSlow(p, object);
}
SlotCallbackResult Scavenger::CheckAndScavengeObject(Heap* heap,
Address slot_address) {
Object** slot = reinterpret_cast<Object**>(slot_address);
Object* object = *slot;
if (heap->InFromSpace(object)) {
HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
DCHECK(heap_object->IsHeapObject());
ScavengeObject(reinterpret_cast<HeapObject**>(slot), heap_object);
object = *slot;
// If the object was in from space before and is after executing the
// callback in to space, the object is still live.
// Unfortunately, we do not know about the slot. It could be in a
// just freed free space object.
if (heap->InToSpace(object)) {
return KEEP_SLOT;
}
} else {
DCHECK(!heap->InNewSpace(object));
}
return REMOVE_SLOT;
}
// static
void StaticScavengeVisitor::VisitPointer(Heap* heap, HeapObject* obj,
......
......@@ -6,6 +6,7 @@
#define V8_HEAP_SCAVENGER_H_
#include "src/heap/objects-visiting.h"
#include "src/heap/slot-set.h"
namespace v8 {
namespace internal {
......@@ -25,6 +26,8 @@ class Scavenger {
// ensure the precondition that the object is (a) a heap object and (b) in
// the heap's from space.
static inline void ScavengeObject(HeapObject** p, HeapObject* object);
static inline SlotCallbackResult CheckAndScavengeObject(Heap* heap,
Address slot_address);
// Slow part of {ScavengeObject} above.
static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
......
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