| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
| 6 | 6 |
| 7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 } | 128 } |
| 129 | 129 |
| 130 static void VerifyMarking(NewSpace* space) { | 130 static void VerifyMarking(NewSpace* space) { |
| 131 Address end = space->top(); | 131 Address end = space->top(); |
| 132 // The bottom position is at the start of its page. Allows us to use | 132 // The bottom position is at the start of its page. Allows us to use |
| 133 // page->area_start() as start of range on all pages. | 133 // page->area_start() as start of range on all pages. |
| 134 CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); | 134 CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); |
| 135 | 135 |
| 136 NewSpacePageRange range(space->bottom(), end); | 136 PageRange range(space->bottom(), end); |
| 137 for (auto it = range.begin(); it != range.end();) { | 137 for (auto it = range.begin(); it != range.end();) { |
| 138 Page* page = *(it++); | 138 Page* page = *(it++); |
| 139 Address limit = it != range.end() ? page->area_end() : end; | 139 Address limit = it != range.end() ? page->area_end() : end; |
| 140 CHECK(limit == end || !page->Contains(end)); | 140 CHECK(limit == end || !page->Contains(end)); |
| 141 VerifyMarking(space->heap(), page->area_start(), limit); | 141 VerifyMarking(space->heap(), page->area_start(), limit); |
| 142 } | 142 } |
| 143 } | 143 } |
| 144 | 144 |
| 145 | 145 |
| 146 static void VerifyMarking(PagedSpace* space) { | 146 static void VerifyMarking(PagedSpace* space) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 // We skip free space objects. | 190 // We skip free space objects. |
| 191 if (!heap_object->IsFiller()) { | 191 if (!heap_object->IsFiller()) { |
| 192 heap_object->Iterate(&visitor); | 192 heap_object->Iterate(&visitor); |
| 193 } | 193 } |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 | 196 |
| 197 | 197 |
| 198 static void VerifyEvacuation(NewSpace* space) { | 198 static void VerifyEvacuation(NewSpace* space) { |
| 199 VerifyEvacuationVisitor visitor; | 199 VerifyEvacuationVisitor visitor; |
| 200 NewSpacePageRange range(space->bottom(), space->top()); | 200 PageRange range(space->bottom(), space->top()); |
| 201 for (auto it = range.begin(); it != range.end();) { | 201 for (auto it = range.begin(); it != range.end();) { |
| 202 Page* page = *(it++); | 202 Page* page = *(it++); |
| 203 Address current = page->area_start(); | 203 Address current = page->area_start(); |
| 204 Address limit = it != range.end() ? page->area_end() : space->top(); | 204 Address limit = it != range.end() ? page->area_end() : space->top(); |
| 205 CHECK(limit == space->top() || !page->Contains(space->top())); | 205 CHECK(limit == space->top() || !page->Contains(space->top())); |
| 206 while (current < limit) { | 206 while (current < limit) { |
| 207 HeapObject* object = HeapObject::FromAddress(current); | 207 HeapObject* object = HeapObject::FromAddress(current); |
| 208 object->Iterate(&visitor); | 208 object->Iterate(&visitor); |
| 209 current += object->Size(); | 209 current += object->Size(); |
| 210 } | 210 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 #ifdef VERIFY_HEAP | 325 #ifdef VERIFY_HEAP |
| 326 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { | 326 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { |
| 327 for (Page* p : *space) { | 327 for (Page* p : *space) { |
| 328 CHECK(p->markbits()->IsClean()); | 328 CHECK(p->markbits()->IsClean()); |
| 329 CHECK_EQ(0, p->LiveBytes()); | 329 CHECK_EQ(0, p->LiveBytes()); |
| 330 } | 330 } |
| 331 } | 331 } |
| 332 | 332 |
| 333 | 333 |
| 334 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { | 334 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { |
| 335 for (Page* p : NewSpacePageRange(space->bottom(), space->top())) { | 335 for (Page* p : PageRange(space->bottom(), space->top())) { |
| 336 CHECK(p->markbits()->IsClean()); | 336 CHECK(p->markbits()->IsClean()); |
| 337 CHECK_EQ(0, p->LiveBytes()); | 337 CHECK_EQ(0, p->LiveBytes()); |
| 338 } | 338 } |
| 339 } | 339 } |
| 340 | 340 |
| 341 | 341 |
| 342 void MarkCompactCollector::VerifyMarkbitsAreClean() { | 342 void MarkCompactCollector::VerifyMarkbitsAreClean() { |
| 343 VerifyMarkbitsAreClean(heap_->old_space()); | 343 VerifyMarkbitsAreClean(heap_->old_space()); |
| 344 VerifyMarkbitsAreClean(heap_->code_space()); | 344 VerifyMarkbitsAreClean(heap_->code_space()); |
| 345 VerifyMarkbitsAreClean(heap_->map_space()); | 345 VerifyMarkbitsAreClean(heap_->map_space()); |
| (...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1969 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { | 1969 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { |
| 1970 for (Page* p : *space) { | 1970 for (Page* p : *space) { |
| 1971 DiscoverGreyObjectsOnPage(p); | 1971 DiscoverGreyObjectsOnPage(p); |
| 1972 if (marking_deque()->IsFull()) return; | 1972 if (marking_deque()->IsFull()) return; |
| 1973 } | 1973 } |
| 1974 } | 1974 } |
| 1975 | 1975 |
| 1976 | 1976 |
| 1977 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 1977 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { |
| 1978 NewSpace* space = heap()->new_space(); | 1978 NewSpace* space = heap()->new_space(); |
| 1979 for (Page* page : NewSpacePageRange(space->bottom(), space->top())) { | 1979 for (Page* page : PageRange(space->bottom(), space->top())) { |
| 1980 DiscoverGreyObjectsOnPage(page); | 1980 DiscoverGreyObjectsOnPage(page); |
| 1981 if (marking_deque()->IsFull()) return; | 1981 if (marking_deque()->IsFull()) return; |
| 1982 } | 1982 } |
| 1983 } | 1983 } |
| 1984 | 1984 |
| 1985 | 1985 |
| 1986 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { | 1986 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { |
| 1987 Object* o = *p; | 1987 Object* o = *p; |
| 1988 if (!o->IsHeapObject()) return false; | 1988 if (!o->IsHeapObject()) return false; |
| 1989 HeapObject* heap_object = HeapObject::cast(o); | 1989 HeapObject* heap_object = HeapObject::cast(o); |
| (...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3036 if (map_word.IsForwardingAddress()) { | 3036 if (map_word.IsForwardingAddress()) { |
| 3037 return String::cast(map_word.ToForwardingAddress()); | 3037 return String::cast(map_word.ToForwardingAddress()); |
| 3038 } | 3038 } |
| 3039 | 3039 |
| 3040 return String::cast(*p); | 3040 return String::cast(*p); |
| 3041 } | 3041 } |
| 3042 | 3042 |
| 3043 void MarkCompactCollector::EvacuateNewSpacePrologue() { | 3043 void MarkCompactCollector::EvacuateNewSpacePrologue() { |
| 3044 NewSpace* new_space = heap()->new_space(); | 3044 NewSpace* new_space = heap()->new_space(); |
| 3045 // Append the list of new space pages to be processed. | 3045 // Append the list of new space pages to be processed. |
| 3046 for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { | 3046 for (Page* p : PageRange(new_space->bottom(), new_space->top())) { |
| 3047 newspace_evacuation_candidates_.Add(p); | 3047 newspace_evacuation_candidates_.Add(p); |
| 3048 } | 3048 } |
| 3049 new_space->Flip(); | 3049 new_space->Flip(); |
| 3050 new_space->ResetAllocationInfo(); | 3050 new_space->ResetAllocationInfo(); |
| 3051 } | 3051 } |
| 3052 | 3052 |
| 3053 class MarkCompactCollector::Evacuator : public Malloced { | 3053 class MarkCompactCollector::Evacuator : public Malloced { |
| 3054 public: | 3054 public: |
| 3055 enum EvacuationMode { | 3055 enum EvacuationMode { |
| 3056 kObjectsNewToOld, | 3056 kObjectsNewToOld, |
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3822 object->IterateBody(map->instance_type(), size, visitor); | 3822 object->IterateBody(map->instance_type(), size, visitor); |
| 3823 } | 3823 } |
| 3824 } | 3824 } |
| 3825 }; | 3825 }; |
| 3826 | 3826 |
| 3827 void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) { | 3827 void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) { |
| 3828 PageParallelJob<ToSpacePointerUpdateJobTraits> job( | 3828 PageParallelJob<ToSpacePointerUpdateJobTraits> job( |
| 3829 heap, heap->isolate()->cancelable_task_manager(), semaphore); | 3829 heap, heap->isolate()->cancelable_task_manager(), semaphore); |
| 3830 Address space_start = heap->new_space()->bottom(); | 3830 Address space_start = heap->new_space()->bottom(); |
| 3831 Address space_end = heap->new_space()->top(); | 3831 Address space_end = heap->new_space()->top(); |
| 3832 for (Page* page : NewSpacePageRange(space_start, space_end)) { | 3832 for (Page* page : PageRange(space_start, space_end)) { |
| 3833 Address start = | 3833 Address start = |
| 3834 page->Contains(space_start) ? space_start : page->area_start(); | 3834 page->Contains(space_start) ? space_start : page->area_start(); |
| 3835 Address end = page->Contains(space_end) ? space_end : page->area_end(); | 3835 Address end = page->Contains(space_end) ? space_end : page->area_end(); |
| 3836 job.AddPage(page, std::make_pair(start, end)); | 3836 job.AddPage(page, std::make_pair(start, end)); |
| 3837 } | 3837 } |
| 3838 PointersUpdatingVisitor visitor; | 3838 PointersUpdatingVisitor visitor; |
| 3839 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; | 3839 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; |
| 3840 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); | 3840 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); |
| 3841 } | 3841 } |
| 3842 | 3842 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4088 // The target is always in old space, we don't have to record the slot in | 4088 // The target is always in old space, we don't have to record the slot in |
| 4089 // the old-to-new remembered set. | 4089 // the old-to-new remembered set. |
| 4090 DCHECK(!heap()->InNewSpace(target)); | 4090 DCHECK(!heap()->InNewSpace(target)); |
| 4091 RecordRelocSlot(host, &rinfo, target); | 4091 RecordRelocSlot(host, &rinfo, target); |
| 4092 } | 4092 } |
| 4093 } | 4093 } |
| 4094 } | 4094 } |
| 4095 | 4095 |
| 4096 } // namespace internal | 4096 } // namespace internal |
| 4097 } // namespace v8 | 4097 } // namespace v8 |
| OLD | NEW |