Chromium Code Reviews| Index: src/heap/mark-compact.cc |
| diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
| index 489b92aca987fd251128e262404e03baafbeaa41..62df5b78d98afb336561d4d4a79dbf6bb3273251 100644 |
| --- a/src/heap/mark-compact.cc |
| +++ b/src/heap/mark-compact.cc |
| @@ -484,9 +484,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(); |
| } |
| @@ -583,6 +581,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) { |
|
ulan
2015/03/27 08:36:55
This can clear bits outside [start, end] since we
Hannes Payer (out of office)
2015/03/30 15:09:25
I would have to expose the cell() call if we would
ulan
2015/03/30 15:17:40
OK
|
| + 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) == |
| @@ -603,14 +629,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(); |
| @@ -994,7 +1017,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(); |
| @@ -1003,6 +1026,7 @@ void CodeFlusher::ProcessJSFunctionCandidates() { |
| shared->set_code(lazy_compile); |
| candidate->set_code(lazy_compile); |
| } else { |
| + DCHECK(Marking::IsBlack(code_mark)); |
| candidate->set_code(code); |
| } |
| @@ -1036,7 +1060,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(); |
| @@ -1074,8 +1098,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++; |
| @@ -1351,7 +1375,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; |
| } |
| @@ -1402,7 +1426,7 @@ class MarkCompactMarkingVisitor |
| collector->RecordSlot(start, p, o); |
| HeapObject* obj = HeapObject::cast(o); |
| MarkBit mark = Marking::MarkBitFrom(obj); |
| - if (mark.Get()) continue; |
| + if (Marking::IsMarked(mark)) continue; |
| VisitUnmarkedObject(collector, obj); |
| } |
| return true; |
| @@ -1747,7 +1771,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::IsMarked(mark_bit)) return; |
| Map* map = object->map(); |
| // Mark the object. |
| @@ -1778,7 +1802,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)); |
| @@ -1811,7 +1835,7 @@ typedef StringTableCleaner<true> ExternalStringTableCleaner; |
| class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { |
| public: |
| virtual Object* RetainAs(Object* object) { |
| - if (Marking::MarkBitFrom(HeapObject::cast(object)).Get()) { |
| + if (Marking::IsMarked(Marking::MarkBitFrom(HeapObject::cast(object)))) { |
| return object; |
| } else if (object->IsAllocationSite() && |
| !(AllocationSite::cast(object)->IsZombie())) { |
| @@ -1885,7 +1909,6 @@ static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, |
| grey_objects >>= trailing_zeros; |
| offset += trailing_zeros; |
| MarkBit markbit(cell, 1 << offset, false); |
| - DCHECK(Marking::IsGrey(markbit)); |
| Marking::GreyToBlack(markbit); |
| Address addr = cell_base + offset * kPointerSize; |
| HeapObject* object = HeapObject::FromAddress(addr); |
| @@ -1925,14 +1948,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)) { |
| @@ -1991,7 +2015,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); |
| } |
| @@ -2001,7 +2025,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); |
| } |
| @@ -2009,7 +2033,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); |
| } |
| @@ -2202,21 +2226,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 { |
| @@ -2430,7 +2454,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); |
| @@ -2498,8 +2522,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::IsMarked(map_mark); |
| + bool parent_is_alive = Marking::IsMarked(Marking::MarkBitFrom(parent)); |
| if (!current_is_alive && parent_is_alive) { |
| ClearMapTransitions(parent, map); |
| } |
| @@ -2509,7 +2533,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::IsMarked(Marking::MarkBitFrom(target))) return false; |
| target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER); |
| return true; |
| } |
| @@ -3563,31 +3587,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; |
| @@ -3609,7 +3620,7 @@ static bool IsOnInvalidatedCodeObject(Address addr) { |
| MarkBit mark_bit = |
| p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); |
| - return mark_bit.Get(); |
| + return Marking::IsMarked(mark_bit); |
| } |