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 |