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