Commit f88fe51a authored by mlippautz's avatar mlippautz Committed by Commit bot

[heap] Remove PromotionMode used by Scavenger

The scavenger should never consider mark bits for promotion/copy as this creates
weird livetimes at the start of incremental marking. E.g. consider an object
marked black by the marker at the start of incremental marking. A scavenge would
promote it to the old generation although it could --and for short-living
objects actually does-- become unreachable during marking

Also, keeping this invariant significantly simplifies young generation mark
compacting as we can compare against the scavenging decision without keeping
different sets of markbits.

BUG=chromium:651354
R=hpayer@chromium.org

Review-Url: https://codereview.chromium.org/2397713002
Cr-Commit-Position: refs/heads/master@{#40026}
parent 6d9b2e12
......@@ -490,30 +490,13 @@ bool Heap::InOldSpaceSlow(Address address) {
return old_space_->ContainsSlow(address);
}
template <PromotionMode promotion_mode>
bool Heap::ShouldBePromoted(Address old_address, int object_size) {
Page* page = Page::FromAddress(old_address);
Address age_mark = new_space_->age_mark();
if (promotion_mode == PROMOTE_MARKED) {
MarkBit mark_bit = ObjectMarking::MarkBitFrom(old_address);
if (!Marking::IsWhite(mark_bit)) {
return true;
}
}
return page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) &&
(!page->ContainsLimit(age_mark) || old_address < age_mark);
}
PromotionMode Heap::CurrentPromotionMode() {
if (incremental_marking()->IsMarking()) {
return PROMOTE_MARKED;
} else {
return DEFAULT_PROMOTION;
}
}
void Heap::RecordWrite(Object* object, int offset, Object* o) {
if (!InNewSpace(o) || !object->IsHeapObject() || InNewSpace(object)) {
return;
......
......@@ -1639,7 +1639,6 @@ void Heap::Scavenge() {
Address new_space_front = new_space_->ToSpaceStart();
promotion_queue_.Initialize();
PromotionMode promotion_mode = CurrentPromotionMode();
ScavengeVisitor scavenge_visitor(this);
if (FLAG_scavenge_reclaim_unmodified_objects) {
......@@ -1692,8 +1691,7 @@ void Heap::Scavenge() {
{
TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_SEMISPACE);
new_space_front =
DoScavenge(&scavenge_visitor, new_space_front, promotion_mode);
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
}
if (FLAG_scavenge_reclaim_unmodified_objects) {
......@@ -1702,14 +1700,12 @@ void Heap::Scavenge() {
isolate()->global_handles()->IterateNewSpaceWeakUnmodifiedRoots(
&scavenge_visitor);
new_space_front =
DoScavenge(&scavenge_visitor, new_space_front, promotion_mode);
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
} else {
TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_OBJECT_GROUPS);
while (isolate()->global_handles()->IterateObjectGroups(
&scavenge_visitor, &IsUnscavengedHeapObject)) {
new_space_front =
DoScavenge(&scavenge_visitor, new_space_front, promotion_mode);
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
}
isolate()->global_handles()->RemoveObjectGroups();
isolate()->global_handles()->RemoveImplicitRefGroups();
......@@ -1719,8 +1715,7 @@ void Heap::Scavenge() {
isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots(
&scavenge_visitor);
new_space_front =
DoScavenge(&scavenge_visitor, new_space_front, promotion_mode);
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
}
UpdateNewSpaceReferencesInExternalStringTable(
......@@ -1904,8 +1899,7 @@ void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
}
Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
Address new_space_front,
PromotionMode promotion_mode) {
Address new_space_front) {
do {
SemiSpace::AssertValidRange(new_space_front, new_space_->top());
// The addresses new_space_front and new_space_.top() define a
......@@ -1914,14 +1908,8 @@ Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
while (new_space_front != new_space_->top()) {
if (!Page::IsAlignedToPageSize(new_space_front)) {
HeapObject* object = HeapObject::FromAddress(new_space_front);
if (promotion_mode == PROMOTE_MARKED) {
new_space_front += StaticScavengeVisitor<PROMOTE_MARKED>::IterateBody(
object->map(), object);
} else {
new_space_front +=
StaticScavengeVisitor<DEFAULT_PROMOTION>::IterateBody(
object->map(), object);
}
new_space_front +=
StaticScavengeVisitor::IterateBody(object->map(), object);
} else {
new_space_front = Page::FromAllocationAreaAddress(new_space_front)
->next_page()
......@@ -5433,8 +5421,7 @@ V8_DECLARE_ONCE(initialize_gc_once);
static void InitializeGCOnce() {
Scavenger::Initialize();
StaticScavengeVisitor<DEFAULT_PROMOTION>::Initialize();
StaticScavengeVisitor<PROMOTE_MARKED>::Initialize();
StaticScavengeVisitor::Initialize();
MarkCompactCollector::Initialize();
}
......
......@@ -342,8 +342,6 @@ class WeakObjectRetainer;
typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to);
enum PromotionMode { PROMOTE_MARKED, DEFAULT_PROMOTION };
enum ArrayStorageAllocationMode {
DONT_INITIALIZE_ARRAY_ELEMENTS,
INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE
......@@ -835,11 +833,8 @@ class Heap {
// An object should be promoted if the object has survived a
// scavenge operation.
template <PromotionMode promotion_mode>
inline bool ShouldBePromoted(Address old_address, int object_size);
inline PromotionMode CurrentPromotionMode();
void ClearNormalizedMapCaches();
void IncrementDeferredCount(v8::Isolate::UseCounterFeature feature);
......@@ -1786,8 +1781,7 @@ class Heap {
// Performs a minor collection in new generation.
void Scavenge();
Address DoScavenge(ObjectVisitor* scavenge_visitor, Address new_space_front,
PromotionMode promotion_mode);
Address DoScavenge(ObjectVisitor* scavenge_visitor, Address new_space_front);
void UpdateNewSpaceReferencesInExternalStringTable(
ExternalStringTableUpdaterCallback updater_func);
......
......@@ -1720,7 +1720,7 @@ class MarkCompactCollector::EvacuateNewSpaceVisitor final
local_pretenuring_feedback_);
int size = object->Size();
HeapObject* target_object = nullptr;
if (heap_->ShouldBePromoted<DEFAULT_PROMOTION>(object->address(), size) &&
if (heap_->ShouldBePromoted(object->address(), size) &&
TryEvacuateObject(compaction_spaces_->Get(OLD_SPACE), object,
&target_object)) {
promoted_size_ += size;
......
......@@ -62,10 +62,8 @@ SlotCallbackResult Scavenger::CheckAndScavengeObject(Heap* heap,
}
// static
template <PromotionMode promotion_mode>
void StaticScavengeVisitor<promotion_mode>::VisitPointer(Heap* heap,
HeapObject* obj,
Object** p) {
void StaticScavengeVisitor::VisitPointer(Heap* heap, HeapObject* obj,
Object** p) {
Object* object = *p;
if (!heap->InNewSpace(object)) return;
Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(p),
......
......@@ -22,7 +22,7 @@ enum LoggingAndProfiling {
enum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS };
template <MarksHandling marks_handling, PromotionMode promotion_mode,
template <MarksHandling marks_handling,
LoggingAndProfiling logging_and_profiling_mode>
class ScavengingVisitor : public StaticVisitorBase {
public:
......@@ -206,8 +206,7 @@ class ScavengingVisitor : public StaticVisitorBase {
SLOW_DCHECK(object->Size() == object_size);
Heap* heap = map->GetHeap();
if (!heap->ShouldBePromoted<promotion_mode>(object->address(),
object_size)) {
if (!heap->ShouldBePromoted(object->address(), object_size)) {
// A semi-space copy may fail due to fragmentation. In that case, we
// try to promote the object.
if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) {
......@@ -219,9 +218,7 @@ class ScavengingVisitor : public StaticVisitorBase {
object_size)) {
return;
}
if (promotion_mode == PROMOTE_MARKED) {
FatalProcessOutOfMemory("Scavenger: promoting marked\n");
}
// If promotion failed, we try to copy the object to the other semi-space
if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) return;
......@@ -358,21 +355,19 @@ class ScavengingVisitor : public StaticVisitorBase {
static VisitorDispatchTable<ScavengingCallback> table_;
};
template <MarksHandling marks_handling, PromotionMode promotion_mode,
template <MarksHandling marks_handling,
LoggingAndProfiling logging_and_profiling_mode>
VisitorDispatchTable<ScavengingCallback> ScavengingVisitor<
marks_handling, promotion_mode, logging_and_profiling_mode>::table_;
VisitorDispatchTable<ScavengingCallback>
ScavengingVisitor<marks_handling, logging_and_profiling_mode>::table_;
// static
void Scavenger::Initialize() {
ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED,
ScavengingVisitor<TRANSFER_MARKS,
LOGGING_AND_PROFILING_DISABLED>::Initialize();
ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION,
LOGGING_AND_PROFILING_DISABLED>::Initialize();
ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED,
LOGGING_AND_PROFILING_ENABLED>::Initialize();
ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION,
ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::Initialize();
ScavengingVisitor<TRANSFER_MARKS,
LOGGING_AND_PROFILING_ENABLED>::Initialize();
ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize();
}
......@@ -397,21 +392,21 @@ void Scavenger::SelectScavengingVisitorsTable() {
if (!heap()->incremental_marking()->IsMarking()) {
if (!logging_and_profiling) {
scavenging_visitors_table_.CopyFrom(
ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION,
ScavengingVisitor<IGNORE_MARKS,
LOGGING_AND_PROFILING_DISABLED>::GetTable());
} else {
scavenging_visitors_table_.CopyFrom(
ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION,
ScavengingVisitor<IGNORE_MARKS,
LOGGING_AND_PROFILING_ENABLED>::GetTable());
}
} else {
if (!logging_and_profiling) {
scavenging_visitors_table_.CopyFrom(
ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED,
ScavengingVisitor<TRANSFER_MARKS,
LOGGING_AND_PROFILING_DISABLED>::GetTable());
} else {
scavenging_visitors_table_.CopyFrom(
ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED,
ScavengingVisitor<TRANSFER_MARKS,
LOGGING_AND_PROFILING_ENABLED>::GetTable());
}
......
......@@ -63,9 +63,8 @@ class ScavengeVisitor : public ObjectVisitor {
// Helper class for turning the scavenger into an object visitor that is also
// filtering out non-HeapObjects and objects which do not reside in new space.
template <PromotionMode promotion_mode>
class StaticScavengeVisitor
: public StaticNewSpaceVisitor<StaticScavengeVisitor<promotion_mode>> {
: public StaticNewSpaceVisitor<StaticScavengeVisitor> {
public:
static inline void VisitPointer(Heap* heap, HeapObject* object, Object** p);
};
......
......@@ -749,46 +749,6 @@ TEST(DeleteWeakGlobalHandle) {
CHECK(WeakPointerCleared);
}
TEST(DoNotPromoteWhiteObjectsOnScavenge) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<Object> white = factory->NewStringFromStaticChars("white");
CHECK(Marking::IsWhite(ObjectMarking::MarkBitFrom(HeapObject::cast(*white))));
CcTest::CollectGarbage(NEW_SPACE);
CHECK(heap->InNewSpace(*white));
}
TEST(PromoteGreyOrBlackObjectsOnScavenge) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<Object> marked = factory->NewStringFromStaticChars("marked");
IncrementalMarking* marking = heap->incremental_marking();
marking->Stop();
heap->StartIncrementalMarking(i::Heap::kNoGCFlags,
i::GarbageCollectionReason::kTesting);
while (
Marking::IsWhite(ObjectMarking::MarkBitFrom(HeapObject::cast(*marked)))) {
marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD,
IncrementalMarking::DO_NOT_FORCE_COMPLETION, StepOrigin::kV8);
}
CcTest::CollectGarbage(NEW_SPACE);
CHECK(!heap->InNewSpace(*marked));
}
TEST(BytecodeArray) {
static const uint8_t kRawBytes[] = {0xc3, 0x7e, 0xa5, 0x5a};
static const int kRawBytesSize = sizeof(kRawBytes);
......
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