Chromium Code Reviews| Index: src/mark-compact.cc |
| =================================================================== |
| --- src/mark-compact.cc (revision 12562) |
| +++ src/mark-compact.cc (working copy) |
| @@ -1066,6 +1066,30 @@ |
| } |
| } |
| + static void VisitHugeFixedArray(Heap* heap, FixedArray* array, int length); |
| + |
| + // The deque is contiguous and we use new space, it is therefore contained in |
| + // one page minus the header. It also has a size that is a power of two so |
| + // it is half the size of a page. We want to scan a number of array entries |
| + // that is less than the number of entries in the deque, so we divide by 2 |
| + // once more. |
| + static const int kScanningChunk = Page::kPageSize / 4 / kPointerSize; |
| + |
| + INLINE(static void VisitFixedArray(Map* map, HeapObject* object)) { |
| + FixedArray* array = FixedArray::cast(object); |
| + int length = array->length(); |
| + Heap* heap = map->GetHeap(); |
| + |
| + if (length < kScanningChunk || |
| + MemoryChunk::FromAddress(array->address())->owner()->identity() != |
| + LO_SPACE) { |
| + Object** start = array->data_start(); |
| + VisitPointers(heap, start, start + length); |
| + } else { |
| + VisitHugeFixedArray(heap, array, length); |
| + } |
| + } |
| + |
| // Marks the object black and pushes it on the marking stack. |
| INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { |
| MarkBit mark = Marking::MarkBitFrom(object); |
| @@ -1504,6 +1528,27 @@ |
| }; |
| +void MarkCompactMarkingVisitor::VisitHugeFixedArray(Heap* heap, |
| + FixedArray* array, |
| + int length) { |
| + MemoryChunk* chunk = MemoryChunk::FromAddress(array->address()); |
| + |
| + ASSERT(chunk->owner()->identity() == LO_SPACE); |
| + |
| + Object** start = array->data_start(); |
| + int from = |
| + chunk->IsPartiallyScanned() ? chunk->PartiallyScannedProgress() : 0; |
| + int to = Min(from + kScanningChunk, length); |
| + VisitPointers(heap, start + from, start + to); |
| + |
| + if (to == length) { |
| + chunk->SetCompletelyScanned(); |
| + } else { |
| + chunk->SetPartiallyScannedProgress(to); |
| + } |
| +} |
| + |
| + |
| void MarkCompactMarkingVisitor::ObjectStatsCountFixedArray( |
| FixedArrayBase* fixed_array, |
| FixedArraySubInstanceType fast_type, |
| @@ -1645,6 +1690,9 @@ |
| table_.Register(kVisitJSRegExp, |
| &VisitRegExpAndFlushCode); |
| + table_.Register(kVisitFixedArray, |
| + &VisitFixedArray); |
| + |
| if (FLAG_track_gc_object_stats) { |
| // Copy the visitor table to make call-through possible. |
| non_count_table_.CopyFrom(&table_); |
| @@ -2116,18 +2164,21 @@ |
| // marking stack have been marked, or are overflowed in the heap. |
| void MarkCompactCollector::EmptyMarkingDeque() { |
| while (!marking_deque_.IsEmpty()) { |
| - while (!marking_deque_.IsEmpty()) { |
| - HeapObject* object = marking_deque_.Pop(); |
| - ASSERT(object->IsHeapObject()); |
| - ASSERT(heap()->Contains(object)); |
| - ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); |
| + do { |
| + while (!marking_deque_.IsEmpty()) { |
| + HeapObject* object = marking_deque_.Pop(); |
| + ASSERT(object->IsHeapObject()); |
| + ASSERT(heap()->Contains(object)); |
| + ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); |
| - Map* map = object->map(); |
| - MarkBit map_mark = Marking::MarkBitFrom(map); |
| - MarkObject(map, map_mark); |
| + Map* map = object->map(); |
| + MarkBit map_mark = Marking::MarkBitFrom(map); |
| + MarkObject(map, map_mark); |
| - MarkCompactMarkingVisitor::IterateBody(map, object); |
| - } |
| + MarkCompactMarkingVisitor::IterateBody(map, object); |
| + } |
| + FillMarkingDequeFromLargePostponedArrays(); |
| + } while (!marking_deque_.IsEmpty()); |
|
Michael Starzinger
2012/09/20 13:29:48
Instead of adding yet another loop we could just r
|
| // Process encountered weak maps, mark objects only reachable by those |
| // weak maps and repeat until fix-point is reached. |
| @@ -2136,12 +2187,28 @@ |
| } |
| +void MarkCompactCollector::FillMarkingDequeFromLargePostponedArrays() { |
|
Michael Starzinger
2012/09/20 13:29:48
How about naming this "ProcessLargePostponedArrays
|
| + ASSERT(marking_deque_.IsEmpty()); |
| + LargeObjectIterator it(heap_->lo_space()); |
| + for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| + if (!obj->IsFixedArray()) continue; |
| + MemoryChunk* p = MemoryChunk::FromAddress(obj->address()); |
| + if (p->IsPartiallyScanned()) { |
| + marking_deque_.PushBlack(obj); |
| + } |
| + } |
| +} |
| + |
| + |
| // Sweep the heap for overflowed objects, clear their overflow bits, and |
| // push them on the marking stack. Stop early if the marking stack fills |
| // before sweeping completes. If sweeping completes, there are no remaining |
| // overflowed objects in the heap so the overflow flag on the markings stack |
| // is cleared. |
| void MarkCompactCollector::RefillMarkingDeque() { |
| + if (FLAG_trace_gc) { |
| + PrintPID("Marking queue overflowed\n"); |
| + } |
| ASSERT(marking_deque_.overflowed()); |
| SemiSpaceIterator new_it(heap()->new_space()); |