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

[heap] Provide ObjectMarking with marking transitions

BUG=chromium:651354

Review-Url: https://codereview.chromium.org/2644523002
Cr-Commit-Position: refs/heads/master@{#42531}
parent 3e407093
...@@ -19,8 +19,7 @@ void LocalArrayBufferTracker::Free() { ...@@ -19,8 +19,7 @@ void LocalArrayBufferTracker::Free() {
for (TrackingData::iterator it = array_buffers_.begin(); for (TrackingData::iterator it = array_buffers_.begin();
it != array_buffers_.end();) { it != array_buffers_.end();) {
JSArrayBuffer* buffer = reinterpret_cast<JSArrayBuffer*>(it->first); JSArrayBuffer* buffer = reinterpret_cast<JSArrayBuffer*>(it->first);
if ((free_mode == kFreeAll) || if ((free_mode == kFreeAll) || ObjectMarking::IsWhite(buffer)) {
Marking::IsWhite(ObjectMarking::MarkBitFrom(buffer))) {
const size_t len = it->second; const size_t len = it->second;
heap_->isolate()->array_buffer_allocator()->Free(buffer->backing_store(), heap_->isolate()->array_buffer_allocator()->Free(buffer->backing_store(),
len); len);
......
...@@ -3183,7 +3183,7 @@ void Heap::AdjustLiveBytes(HeapObject* object, int by) { ...@@ -3183,7 +3183,7 @@ void Heap::AdjustLiveBytes(HeapObject* object, int by) {
lo_space()->AdjustLiveBytes(by); lo_space()->AdjustLiveBytes(by);
} else if (!in_heap_iterator() && } else if (!in_heap_iterator() &&
!mark_compact_collector()->sweeping_in_progress() && !mark_compact_collector()->sweeping_in_progress() &&
Marking::IsBlack(ObjectMarking::MarkBitFrom(object))) { ObjectMarking::IsBlack(object)) {
DCHECK(MemoryChunk::FromAddress(object->address())->SweepingDone()); DCHECK(MemoryChunk::FromAddress(object->address())->SweepingDone());
MemoryChunk::IncrementLiveBytes(object, by); MemoryChunk::IncrementLiveBytes(object, by);
} }
...@@ -3193,6 +3193,7 @@ void Heap::AdjustLiveBytes(HeapObject* object, int by) { ...@@ -3193,6 +3193,7 @@ void Heap::AdjustLiveBytes(HeapObject* object, int by) {
FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object,
int elements_to_trim) { int elements_to_trim) {
CHECK_NOT_NULL(object); CHECK_NOT_NULL(object);
DCHECK(CanMoveObjectStart(object));
DCHECK(!object->IsFixedTypedArrayBase()); DCHECK(!object->IsFixedTypedArrayBase());
DCHECK(!object->IsByteArray()); DCHECK(!object->IsByteArray());
const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize; const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize;
...@@ -3243,7 +3244,6 @@ FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, ...@@ -3243,7 +3244,6 @@ FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object,
// Initialize header of the trimmed array. Since left trimming is only // Initialize header of the trimmed array. Since left trimming is only
// performed on pages which are not concurrently swept creating a filler // performed on pages which are not concurrently swept creating a filler
// object does not require synchronization. // object does not require synchronization.
DCHECK(CanMoveObjectStart(object));
Object** former_start = HeapObject::RawField(object, 0); Object** former_start = HeapObject::RawField(object, 0);
int new_start_index = elements_to_trim * (element_size / kPointerSize); int new_start_index = elements_to_trim * (element_size / kPointerSize);
former_start[new_start_index] = map; former_start[new_start_index] = map;
...@@ -3314,7 +3314,7 @@ void Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) { ...@@ -3314,7 +3314,7 @@ void Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) {
// Clear the mark bits of the black area that belongs now to the filler. // Clear the mark bits of the black area that belongs now to the filler.
// This is an optimization. The sweeper will release black fillers anyway. // This is an optimization. The sweeper will release black fillers anyway.
if (incremental_marking()->black_allocation() && if (incremental_marking()->black_allocation() &&
Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(filler))) { ObjectMarking::IsBlackOrGrey(filler)) {
Page* page = Page::FromAddress(new_end); Page* page = Page::FromAddress(new_end);
page->markbits()->ClearRange( page->markbits()->ClearRange(
page->AddressToMarkbitIndex(new_end), page->AddressToMarkbitIndex(new_end),
...@@ -4309,17 +4309,19 @@ void Heap::RegisterReservationsForBlackAllocation(Reservation* reservations) { ...@@ -4309,17 +4309,19 @@ void Heap::RegisterReservationsForBlackAllocation(Reservation* reservations) {
// Hence we have to color all objects of the reservation first black to avoid // Hence we have to color all objects of the reservation first black to avoid
// unnecessary marking deque load. // unnecessary marking deque load.
if (incremental_marking()->black_allocation()) { if (incremental_marking()->black_allocation()) {
for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) { for (int i = CODE_SPACE; i < Serializer::kNumberOfSpaces; i++) {
const Heap::Reservation& res = reservations[i]; const Heap::Reservation& res = reservations[i];
for (auto& chunk : res) { for (auto& chunk : res) {
Address addr = chunk.start; Address addr = chunk.start;
while (addr < chunk.end) { while (addr < chunk.end) {
HeapObject* obj = HeapObject::FromAddress(addr); HeapObject* obj = HeapObject::FromAddress(addr);
Marking::MarkBlack(ObjectMarking::MarkBitFrom(obj)); ObjectMarking::WhiteToBlack(obj);
addr += obj->Size(); addr += obj->Size();
} }
} }
} }
// Iterate black objects in old space, code space, map space, and large
// object space for side effects.
for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) { for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) {
const Heap::Reservation& res = reservations[i]; const Heap::Reservation& res = reservations[i];
for (auto& chunk : res) { for (auto& chunk : res) {
...@@ -4898,8 +4900,7 @@ void Heap::IterateAndScavengePromotedObject(HeapObject* target, int size, ...@@ -4898,8 +4900,7 @@ void Heap::IterateAndScavengePromotedObject(HeapObject* target, int size,
// it would be a violation of the invariant to record it's slots. // it would be a violation of the invariant to record it's slots.
bool record_slots = false; bool record_slots = false;
if (incremental_marking()->IsCompacting()) { if (incremental_marking()->IsCompacting()) {
MarkBit mark_bit = ObjectMarking::MarkBitFrom(target); record_slots = ObjectMarking::IsBlack(target);
record_slots = Marking::IsBlack(mark_bit);
} }
IterateAndScavengePromotedObjectsVisitor visitor(this, target, record_slots); IterateAndScavengePromotedObjectsVisitor visitor(this, target, record_slots);
...@@ -6137,8 +6138,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter { ...@@ -6137,8 +6138,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
bool SkipObject(HeapObject* object) { bool SkipObject(HeapObject* object) {
if (object->IsFiller()) return true; if (object->IsFiller()) return true;
MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); return ObjectMarking::IsWhite(object);
return Marking::IsWhite(mark_bit);
} }
private: private:
...@@ -6150,6 +6150,8 @@ class UnreachableObjectsFilter : public HeapObjectsFilter { ...@@ -6150,6 +6150,8 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
for (Object** p = start; p < end; p++) { for (Object** p = start; p < end; p++) {
if (!(*p)->IsHeapObject()) continue; if (!(*p)->IsHeapObject()) continue;
HeapObject* obj = HeapObject::cast(*p); HeapObject* obj = HeapObject::cast(*p);
// Use Marking instead of ObjectMarking to avoid adjusting live bytes
// counter.
MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj);
if (Marking::IsWhite(mark_bit)) { if (Marking::IsWhite(mark_bit)) {
Marking::WhiteToBlack(mark_bit); Marking::WhiteToBlack(mark_bit);
......
...@@ -39,15 +39,12 @@ IncrementalMarking::IncrementalMarking(Heap* heap) ...@@ -39,15 +39,12 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) { bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) {
HeapObject* value_heap_obj = HeapObject::cast(value); HeapObject* value_heap_obj = HeapObject::cast(value);
MarkBit value_bit = ObjectMarking::MarkBitFrom(value_heap_obj); DCHECK(!ObjectMarking::IsImpossible(value_heap_obj));
DCHECK(!Marking::IsImpossible(value_bit)); DCHECK(!ObjectMarking::IsImpossible(obj));
const bool is_black = ObjectMarking::IsBlack(obj);
MarkBit obj_bit = ObjectMarking::MarkBitFrom(obj); if (is_black && ObjectMarking::IsWhite(value_heap_obj)) {
DCHECK(!Marking::IsImpossible(obj_bit)); WhiteToGreyAndPush(value_heap_obj);
bool is_black = Marking::IsBlack(obj_bit);
if (is_black && Marking::IsWhite(value_bit)) {
WhiteToGreyAndPush(value_heap_obj, value_bit);
RestartIfNotMarking(); RestartIfNotMarking();
} }
return is_compacting_ && is_black; return is_compacting_ && is_black;
...@@ -118,9 +115,8 @@ void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo, ...@@ -118,9 +115,8 @@ void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo,
} }
} }
void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj) {
void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { ObjectMarking::WhiteToGrey(obj);
Marking::WhiteToGrey(mark_bit);
heap_->mark_compact_collector()->marking_deque()->Push(obj); heap_->mark_compact_collector()->marking_deque()->Push(obj);
} }
...@@ -128,16 +124,13 @@ void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { ...@@ -128,16 +124,13 @@ void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
static void MarkObjectGreyDoNotEnqueue(Object* obj) { static void MarkObjectGreyDoNotEnqueue(Object* obj) {
if (obj->IsHeapObject()) { if (obj->IsHeapObject()) {
HeapObject* heap_obj = HeapObject::cast(obj); HeapObject* heap_obj = HeapObject::cast(obj);
MarkBit mark_bit = ObjectMarking::MarkBitFrom(HeapObject::cast(obj)); ObjectMarking::AnyToGrey(heap_obj);
if (Marking::IsBlack(mark_bit)) {
MemoryChunk::IncrementLiveBytes(heap_obj, -heap_obj->Size());
}
Marking::AnyToGrey(mark_bit);
} }
} }
void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from, void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from,
HeapObject* to) { HeapObject* to) {
DCHECK(MemoryChunk::FromAddress(from->address())->SweepingDone());
// This is only used when resizing an object. // This is only used when resizing an object.
DCHECK(MemoryChunk::FromAddress(from->address()) == DCHECK(MemoryChunk::FromAddress(from->address()) ==
MemoryChunk::FromAddress(to->address())); MemoryChunk::FromAddress(to->address()));
...@@ -158,11 +151,12 @@ void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from, ...@@ -158,11 +151,12 @@ void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from,
if (Marking::IsBlack(old_mark_bit)) { if (Marking::IsBlack(old_mark_bit)) {
Marking::BlackToWhite(old_mark_bit); Marking::BlackToWhite(old_mark_bit);
Marking::MarkBlack(new_mark_bit); Marking::WhiteToBlack(new_mark_bit);
return; return;
} else if (Marking::IsGrey(old_mark_bit)) { } else if (Marking::IsGrey(old_mark_bit)) {
Marking::GreyToWhite(old_mark_bit); Marking::GreyToWhite(old_mark_bit);
heap->incremental_marking()->WhiteToGreyAndPush(to, new_mark_bit); Marking::WhiteToGrey(new_mark_bit);
heap->mark_compact_collector()->marking_deque()->Push(to);
heap->incremental_marking()->RestartIfNotMarking(); heap->incremental_marking()->RestartIfNotMarking();
} }
...@@ -210,10 +204,10 @@ class IncrementalMarkingMarkingVisitor ...@@ -210,10 +204,10 @@ class IncrementalMarkingMarkingVisitor
} while (scan_until_end && start_offset < object_size); } while (scan_until_end && start_offset < object_size);
chunk->set_progress_bar(start_offset); chunk->set_progress_bar(start_offset);
if (start_offset < object_size) { if (start_offset < object_size) {
if (Marking::IsGrey(ObjectMarking::MarkBitFrom(object))) { if (ObjectMarking::IsGrey(object)) {
heap->mark_compact_collector()->marking_deque()->Unshift(object); heap->mark_compact_collector()->marking_deque()->Unshift(object);
} else { } else {
DCHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); DCHECK(ObjectMarking::IsBlack(object));
heap->mark_compact_collector()->UnshiftBlack(object); heap->mark_compact_collector()->UnshiftBlack(object);
} }
heap->incremental_marking()->NotifyIncompleteScanOfObject( heap->incremental_marking()->NotifyIncompleteScanOfObject(
...@@ -265,10 +259,8 @@ class IncrementalMarkingMarkingVisitor ...@@ -265,10 +259,8 @@ class IncrementalMarkingMarkingVisitor
// Returns true if object needed marking and false otherwise. // Returns true if object needed marking and false otherwise.
INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) {
HeapObject* heap_object = HeapObject::cast(obj); HeapObject* heap_object = HeapObject::cast(obj);
MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); if (ObjectMarking::IsWhite(heap_object)) {
if (Marking::IsWhite(mark_bit)) { ObjectMarking::WhiteToBlack(heap_object);
Marking::MarkBlack(mark_bit);
MemoryChunk::IncrementLiveBytes(heap_object, heap_object->Size());
return true; return true;
} }
return false; return false;
...@@ -276,7 +268,7 @@ class IncrementalMarkingMarkingVisitor ...@@ -276,7 +268,7 @@ class IncrementalMarkingMarkingVisitor
}; };
void IncrementalMarking::IterateBlackObject(HeapObject* object) { void IncrementalMarking::IterateBlackObject(HeapObject* object) {
if (IsMarking() && Marking::IsBlack(ObjectMarking::MarkBitFrom(object))) { if (IsMarking() && ObjectMarking::IsBlack(object)) {
Page* page = Page::FromAddress(object->address()); Page* page = Page::FromAddress(object->address());
if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) { if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) {
// IterateBlackObject requires us to visit the whole object. // IterateBlackObject requires us to visit the whole object.
...@@ -661,8 +653,7 @@ bool ShouldRetainMap(Map* map, int age) { ...@@ -661,8 +653,7 @@ bool ShouldRetainMap(Map* map, int age) {
} }
Object* constructor = map->GetConstructor(); Object* constructor = map->GetConstructor();
if (!constructor->IsHeapObject() || if (!constructor->IsHeapObject() ||
Marking::IsWhite( ObjectMarking::IsWhite(HeapObject::cast(constructor))) {
ObjectMarking::MarkBitFrom(HeapObject::cast(constructor)))) {
// The constructor is dead, no new objects with this map can // The constructor is dead, no new objects with this map can
// be created. Do not retain this map. // be created. Do not retain this map.
return false; return false;
...@@ -691,16 +682,14 @@ void IncrementalMarking::RetainMaps() { ...@@ -691,16 +682,14 @@ void IncrementalMarking::RetainMaps() {
int age = Smi::cast(retained_maps->Get(i + 1))->value(); int age = Smi::cast(retained_maps->Get(i + 1))->value();
int new_age; int new_age;
Map* map = Map::cast(cell->value()); Map* map = Map::cast(cell->value());
MarkBit map_mark = ObjectMarking::MarkBitFrom(map);
if (i >= number_of_disposed_maps && !map_retaining_is_disabled && if (i >= number_of_disposed_maps && !map_retaining_is_disabled &&
Marking::IsWhite(map_mark)) { ObjectMarking::IsWhite(map)) {
if (ShouldRetainMap(map, age)) { if (ShouldRetainMap(map, age)) {
MarkGrey(heap(), map); MarkGrey(heap(), map);
} }
Object* prototype = map->prototype(); Object* prototype = map->prototype();
if (age > 0 && prototype->IsHeapObject() && if (age > 0 && prototype->IsHeapObject() &&
Marking::IsWhite( ObjectMarking::IsWhite(HeapObject::cast(prototype))) {
ObjectMarking::MarkBitFrom(HeapObject::cast(prototype)))) {
// The prototype is not marked, age the map. // The prototype is not marked, age the map.
new_age = age - 1; new_age = age - 1;
} else { } else {
...@@ -807,15 +796,12 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { ...@@ -807,15 +796,12 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
// them. // them.
if (map_word.IsForwardingAddress()) { if (map_word.IsForwardingAddress()) {
HeapObject* dest = map_word.ToForwardingAddress(); HeapObject* dest = map_word.ToForwardingAddress();
if (Marking::IsBlack(ObjectMarking::MarkBitFrom(dest))) continue; if (ObjectMarking::IsBlack(dest)) continue;
array[new_top] = dest; array[new_top] = dest;
new_top = ((new_top + 1) & mask); new_top = ((new_top + 1) & mask);
DCHECK(new_top != marking_deque->bottom()); DCHECK(new_top != marking_deque->bottom());
#ifdef DEBUG DCHECK(ObjectMarking::IsGrey(obj) ||
MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); (obj->IsFiller() && ObjectMarking::IsWhite(obj)));
DCHECK(Marking::IsGrey(mark_bit) ||
(obj->IsFiller() && Marking::IsWhite(mark_bit)));
#endif
} }
} else if (obj->map() != filler_map) { } else if (obj->map() != filler_map) {
// Skip one word filler objects that appear on the // Skip one word filler objects that appear on the
...@@ -823,14 +809,11 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { ...@@ -823,14 +809,11 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
array[new_top] = obj; array[new_top] = obj;
new_top = ((new_top + 1) & mask); new_top = ((new_top + 1) & mask);
DCHECK(new_top != marking_deque->bottom()); DCHECK(new_top != marking_deque->bottom());
#ifdef DEBUG DCHECK(ObjectMarking::IsGrey(obj) ||
MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); (obj->IsFiller() && ObjectMarking::IsWhite(obj)) ||
MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); (MemoryChunk::FromAddress(obj->address())
DCHECK(Marking::IsGrey(mark_bit) || ->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
(obj->IsFiller() && Marking::IsWhite(mark_bit)) || ObjectMarking::IsBlack(obj)));
(chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
Marking::IsBlack(mark_bit)));
#endif
} }
} }
marking_deque->set_top(new_top); marking_deque->set_top(new_top);
...@@ -854,17 +837,14 @@ void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { ...@@ -854,17 +837,14 @@ void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) {
} }
void IncrementalMarking::MarkGrey(Heap* heap, HeapObject* object) { void IncrementalMarking::MarkGrey(Heap* heap, HeapObject* object) {
MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); if (ObjectMarking::IsWhite(object)) {
if (Marking::IsWhite(mark_bit)) { heap->incremental_marking()->WhiteToGreyAndPush(object);
heap->incremental_marking()->WhiteToGreyAndPush(object, mark_bit);
} }
} }
void IncrementalMarking::MarkBlack(HeapObject* obj, int size) { void IncrementalMarking::MarkBlack(HeapObject* obj, int size) {
MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); if (ObjectMarking::IsBlack(obj)) return;
if (Marking::IsBlack(mark_bit)) return; ObjectMarking::GreyToBlack(obj);
Marking::GreyToBlack(mark_bit);
MemoryChunk::IncrementLiveBytes(obj, size);
} }
intptr_t IncrementalMarking::ProcessMarkingDeque( intptr_t IncrementalMarking::ProcessMarkingDeque(
...@@ -879,8 +859,7 @@ intptr_t IncrementalMarking::ProcessMarkingDeque( ...@@ -879,8 +859,7 @@ intptr_t IncrementalMarking::ProcessMarkingDeque(
// Left trimming may result in white filler objects on the marking deque. // Left trimming may result in white filler objects on the marking deque.
// Ignore these objects. // Ignore these objects.
if (obj->IsFiller()) { if (obj->IsFiller()) {
DCHECK(Marking::IsImpossible(ObjectMarking::MarkBitFrom(obj)) || DCHECK(ObjectMarking::IsImpossible(obj) || ObjectMarking::IsWhite(obj));
Marking::IsWhite(ObjectMarking::MarkBitFrom(obj)));
continue; continue;
} }
...@@ -935,10 +914,8 @@ void IncrementalMarking::Hurry() { ...@@ -935,10 +914,8 @@ void IncrementalMarking::Hurry() {
HeapObject* cache = HeapObject::cast( HeapObject* cache = HeapObject::cast(
Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX)); Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX));
if (!cache->IsUndefined(heap_->isolate())) { if (!cache->IsUndefined(heap_->isolate())) {
MarkBit mark_bit = ObjectMarking::MarkBitFrom(cache); if (ObjectMarking::IsGrey(cache)) {
if (Marking::IsGrey(mark_bit)) { ObjectMarking::GreyToBlack(cache);
Marking::GreyToBlack(mark_bit);
MemoryChunk::IncrementLiveBytes(cache, cache->Size());
} }
} }
context = Context::cast(context)->next_context_link(); context = Context::cast(context)->next_context_link();
......
...@@ -158,7 +158,7 @@ class IncrementalMarking { ...@@ -158,7 +158,7 @@ class IncrementalMarking {
void RecordCodeTargetPatch(Code* host, Address pc, HeapObject* value); void RecordCodeTargetPatch(Code* host, Address pc, HeapObject* value);
void RecordCodeTargetPatch(Address pc, HeapObject* value); void RecordCodeTargetPatch(Address pc, HeapObject* value);
void WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit); void WhiteToGreyAndPush(HeapObject* obj);
inline void SetOldSpacePageFlags(MemoryChunk* chunk) { inline void SetOldSpacePageFlags(MemoryChunk* chunk) {
SetOldSpacePageFlags(chunk, IsMarking(), IsCompacting()); SetOldSpacePageFlags(chunk, IsMarking(), IsCompacting());
......
...@@ -13,48 +13,38 @@ namespace v8 { ...@@ -13,48 +13,38 @@ namespace v8 {
namespace internal { namespace internal {
void MarkCompactCollector::PushBlack(HeapObject* obj) { void MarkCompactCollector::PushBlack(HeapObject* obj) {
DCHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(obj))); DCHECK(ObjectMarking::IsBlack(obj));
if (marking_deque()->Push(obj)) { if (!marking_deque()->Push(obj)) {
MemoryChunk::IncrementLiveBytes(obj, obj->Size()); ObjectMarking::BlackToGrey(obj);
} else {
MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj);
Marking::BlackToGrey(mark_bit);
} }
} }
void MarkCompactCollector::UnshiftBlack(HeapObject* obj) { void MarkCompactCollector::UnshiftBlack(HeapObject* obj) {
DCHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(obj))); DCHECK(ObjectMarking::IsBlack(obj));
if (!marking_deque()->Unshift(obj)) { if (!marking_deque()->Unshift(obj)) {
MemoryChunk::IncrementLiveBytes(obj, -obj->Size()); ObjectMarking::BlackToGrey(obj);
MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj);
Marking::BlackToGrey(mark_bit);
} }
} }
void MarkCompactCollector::MarkObject(HeapObject* obj, MarkBit mark_bit) { void MarkCompactCollector::MarkObject(HeapObject* obj, MarkBit mark_bit) {
DCHECK(ObjectMarking::MarkBitFrom(obj) == mark_bit); DCHECK(ObjectMarking::MarkBitFrom(obj) == mark_bit);
if (Marking::IsWhite(mark_bit)) { if (ObjectMarking::IsWhite(obj)) {
Marking::WhiteToBlack(mark_bit); ObjectMarking::WhiteToBlack(obj);
DCHECK(obj->GetIsolate()->heap()->Contains(obj));
PushBlack(obj); PushBlack(obj);
} }
} }
void MarkCompactCollector::SetMark(HeapObject* obj) {
void MarkCompactCollector::SetMark(HeapObject* obj, MarkBit mark_bit) { DCHECK(ObjectMarking::IsWhite(obj));
DCHECK(Marking::IsWhite(mark_bit)); ObjectMarking::WhiteToBlack(obj);
DCHECK(ObjectMarking::MarkBitFrom(obj) == mark_bit);
Marking::WhiteToBlack(mark_bit);
MemoryChunk::IncrementLiveBytes(obj, obj->Size());
} }
bool MarkCompactCollector::IsMarked(Object* obj) { bool MarkCompactCollector::IsMarked(Object* obj) {
DCHECK(obj->IsHeapObject()); DCHECK(obj->IsHeapObject());
HeapObject* heap_object = HeapObject::cast(obj); return ObjectMarking::IsBlackOrGrey(HeapObject::cast(obj));
return Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(heap_object));
} }
...@@ -64,7 +54,7 @@ void MarkCompactCollector::RecordSlot(HeapObject* object, Object** slot, ...@@ -64,7 +54,7 @@ void MarkCompactCollector::RecordSlot(HeapObject* object, Object** slot,
Page* source_page = Page::FromAddress(reinterpret_cast<Address>(object)); Page* source_page = Page::FromAddress(reinterpret_cast<Address>(object));
if (target_page->IsEvacuationCandidate() && if (target_page->IsEvacuationCandidate() &&
!ShouldSkipEvacuationSlotRecording(object)) { !ShouldSkipEvacuationSlotRecording(object)) {
DCHECK(Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(object))); DCHECK(IsMarked(object));
RememberedSet<OLD_TO_OLD>::Insert(source_page, RememberedSet<OLD_TO_OLD>::Insert(source_page,
reinterpret_cast<Address>(slot)); reinterpret_cast<Address>(slot));
} }
......
This diff is collapsed.
...@@ -46,6 +46,76 @@ class ObjectMarking : public AllStatic { ...@@ -46,6 +46,76 @@ class ObjectMarking : public AllStatic {
return Marking::Color(ObjectMarking::MarkBitFrom(obj)); return Marking::Color(ObjectMarking::MarkBitFrom(obj));
} }
V8_INLINE static bool IsImpossible(HeapObject* obj) {
return Marking::IsImpossible(MarkBitFrom(obj));
}
V8_INLINE static bool IsBlack(HeapObject* obj) {
return Marking::IsBlack(MarkBitFrom(obj));
}
V8_INLINE static bool IsWhite(HeapObject* obj) {
return Marking::IsWhite(MarkBitFrom(obj));
}
V8_INLINE static bool IsGrey(HeapObject* obj) {
return Marking::IsGrey(MarkBitFrom(obj));
}
V8_INLINE static bool IsBlackOrGrey(HeapObject* obj) {
return Marking::IsBlackOrGrey(MarkBitFrom(obj));
}
V8_INLINE static void ClearMarkBit(HeapObject* obj) {
Marking::MarkWhite(MarkBitFrom(obj));
}
V8_INLINE static void BlackToWhite(HeapObject* obj) {
DCHECK(IsBlack(obj));
MarkBit markbit = MarkBitFrom(obj);
Marking::BlackToWhite(markbit);
MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
}
V8_INLINE static void GreyToWhite(HeapObject* obj) {
DCHECK(IsGrey(obj));
Marking::GreyToWhite(MarkBitFrom(obj));
}
V8_INLINE static void BlackToGrey(HeapObject* obj) {
DCHECK(IsBlack(obj));
MarkBit markbit = MarkBitFrom(obj);
Marking::BlackToGrey(markbit);
MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
}
V8_INLINE static void WhiteToGrey(HeapObject* obj) {
DCHECK(IsWhite(obj));
Marking::WhiteToGrey(MarkBitFrom(obj));
}
V8_INLINE static void WhiteToBlack(HeapObject* obj) {
DCHECK(IsWhite(obj));
MarkBit markbit = MarkBitFrom(obj);
Marking::WhiteToBlack(markbit);
MemoryChunk::IncrementLiveBytes(obj, obj->Size());
}
V8_INLINE static void GreyToBlack(HeapObject* obj) {
DCHECK(IsGrey(obj));
MarkBit markbit = MarkBitFrom(obj);
Marking::GreyToBlack(markbit);
MemoryChunk::IncrementLiveBytes(obj, obj->Size());
}
V8_INLINE static void AnyToGrey(HeapObject* obj) {
MarkBit markbit = MarkBitFrom(obj);
if (Marking::IsBlack(markbit)) {
MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
}
Marking::AnyToGrey(markbit);
}
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectMarking); DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectMarking);
}; };
...@@ -595,7 +665,7 @@ class MarkCompactCollector { ...@@ -595,7 +665,7 @@ class MarkCompactCollector {
// Marks the object black assuming that it is not yet marked. // Marks the object black assuming that it is not yet marked.
// This is for non-incremental marking only. // This is for non-incremental marking only.
INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit)); INLINE(void SetMark(HeapObject* obj));
// Mark the heap roots and all objects reachable from them. // Mark the heap roots and all objects reachable from them.
void MarkRoots(RootMarkingVisitor<MarkCompactMode::FULL>* visitor); void MarkRoots(RootMarkingVisitor<MarkCompactMode::FULL>* visitor);
......
...@@ -534,8 +534,7 @@ bool StaticMarkingVisitor<StaticVisitor>::IsFlushable(Heap* heap, ...@@ -534,8 +534,7 @@ bool StaticMarkingVisitor<StaticVisitor>::IsFlushable(Heap* heap,
// Code is either on stack, in compilation cache or referenced // Code is either on stack, in compilation cache or referenced
// by optimized version of function. // by optimized version of function.
MarkBit code_mark = ObjectMarking::MarkBitFrom(function->code()); if (ObjectMarking::IsBlackOrGrey(function->code())) {
if (Marking::IsBlackOrGrey(code_mark)) {
return false; return false;
} }
...@@ -558,8 +557,7 @@ bool StaticMarkingVisitor<StaticVisitor>::IsFlushable( ...@@ -558,8 +557,7 @@ bool StaticMarkingVisitor<StaticVisitor>::IsFlushable(
Heap* heap, SharedFunctionInfo* shared_info) { Heap* heap, SharedFunctionInfo* shared_info) {
// Code is either on stack, in compilation cache or referenced // Code is either on stack, in compilation cache or referenced
// by optimized version of function. // by optimized version of function.
MarkBit code_mark = ObjectMarking::MarkBitFrom(shared_info->code()); if (ObjectMarking::IsBlackOrGrey(shared_info->code())) {
if (Marking::IsBlackOrGrey(code_mark)) {
return false; return false;
} }
......
...@@ -200,9 +200,8 @@ class ScavengingVisitor : public StaticVisitorBase { ...@@ -200,9 +200,8 @@ class ScavengingVisitor : public StaticVisitorBase {
reinterpret_cast<base::AtomicWord>(target)); reinterpret_cast<base::AtomicWord>(target));
if (object_contents == POINTER_OBJECT) { if (object_contents == POINTER_OBJECT) {
heap->promotion_queue()->insert( heap->promotion_queue()->insert(target, object_size,
target, object_size, ObjectMarking::IsBlack(object));
Marking::IsBlack(ObjectMarking::MarkBitFrom(object)));
} }
heap->IncrementPromotedObjectsSize(object_size); heap->IncrementPromotedObjectsSize(object_size);
return true; return true;
...@@ -246,8 +245,7 @@ class ScavengingVisitor : public StaticVisitorBase { ...@@ -246,8 +245,7 @@ class ScavengingVisitor : public StaticVisitorBase {
DCHECK(map_word.IsForwardingAddress()); DCHECK(map_word.IsForwardingAddress());
HeapObject* target = map_word.ToForwardingAddress(); HeapObject* target = map_word.ToForwardingAddress();
MarkBit mark_bit = ObjectMarking::MarkBitFrom(target); if (ObjectMarking::IsBlack(target)) {
if (Marking::IsBlack(mark_bit)) {
// This object is black and it might not be rescanned by marker. // This object is black and it might not be rescanned by marker.
// We should explicitly record code entry slot for compaction because // We should explicitly record code entry slot for compaction because
// promotion queue processing (IteratePromotedObjectPointers) will // promotion queue processing (IteratePromotedObjectPointers) will
......
...@@ -1459,7 +1459,7 @@ void PagedSpace::Verify(ObjectVisitor* visitor) { ...@@ -1459,7 +1459,7 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
// All the interior pointers should be contained in the heap. // All the interior pointers should be contained in the heap.
int size = object->Size(); int size = object->Size();
object->IterateBody(map->instance_type(), size, visitor); object->IterateBody(map->instance_type(), size, visitor);
if (Marking::IsBlack(ObjectMarking::MarkBitFrom(object))) { if (ObjectMarking::IsBlack(object)) {
black_size += size; black_size += size;
} }
...@@ -2990,7 +2990,8 @@ AllocationResult LargeObjectSpace::AllocateRaw(int object_size, ...@@ -2990,7 +2990,8 @@ AllocationResult LargeObjectSpace::AllocateRaw(int object_size,
AllocationStep(object->address(), object_size); AllocationStep(object->address(), object_size);
if (heap()->incremental_marking()->black_allocation()) { if (heap()->incremental_marking()->black_allocation()) {
Marking::MarkBlack(ObjectMarking::MarkBitFrom(object)); // We cannot use ObjectMarking here as the object still lacks a size.
Marking::WhiteToBlack(ObjectMarking::MarkBitFrom(object));
MemoryChunk::IncrementLiveBytes(object, object_size); MemoryChunk::IncrementLiveBytes(object, object_size);
} }
return object; return object;
...@@ -3039,9 +3040,8 @@ void LargeObjectSpace::ClearMarkingStateOfLiveObjects() { ...@@ -3039,9 +3040,8 @@ void LargeObjectSpace::ClearMarkingStateOfLiveObjects() {
LargePage* current = first_page_; LargePage* current = first_page_;
while (current != NULL) { while (current != NULL) {
HeapObject* object = current->GetObject(); HeapObject* object = current->GetObject();
MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); DCHECK(ObjectMarking::IsBlack(object));
DCHECK(Marking::IsBlack(mark_bit)); ObjectMarking::BlackToWhite(object);
Marking::BlackToWhite(mark_bit);
Page::FromAddress(object->address())->ResetProgressBar(); Page::FromAddress(object->address())->ResetProgressBar();
Page::FromAddress(object->address())->ResetLiveBytes(); Page::FromAddress(object->address())->ResetLiveBytes();
current = current->next_page(); current = current->next_page();
...@@ -3086,9 +3086,8 @@ void LargeObjectSpace::FreeUnmarkedObjects() { ...@@ -3086,9 +3086,8 @@ void LargeObjectSpace::FreeUnmarkedObjects() {
LargePage* current = first_page_; LargePage* current = first_page_;
while (current != NULL) { while (current != NULL) {
HeapObject* object = current->GetObject(); HeapObject* object = current->GetObject();
MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); DCHECK(!ObjectMarking::IsGrey(object));
DCHECK(!Marking::IsGrey(mark_bit)); if (ObjectMarking::IsBlack(object)) {
if (Marking::IsBlack(mark_bit)) {
Address free_start; Address free_start;
if ((free_start = current->GetAddressToShrink()) != 0) { if ((free_start = current->GetAddressToShrink()) != 0) {
// TODO(hpayer): Perform partial free concurrently. // TODO(hpayer): Perform partial free concurrently.
...@@ -3223,7 +3222,7 @@ void Page::Print() { ...@@ -3223,7 +3222,7 @@ void Page::Print() {
unsigned mark_size = 0; unsigned mark_size = 0;
for (HeapObject* object = objects.Next(); object != NULL; for (HeapObject* object = objects.Next(); object != NULL;
object = objects.Next()) { object = objects.Next()) {
bool is_marked = Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(object)); bool is_marked = ObjectMarking::IsBlackOrGrey(object);
PrintF(" %c ", (is_marked ? '!' : ' ')); // Indent a little. PrintF(" %c ", (is_marked ? '!' : ' ')); // Indent a little.
if (is_marked) { if (is_marked) {
mark_size += object->Size(); mark_size += object->Size();
......
...@@ -2121,7 +2121,7 @@ void WeakCell::initialize(HeapObject* val) { ...@@ -2121,7 +2121,7 @@ void WeakCell::initialize(HeapObject* val) {
// We just have to execute the generational barrier here because we never // We just have to execute the generational barrier here because we never
// mark through a weak cell and collect evacuation candidates when we process // mark through a weak cell and collect evacuation candidates when we process
// all weak cells. // all weak cells.
WriteBarrierMode mode = Marking::IsBlack(ObjectMarking::MarkBitFrom(this)) WriteBarrierMode mode = ObjectMarking::IsBlack(this)
? UPDATE_WRITE_BARRIER ? UPDATE_WRITE_BARRIER
: UPDATE_WEAK_WRITE_BARRIER; : UPDATE_WEAK_WRITE_BARRIER;
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kValueOffset, val, mode); CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kValueOffset, val, mode);
......
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