Commit 7d3f9f13 authored by ahaas's avatar ahaas Committed by Commit bot

[heap] Pass a force_promotion flag to the evacuation routine in the scavenger.

The {force_promotion} flag causes the scavenger to move an object to the
old generation instead of to the other semi-space. We use the flag to force
the promotion of objects which are referenced by code objects.

R=ulan@chromium.org

Committed: https://crrev.com/f2a7ba6449406d0b11a245aa1f5b4981265b6f20
Cr-Commit-Position: refs/heads/master@{#36443}

Review-Url: https://codereview.chromium.org/2002013002
Cr-Commit-Position: refs/heads/master@{#36462}
parent d2dff032
......@@ -1670,15 +1670,18 @@ void Heap::Scavenge() {
// Copy objects reachable from the old generation.
TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_OLD_TO_NEW_POINTERS);
RememberedSet<OLD_TO_NEW>::Iterate(this, [this](Address addr) {
return Scavenger::CheckAndScavengeObject(this, addr);
return Scavenger::CheckAndScavengeObject(this, addr, DEFAULT_PROMOTION);
});
RememberedSet<OLD_TO_NEW>::IterateTyped(
this, [this](SlotType type, Address addr) {
return UpdateTypedSlotHelper::UpdateTypedSlot(
isolate(), type, addr, [this](Object** addr) {
// We expect that objects referenced by code are long living.
// If we do not force promotion, then we need to clear
// old_to_new slots in dead code objects after mark-compact.
return Scavenger::CheckAndScavengeObject(
this, reinterpret_cast<Address>(addr));
this, reinterpret_cast<Address>(addr), FORCE_PROMOTION);
});
});
}
......@@ -4666,8 +4669,8 @@ void Heap::IteratePromotedObjectPointers(HeapObject* object, Address start,
Object* target = *slot;
if (target->IsHeapObject()) {
if (Heap::InFromSpace(target)) {
callback(reinterpret_cast<HeapObject**>(slot),
HeapObject::cast(target));
callback(reinterpret_cast<HeapObject**>(slot), HeapObject::cast(target),
DEFAULT_PROMOTION);
Object* new_target = *slot;
if (InNewSpace(new_target)) {
SLOW_DCHECK(Heap::InToSpace(new_target));
......
......@@ -301,7 +301,10 @@ class Scavenger;
class ScavengeJob;
class WeakObjectRetainer;
typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to);
enum PromotionMode { FORCE_PROMOTION, DEFAULT_PROMOTION };
typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to,
PromotionMode mode);
// A queue of objects promoted during scavenge. Each object is accompanied
// by it's size to avoid dereferencing a map pointer for scanning.
......
......@@ -10,7 +10,8 @@
namespace v8 {
namespace internal {
void Scavenger::ScavengeObject(HeapObject** p, HeapObject* object) {
void Scavenger::ScavengeObject(HeapObject** p, HeapObject* object,
PromotionMode promotion_mode) {
DCHECK(object->GetIsolate()->heap()->InFromSpace(object));
// We use the first word (where the map pointer usually is) of a heap
......@@ -34,18 +35,19 @@ void Scavenger::ScavengeObject(HeapObject** p, HeapObject* object) {
// AllocationMementos are unrooted and shouldn't survive a scavenge
DCHECK(object->map() != object->GetHeap()->allocation_memento_map());
// Call the slow part of scavenge object.
return ScavengeObjectSlow(p, object);
return ScavengeObjectSlow(p, object, promotion_mode);
}
SlotCallbackResult Scavenger::CheckAndScavengeObject(Heap* heap,
Address slot_address) {
SlotCallbackResult Scavenger::CheckAndScavengeObject(
Heap* heap, Address slot_address, PromotionMode promotion_mode) {
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);
ScavengeObject(reinterpret_cast<HeapObject**>(slot), heap_object,
promotion_mode);
object = *slot;
// If the object was in from space before and is after executing the
......@@ -67,7 +69,8 @@ void StaticScavengeVisitor::VisitPointer(Heap* heap, HeapObject* obj,
Object* object = *p;
if (!heap->InNewSpace(object)) return;
Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(p),
reinterpret_cast<HeapObject*>(object));
reinterpret_cast<HeapObject*>(object),
DEFAULT_PROMOTION);
}
} // namespace internal
......
This diff is collapsed.
......@@ -12,7 +12,8 @@ namespace v8 {
namespace internal {
typedef void (*ScavengingCallback)(Map* map, HeapObject** slot,
HeapObject* object);
HeapObject* object,
PromotionMode promotion_mode);
class Scavenger {
public:
......@@ -25,12 +26,15 @@ class Scavenger {
// necessary, the object might be promoted to an old space. The caller must
// 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);
static inline void ScavengeObject(
HeapObject** p, HeapObject* object,
PromotionMode promotion_mode = DEFAULT_PROMOTION);
static inline SlotCallbackResult CheckAndScavengeObject(
Heap* heap, Address slot_address, PromotionMode promotion_mode);
// Slow part of {ScavengeObject} above.
static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
static void ScavengeObjectSlow(HeapObject** p, HeapObject* object,
PromotionMode promotion_mode);
// Chooses an appropriate static visitor table depending on the current state
// of the heap (i.e. incremental marking, logging and profiling).
......
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