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 PageRange range(space->bottom(), end); | 136 NewSpacePageRange 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); | 178 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); |
179 } | 179 } |
180 } | 180 } |
181 } | 181 } |
182 }; | 182 }; |
183 | 183 |
184 | 184 |
185 static void VerifyEvacuation(Page* page) { | 185 static void VerifyEvacuation(Page* page) { |
186 VerifyEvacuationVisitor visitor; | 186 VerifyEvacuationVisitor visitor; |
187 HeapObjectIterator iterator(page); | 187 HeapObjectIterator iterator(page); |
188 for (HeapObject* heap_object = iterator.Next(); heap_object != nullptr; | 188 for (HeapObject* heap_object = iterator.Next(); heap_object != NULL; |
189 heap_object = iterator.Next()) { | 189 heap_object = iterator.Next()) { |
190 CHECK(!heap_object->IsFiller()); | 190 // We skip free space objects. |
191 heap_object->Iterate(&visitor); | 191 if (!heap_object->IsFiller()) { |
| 192 heap_object->Iterate(&visitor); |
| 193 } |
192 } | 194 } |
193 } | 195 } |
194 | 196 |
195 | 197 |
196 static void VerifyEvacuation(NewSpace* space) { | 198 static void VerifyEvacuation(NewSpace* space) { |
197 VerifyEvacuationVisitor visitor; | 199 VerifyEvacuationVisitor visitor; |
198 HeapObjectIterator iterator(space); | 200 NewSpacePageRange range(space->bottom(), space->top()); |
199 for (HeapObject* heap_object = iterator.Next(); heap_object != nullptr; | 201 for (auto it = range.begin(); it != range.end();) { |
200 heap_object = iterator.Next()) { | 202 Page* page = *(it++); |
201 CHECK(!heap_object->IsFiller()); | 203 Address current = page->area_start(); |
202 heap_object->Iterate(&visitor); | 204 Address limit = it != range.end() ? page->area_end() : space->top(); |
| 205 CHECK(limit == space->top() || !page->Contains(space->top())); |
| 206 while (current < limit) { |
| 207 HeapObject* object = HeapObject::FromAddress(current); |
| 208 object->Iterate(&visitor); |
| 209 current += object->Size(); |
| 210 } |
203 } | 211 } |
204 } | 212 } |
205 | 213 |
206 | 214 |
207 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { | 215 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { |
208 if (FLAG_use_allocation_folding && (space == heap->old_space())) { | 216 if (FLAG_use_allocation_folding && (space == heap->old_space())) { |
209 return; | 217 return; |
210 } | 218 } |
211 for (Page* p : *space) { | 219 for (Page* p : *space) { |
212 if (p->IsEvacuationCandidate()) continue; | 220 if (p->IsEvacuationCandidate()) continue; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 #ifdef VERIFY_HEAP | 325 #ifdef VERIFY_HEAP |
318 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { | 326 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { |
319 for (Page* p : *space) { | 327 for (Page* p : *space) { |
320 CHECK(p->markbits()->IsClean()); | 328 CHECK(p->markbits()->IsClean()); |
321 CHECK_EQ(0, p->LiveBytes()); | 329 CHECK_EQ(0, p->LiveBytes()); |
322 } | 330 } |
323 } | 331 } |
324 | 332 |
325 | 333 |
326 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { | 334 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { |
327 for (Page* p : PageRange(space->bottom(), space->top())) { | 335 for (Page* p : NewSpacePageRange(space->bottom(), space->top())) { |
328 CHECK(p->markbits()->IsClean()); | 336 CHECK(p->markbits()->IsClean()); |
329 CHECK_EQ(0, p->LiveBytes()); | 337 CHECK_EQ(0, p->LiveBytes()); |
330 } | 338 } |
331 } | 339 } |
332 | 340 |
333 | 341 |
334 void MarkCompactCollector::VerifyMarkbitsAreClean() { | 342 void MarkCompactCollector::VerifyMarkbitsAreClean() { |
335 VerifyMarkbitsAreClean(heap_->old_space()); | 343 VerifyMarkbitsAreClean(heap_->old_space()); |
336 VerifyMarkbitsAreClean(heap_->code_space()); | 344 VerifyMarkbitsAreClean(heap_->code_space()); |
337 VerifyMarkbitsAreClean(heap_->map_space()); | 345 VerifyMarkbitsAreClean(heap_->map_space()); |
(...skipping 1611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { | 1957 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { |
1950 for (Page* p : *space) { | 1958 for (Page* p : *space) { |
1951 DiscoverGreyObjectsOnPage(p); | 1959 DiscoverGreyObjectsOnPage(p); |
1952 if (marking_deque()->IsFull()) return; | 1960 if (marking_deque()->IsFull()) return; |
1953 } | 1961 } |
1954 } | 1962 } |
1955 | 1963 |
1956 | 1964 |
1957 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 1965 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { |
1958 NewSpace* space = heap()->new_space(); | 1966 NewSpace* space = heap()->new_space(); |
1959 for (Page* page : PageRange(space->bottom(), space->top())) { | 1967 for (Page* page : NewSpacePageRange(space->bottom(), space->top())) { |
1960 DiscoverGreyObjectsOnPage(page); | 1968 DiscoverGreyObjectsOnPage(page); |
1961 if (marking_deque()->IsFull()) return; | 1969 if (marking_deque()->IsFull()) return; |
1962 } | 1970 } |
1963 } | 1971 } |
1964 | 1972 |
1965 | 1973 |
1966 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { | 1974 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { |
1967 Object* o = *p; | 1975 Object* o = *p; |
1968 if (!o->IsHeapObject()) return false; | 1976 if (!o->IsHeapObject()) return false; |
1969 HeapObject* heap_object = HeapObject::cast(o); | 1977 HeapObject* heap_object = HeapObject::cast(o); |
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3016 if (map_word.IsForwardingAddress()) { | 3024 if (map_word.IsForwardingAddress()) { |
3017 return String::cast(map_word.ToForwardingAddress()); | 3025 return String::cast(map_word.ToForwardingAddress()); |
3018 } | 3026 } |
3019 | 3027 |
3020 return String::cast(*p); | 3028 return String::cast(*p); |
3021 } | 3029 } |
3022 | 3030 |
3023 void MarkCompactCollector::EvacuateNewSpacePrologue() { | 3031 void MarkCompactCollector::EvacuateNewSpacePrologue() { |
3024 NewSpace* new_space = heap()->new_space(); | 3032 NewSpace* new_space = heap()->new_space(); |
3025 // Append the list of new space pages to be processed. | 3033 // Append the list of new space pages to be processed. |
3026 for (Page* p : PageRange(new_space->bottom(), new_space->top())) { | 3034 for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { |
3027 newspace_evacuation_candidates_.Add(p); | 3035 newspace_evacuation_candidates_.Add(p); |
3028 } | 3036 } |
3029 new_space->Flip(); | 3037 new_space->Flip(); |
3030 new_space->ResetAllocationInfo(); | 3038 new_space->ResetAllocationInfo(); |
3031 } | 3039 } |
3032 | 3040 |
3033 class MarkCompactCollector::Evacuator : public Malloced { | 3041 class MarkCompactCollector::Evacuator : public Malloced { |
3034 public: | 3042 public: |
3035 enum EvacuationMode { | 3043 enum EvacuationMode { |
3036 kObjectsNewToOld, | 3044 kObjectsNewToOld, |
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3802 object->IterateBody(map->instance_type(), size, visitor); | 3810 object->IterateBody(map->instance_type(), size, visitor); |
3803 } | 3811 } |
3804 } | 3812 } |
3805 }; | 3813 }; |
3806 | 3814 |
3807 void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) { | 3815 void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) { |
3808 PageParallelJob<ToSpacePointerUpdateJobTraits> job( | 3816 PageParallelJob<ToSpacePointerUpdateJobTraits> job( |
3809 heap, heap->isolate()->cancelable_task_manager(), semaphore); | 3817 heap, heap->isolate()->cancelable_task_manager(), semaphore); |
3810 Address space_start = heap->new_space()->bottom(); | 3818 Address space_start = heap->new_space()->bottom(); |
3811 Address space_end = heap->new_space()->top(); | 3819 Address space_end = heap->new_space()->top(); |
3812 for (Page* page : PageRange(space_start, space_end)) { | 3820 for (Page* page : NewSpacePageRange(space_start, space_end)) { |
3813 Address start = | 3821 Address start = |
3814 page->Contains(space_start) ? space_start : page->area_start(); | 3822 page->Contains(space_start) ? space_start : page->area_start(); |
3815 Address end = page->Contains(space_end) ? space_end : page->area_end(); | 3823 Address end = page->Contains(space_end) ? space_end : page->area_end(); |
3816 job.AddPage(page, std::make_pair(start, end)); | 3824 job.AddPage(page, std::make_pair(start, end)); |
3817 } | 3825 } |
3818 PointersUpdatingVisitor visitor; | 3826 PointersUpdatingVisitor visitor; |
3819 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; | 3827 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; |
3820 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); | 3828 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); |
3821 } | 3829 } |
3822 | 3830 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4068 // The target is always in old space, we don't have to record the slot in | 4076 // The target is always in old space, we don't have to record the slot in |
4069 // the old-to-new remembered set. | 4077 // the old-to-new remembered set. |
4070 DCHECK(!heap()->InNewSpace(target)); | 4078 DCHECK(!heap()->InNewSpace(target)); |
4071 RecordRelocSlot(host, &rinfo, target); | 4079 RecordRelocSlot(host, &rinfo, target); |
4072 } | 4080 } |
4073 } | 4081 } |
4074 } | 4082 } |
4075 | 4083 |
4076 } // namespace internal | 4084 } // namespace internal |
4077 } // namespace v8 | 4085 } // namespace v8 |
OLD | NEW |