Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index 931206ff43538020c457e9b98d18484e5ac69db2..1bbe0e11cc67a7fa923aae0509be776abaf48875 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -474,9 +474,7 @@ void MarkCompactCollector::ClearMarkbits() { |
LargeObjectIterator it(heap_->lo_space()); |
for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
- MarkBit mark_bit = Marking::MarkBitFrom(obj); |
- mark_bit.Clear(); |
- mark_bit.Next().Clear(); |
+ Marking::MarkWhite(Marking::MarkBitFrom(obj)); |
Page::FromAddress(obj->address())->ResetProgressBar(); |
Page::FromAddress(obj->address())->ResetLiveBytes(); |
} |
@@ -563,6 +561,34 @@ void MarkCompactCollector::RefillFreeList(PagedSpace* space) { |
} |
+void Marking::SetAllMarkBitsInRange(MarkBit start, MarkBit end) { |
+ MarkBit::CellType* start_cell = start.cell(); |
+ MarkBit::CellType* end_cell = end.cell(); |
+ MarkBit::CellType start_mask = ~(start.mask() - 1); |
+ MarkBit::CellType end_mask = (end.mask() << 1) - 1; |
+ |
+ if (start_cell == end_cell) { |
+ *start_cell |= start_mask & end_mask; |
+ } else { |
+ *start_cell |= start_mask; |
+ for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) { |
+ *cell = ~0; |
+ } |
+ *end_cell |= end_mask; |
+ } |
+} |
+ |
+ |
+void Marking::ClearAllMarkBitsOfCellsContainedInRange(MarkBit start, |
+ MarkBit end) { |
+ MarkBit::CellType* start_cell = start.cell(); |
+ MarkBit::CellType* end_cell = end.cell(); |
+ for (MarkBit::CellType* cell = start_cell; cell <= end_cell; cell++) { |
+ *cell = 0; |
+ } |
+} |
+ |
+ |
void Marking::TransferMark(Address old_start, Address new_start) { |
// This is only used when resizing an object. |
DCHECK(MemoryChunk::FromAddress(old_start) == |
@@ -583,14 +609,11 @@ void Marking::TransferMark(Address old_start, Address new_start) { |
#endif |
if (Marking::IsBlack(old_mark_bit)) { |
- old_mark_bit.Clear(); |
- DCHECK(IsWhite(old_mark_bit)); |
+ Marking::BlackToWhite(old_mark_bit); |
Marking::MarkBlack(new_mark_bit); |
return; |
} else if (Marking::IsGrey(old_mark_bit)) { |
- old_mark_bit.Clear(); |
- old_mark_bit.Next().Clear(); |
- DCHECK(IsWhite(old_mark_bit)); |
+ Marking::GreyToWhite(old_mark_bit); |
heap_->incremental_marking()->WhiteToGreyAndPush( |
HeapObject::FromAddress(new_start), new_mark_bit); |
heap_->incremental_marking()->RestartIfNotMarking(); |
@@ -970,7 +993,7 @@ void CodeFlusher::ProcessJSFunctionCandidates() { |
Code* code = shared->code(); |
MarkBit code_mark = Marking::MarkBitFrom(code); |
- if (!code_mark.Get()) { |
+ if (Marking::IsWhite(code_mark)) { |
if (FLAG_trace_code_flushing && shared->is_compiled()) { |
PrintF("[code-flushing clears: "); |
shared->ShortPrint(); |
@@ -979,6 +1002,7 @@ void CodeFlusher::ProcessJSFunctionCandidates() { |
shared->set_code(lazy_compile); |
candidate->set_code(lazy_compile); |
} else { |
+ DCHECK(Marking::IsBlack(code_mark)); |
candidate->set_code(code); |
} |
@@ -1012,7 +1036,7 @@ void CodeFlusher::ProcessSharedFunctionInfoCandidates() { |
Code* code = candidate->code(); |
MarkBit code_mark = Marking::MarkBitFrom(code); |
- if (!code_mark.Get()) { |
+ if (Marking::IsWhite(code_mark)) { |
if (FLAG_trace_code_flushing && candidate->is_compiled()) { |
PrintF("[code-flushing clears: "); |
candidate->ShortPrint(); |
@@ -1050,8 +1074,8 @@ void CodeFlusher::ProcessOptimizedCodeMaps() { |
i += SharedFunctionInfo::kEntryLength) { |
Code* code = |
Code::cast(code_map->get(i + SharedFunctionInfo::kCachedCodeOffset)); |
- if (!Marking::MarkBitFrom(code).Get()) continue; |
- |
+ if (Marking::IsWhite(Marking::MarkBitFrom(code))) continue; |
+ DCHECK(Marking::IsBlack(Marking::MarkBitFrom(code))); |
// Move every slot in the entry. |
for (int j = 0; j < SharedFunctionInfo::kEntryLength; j++) { |
int dst_index = new_length++; |
@@ -1327,7 +1351,7 @@ class MarkCompactMarkingVisitor |
// Returns true if object needed marking and false otherwise. |
INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) { |
MarkBit mark_bit = Marking::MarkBitFrom(object); |
- if (!mark_bit.Get()) { |
+ if (Marking::IsWhite(mark_bit)) { |
heap->mark_compact_collector()->SetMark(object, mark_bit); |
return true; |
} |
@@ -1378,7 +1402,7 @@ class MarkCompactMarkingVisitor |
collector->RecordSlot(start, p, o); |
HeapObject* obj = HeapObject::cast(o); |
MarkBit mark = Marking::MarkBitFrom(obj); |
- if (mark.Get()) continue; |
+ if (Marking::IsBlackOrGrey(mark)) continue; |
VisitUnmarkedObject(collector, obj); |
} |
return true; |
@@ -1723,7 +1747,7 @@ class RootMarkingVisitor : public ObjectVisitor { |
// Replace flat cons strings in place. |
HeapObject* object = ShortCircuitConsString(p); |
MarkBit mark_bit = Marking::MarkBitFrom(object); |
- if (mark_bit.Get()) return; |
+ if (Marking::IsBlackOrGrey(mark_bit)) return; |
Map* map = object->map(); |
// Mark the object. |
@@ -1754,7 +1778,7 @@ class StringTableCleaner : public ObjectVisitor { |
for (Object** p = start; p < end; p++) { |
Object* o = *p; |
if (o->IsHeapObject() && |
- !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) { |
+ Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(o)))) { |
if (finalize_external_strings) { |
DCHECK(o->IsExternalString()); |
heap_->FinalizeExternalString(String::cast(*p)); |
@@ -1787,7 +1811,8 @@ typedef StringTableCleaner<true> ExternalStringTableCleaner; |
class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { |
public: |
virtual Object* RetainAs(Object* object) { |
- if (Marking::MarkBitFrom(HeapObject::cast(object)).Get()) { |
+ if (Marking::IsBlackOrGrey( |
+ Marking::MarkBitFrom(HeapObject::cast(object)))) { |
return object; |
} else if (object->IsAllocationSite() && |
!(AllocationSite::cast(object)->IsZombie())) { |
@@ -1901,14 +1926,15 @@ int MarkCompactCollector::DiscoverAndEvacuateBlackObjectsOnPage( |
offset += trailing_zeros; |
Address address = cell_base + offset * kPointerSize; |
HeapObject* object = HeapObject::FromAddress(address); |
+ DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
int size = object->Size(); |
survivors_size += size; |
Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT); |
- offset++; |
- current_cell >>= 1; |
+ offset += 2; |
+ current_cell >>= 2; |
// TODO(hpayer): Refactor EvacuateObject and call this function instead. |
if (heap()->ShouldBePromoted(object->address(), size) && |
@@ -1966,7 +1992,7 @@ bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { |
if (!o->IsHeapObject()) return false; |
HeapObject* heap_object = HeapObject::cast(o); |
MarkBit mark = Marking::MarkBitFrom(heap_object); |
- return !mark.Get(); |
+ return Marking::IsWhite(mark); |
} |
@@ -1976,7 +2002,7 @@ bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap, |
DCHECK(o->IsHeapObject()); |
HeapObject* heap_object = HeapObject::cast(o); |
MarkBit mark = Marking::MarkBitFrom(heap_object); |
- return !mark.Get(); |
+ return Marking::IsWhite(mark); |
} |
@@ -1984,7 +2010,7 @@ void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) { |
StringTable* string_table = heap()->string_table(); |
// Mark the string table itself. |
MarkBit string_table_mark = Marking::MarkBitFrom(string_table); |
- if (!string_table_mark.Get()) { |
+ if (Marking::IsWhite(string_table_mark)) { |
// String table could have already been marked by visiting the handles list. |
SetMark(string_table, string_table_mark); |
} |
@@ -2174,21 +2200,21 @@ void MarkCompactCollector::RetainMaps() { |
int new_age; |
Map* map = Map::cast(cell->value()); |
MarkBit map_mark = Marking::MarkBitFrom(map); |
- if (!map_mark.Get()) { |
+ if (Marking::IsWhite(map_mark)) { |
if (age == 0) { |
// The map has aged. Do not retain this map. |
continue; |
} |
Object* constructor = map->GetConstructor(); |
- if (!constructor->IsHeapObject() || |
- !Marking::MarkBitFrom(HeapObject::cast(constructor)).Get()) { |
+ if (!constructor->IsHeapObject() || Marking::IsWhite(Marking::MarkBitFrom( |
+ HeapObject::cast(constructor)))) { |
// The constructor is dead, no new objects with this map can |
// be created. Do not retain this map. |
continue; |
} |
Object* prototype = map->prototype(); |
if (prototype->IsHeapObject() && |
- !Marking::MarkBitFrom(HeapObject::cast(prototype)).Get()) { |
+ Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(prototype)))) { |
// The prototype is not marked, age the map. |
new_age = age - 1; |
} else { |
@@ -2402,7 +2428,7 @@ void MarkCompactCollector::ClearNonLiveReferences() { |
ClearNonLivePrototypeTransitions(map); |
ClearNonLiveMapTransitions(map, map_mark); |
- if (!map_mark.Get()) { |
+ if (Marking::IsWhite(map_mark)) { |
have_code_to_deoptimize_ |= |
map->dependent_code()->MarkCodeForDeoptimization( |
isolate(), DependentCode::kWeakCodeGroup); |
@@ -2470,8 +2496,8 @@ void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map, |
// Follow back pointer, check whether we are dealing with a map transition |
// from a live map to a dead path and in case clear transitions of parent. |
- bool current_is_alive = map_mark.Get(); |
- bool parent_is_alive = Marking::MarkBitFrom(parent).Get(); |
+ bool current_is_alive = Marking::IsBlackOrGrey(map_mark); |
+ bool parent_is_alive = Marking::IsBlackOrGrey(Marking::MarkBitFrom(parent)); |
if (!current_is_alive && parent_is_alive) { |
ClearMapTransitions(parent, map); |
} |
@@ -2481,7 +2507,7 @@ void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map, |
// Clear a possible back pointer in case the transition leads to a dead map. |
// Return true in case a back pointer has been cleared and false otherwise. |
bool MarkCompactCollector::ClearMapBackPointer(Map* target) { |
- if (Marking::MarkBitFrom(target).Get()) return false; |
+ if (Marking::IsBlackOrGrey(Marking::MarkBitFrom(target))) return false; |
target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER); |
return true; |
} |
@@ -3550,31 +3576,18 @@ static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { |
uint32_t end_index = |
MemoryChunk::FastAddressToMarkbitIndex(code_end - kPointerSize); |
+ // TODO(hpayer): Filter out invalidated code in |
+ // ClearInvalidSlotsBufferEntries. |
Bitmap* b = p->markbits(); |
MarkBit start_mark_bit = b->MarkBitFromIndex(start_index); |
MarkBit end_mark_bit = b->MarkBitFromIndex(end_index); |
- MarkBit::CellType* start_cell = start_mark_bit.cell(); |
- MarkBit::CellType* end_cell = end_mark_bit.cell(); |
- |
if (value) { |
- MarkBit::CellType start_mask = ~(start_mark_bit.mask() - 1); |
- MarkBit::CellType end_mask = (end_mark_bit.mask() << 1) - 1; |
- |
- if (start_cell == end_cell) { |
- *start_cell |= start_mask & end_mask; |
- } else { |
- *start_cell |= start_mask; |
- for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) { |
- *cell = ~0; |
- } |
- *end_cell |= end_mask; |
- } |
+ Marking::SetAllMarkBitsInRange(start_mark_bit, end_mark_bit); |
} else { |
- for (MarkBit::CellType* cell = start_cell; cell <= end_cell; cell++) { |
- *cell = 0; |
- } |
+ Marking::ClearAllMarkBitsOfCellsContainedInRange(start_mark_bit, |
+ end_mark_bit); |
} |
return true; |
@@ -3595,7 +3608,7 @@ static bool IsOnInvalidatedCodeObject(Address addr) { |
MarkBit mark_bit = |
p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); |
- return mark_bit.Get(); |
+ return Marking::IsBlackOrGrey(mark_bit); |
} |