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()); |