Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(962)

Side by Side Diff: src/heap/mark-compact.cc

Issue 2790373002: [heap] Refactor evacuation verifier (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 25 matching lines...) Expand all
36 36
37 const char* Marking::kWhiteBitPattern = "00"; 37 const char* Marking::kWhiteBitPattern = "00";
38 const char* Marking::kBlackBitPattern = "11"; 38 const char* Marking::kBlackBitPattern = "11";
39 const char* Marking::kGreyBitPattern = "10"; 39 const char* Marking::kGreyBitPattern = "10";
40 const char* Marking::kImpossibleBitPattern = "01"; 40 const char* Marking::kImpossibleBitPattern = "01";
41 41
42 // The following has to hold in order for {ObjectMarking::MarkBitFrom} to not 42 // The following has to hold in order for {ObjectMarking::MarkBitFrom} to not
43 // produce invalid {kImpossibleBitPattern} in the marking bitmap by overlapping. 43 // produce invalid {kImpossibleBitPattern} in the marking bitmap by overlapping.
44 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2); 44 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2);
45 45
46 46 // =============================================================================
47 // ------------------------------------------------------------------------- 47 // Verifiers
48 // MarkCompactCollector 48 // =============================================================================
49
50 MarkCompactCollector::MarkCompactCollector(Heap* heap)
51 : // NOLINT
52 heap_(heap),
53 page_parallel_job_semaphore_(0),
54 #ifdef DEBUG
55 state_(IDLE),
56 #endif
57 was_marked_incrementally_(false),
58 evacuation_(false),
59 compacting_(false),
60 black_allocation_(false),
61 have_code_to_deoptimize_(false),
62 marking_deque_(heap),
63 code_flusher_(nullptr),
64 sweeper_(heap) {
65 }
66 49
67 #ifdef VERIFY_HEAP 50 #ifdef VERIFY_HEAP
51 namespace {
52
68 class MarkingVerifier : public ObjectVisitor { 53 class MarkingVerifier : public ObjectVisitor {
69 public: 54 public:
70 virtual void Run() = 0; 55 virtual void Run() = 0;
71 56
72 protected: 57 protected:
73 explicit MarkingVerifier(Heap* heap) : heap_(heap) {} 58 explicit MarkingVerifier(Heap* heap) : heap_(heap) {}
74 59
75 virtual MarkingState marking_state(MemoryChunk* chunk) = 0; 60 virtual MarkingState marking_state(MemoryChunk* chunk) = 0;
76 61
77 void VerifyRoots(VisitMode mode); 62 void VerifyRoots(VisitMode mode);
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 for (Object** current = start; current < end; current++) { 198 for (Object** current = start; current < end; current++) {
214 if ((*current)->IsHeapObject()) { 199 if ((*current)->IsHeapObject()) {
215 HeapObject* object = HeapObject::cast(*current); 200 HeapObject* object = HeapObject::cast(*current);
216 if (!heap_->InNewSpace(object)) return; 201 if (!heap_->InNewSpace(object)) return;
217 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); 202 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object)));
218 } 203 }
219 } 204 }
220 } 205 }
221 }; 206 };
222 207
223 class VerifyEvacuationVisitor : public ObjectVisitor { 208 class EvacuationVerifier : public ObjectVisitor {
224 public: 209 public:
210 virtual void Run() = 0;
211
225 void VisitPointers(Object** start, Object** end) override { 212 void VisitPointers(Object** start, Object** end) override {
226 for (Object** current = start; current < end; current++) { 213 for (Object** current = start; current < end; current++) {
227 if ((*current)->IsHeapObject()) { 214 if ((*current)->IsHeapObject()) {
228 HeapObject* object = HeapObject::cast(*current); 215 HeapObject* object = HeapObject::cast(*current);
229 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); 216 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object));
230 } 217 }
231 } 218 }
232 } 219 }
220
221 protected:
222 explicit EvacuationVerifier(Heap* heap) : heap_(heap) {}
223
224 void VerifyRoots(VisitMode mode);
225 void VerifyEvacuationOnPage(Address start, Address end);
226 void VerifyEvacuation(NewSpace* new_space);
227 void VerifyEvacuation(PagedSpace* paged_space);
228
229 Heap* heap_;
233 }; 230 };
234 231
232 void EvacuationVerifier::VerifyRoots(VisitMode mode) {
233 heap_->IterateStrongRoots(this, mode);
234 }
235 235
236 static void VerifyEvacuation(Page* page) { 236 void EvacuationVerifier::VerifyEvacuationOnPage(Address start, Address end) {
237 VerifyEvacuationVisitor visitor; 237 Address current = start;
238 HeapObjectIterator iterator(page); 238 while (current < end) {
239 for (HeapObject* heap_object = iterator.Next(); heap_object != NULL; 239 HeapObject* object = HeapObject::FromAddress(current);
240 heap_object = iterator.Next()) { 240 if (!object->IsFiller()) object->Iterate(this);
241 // We skip free space objects. 241 current += object->Size();
242 if (!heap_object->IsFiller()) {
243 heap_object->Iterate(&visitor);
244 }
245 } 242 }
246 } 243 }
247 244
248 245 void EvacuationVerifier::VerifyEvacuation(NewSpace* space) {
249 static void VerifyEvacuation(NewSpace* space) {
250 VerifyEvacuationVisitor visitor;
251 PageRange range(space->bottom(), space->top()); 246 PageRange range(space->bottom(), space->top());
252 for (auto it = range.begin(); it != range.end();) { 247 for (auto it = range.begin(); it != range.end();) {
253 Page* page = *(it++); 248 Page* page = *(it++);
254 Address current = page->area_start(); 249 Address current = page->area_start();
255 Address limit = it != range.end() ? page->area_end() : space->top(); 250 Address limit = it != range.end() ? page->area_end() : space->top();
256 CHECK(limit == space->top() || !page->Contains(space->top())); 251 CHECK(limit == space->top() || !page->Contains(space->top()));
257 while (current < limit) { 252 VerifyEvacuationOnPage(current, limit);
258 HeapObject* object = HeapObject::FromAddress(current);
259 object->Iterate(&visitor);
260 current += object->Size();
261 }
262 } 253 }
263 } 254 }
264 255
265 256 void EvacuationVerifier::VerifyEvacuation(PagedSpace* space) {
266 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { 257 if (FLAG_use_allocation_folding && (space == heap_->old_space())) {
Michael Lippautz 2017/04/04 11:21:42 I just copied this part but with the current imple
267 if (FLAG_use_allocation_folding && (space == heap->old_space())) {
268 return; 258 return;
269 } 259 }
270 for (Page* p : *space) { 260 for (Page* p : *space) {
271 if (p->IsEvacuationCandidate()) continue; 261 if (p->IsEvacuationCandidate()) continue;
272 VerifyEvacuation(p); 262 VerifyEvacuationOnPage(p->area_start(), p->area_end());
273 } 263 }
274 } 264 }
275 265
266 class FullEvacuationVerifier : public EvacuationVerifier {
267 public:
268 explicit FullEvacuationVerifier(Heap* heap) : EvacuationVerifier(heap) {}
276 269
277 static void VerifyEvacuation(Heap* heap) { 270 void Run() override {
278 VerifyEvacuation(heap, heap->old_space()); 271 VerifyRoots(VISIT_ALL);
279 VerifyEvacuation(heap, heap->code_space()); 272 VerifyEvacuation(heap_->new_space());
280 VerifyEvacuation(heap, heap->map_space()); 273 VerifyEvacuation(heap_->old_space());
281 VerifyEvacuation(heap->new_space()); 274 VerifyEvacuation(heap_->code_space());
275 VerifyEvacuation(heap_->map_space());
276 }
277 };
282 278
283 VerifyEvacuationVisitor visitor; 279 } // namespace
284 heap->IterateStrongRoots(&visitor, VISIT_ALL);
285 }
286 #endif // VERIFY_HEAP 280 #endif // VERIFY_HEAP
287 281
282 // =============================================================================
283 // MarkCompactCollector
284 // =============================================================================
285
286 MarkCompactCollector::MarkCompactCollector(Heap* heap)
287 : // NOLINT
288 heap_(heap),
289 page_parallel_job_semaphore_(0),
290 #ifdef DEBUG
291 state_(IDLE),
292 #endif
293 was_marked_incrementally_(false),
294 evacuation_(false),
295 compacting_(false),
296 black_allocation_(false),
297 have_code_to_deoptimize_(false),
298 marking_deque_(heap),
299 code_flusher_(nullptr),
300 sweeper_(heap) {
301 }
288 302
289 void MarkCompactCollector::SetUp() { 303 void MarkCompactCollector::SetUp() {
290 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 304 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
291 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 305 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0);
292 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); 306 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0);
293 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 307 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
294 marking_deque()->SetUp(); 308 marking_deque()->SetUp();
295 309
296 if (FLAG_flush_code) { 310 if (FLAG_flush_code) {
297 code_flusher_ = new CodeFlusher(isolate()); 311 code_flusher_ = new CodeFlusher(isolate());
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 void MarkCompactCollector::EnsureSweepingCompleted() { 593 void MarkCompactCollector::EnsureSweepingCompleted() {
580 if (!sweeper().sweeping_in_progress()) return; 594 if (!sweeper().sweeping_in_progress()) return;
581 595
582 sweeper().EnsureCompleted(); 596 sweeper().EnsureCompleted();
583 heap()->old_space()->RefillFreeList(); 597 heap()->old_space()->RefillFreeList();
584 heap()->code_space()->RefillFreeList(); 598 heap()->code_space()->RefillFreeList();
585 heap()->map_space()->RefillFreeList(); 599 heap()->map_space()->RefillFreeList();
586 600
587 #ifdef VERIFY_HEAP 601 #ifdef VERIFY_HEAP
588 if (FLAG_verify_heap && !evacuation()) { 602 if (FLAG_verify_heap && !evacuation()) {
589 VerifyEvacuation(heap_); 603 FullEvacuationVerifier verifier(heap_);
604 verifier.Run();
590 } 605 }
591 #endif 606 #endif
592 607
593 if (heap()->memory_allocator()->unmapper()->has_delayed_chunks()) 608 if (heap()->memory_allocator()->unmapper()->has_delayed_chunks())
594 heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); 609 heap()->memory_allocator()->unmapper()->FreeQueuedChunks();
595 } 610 }
596 611
597 bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() { 612 bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() {
598 return num_sweeping_tasks_.Value() != 0; 613 return num_sweeping_tasks_.Value() != 0;
599 } 614 }
(...skipping 3104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3704 } 3719 }
3705 } 3720 }
3706 3721
3707 { 3722 {
3708 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_EPILOGUE); 3723 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_EPILOGUE);
3709 EvacuateEpilogue(); 3724 EvacuateEpilogue();
3710 } 3725 }
3711 3726
3712 #ifdef VERIFY_HEAP 3727 #ifdef VERIFY_HEAP
3713 if (FLAG_verify_heap && !sweeper().sweeping_in_progress()) { 3728 if (FLAG_verify_heap && !sweeper().sweeping_in_progress()) {
3714 VerifyEvacuation(heap()); 3729 FullEvacuationVerifier verifier(heap());
3730 verifier.Run();
3715 } 3731 }
3716 #endif 3732 #endif
3717 } 3733 }
3718 3734
3719 template <RememberedSetType type> 3735 template <RememberedSetType type>
3720 class PointerUpdateJobTraits { 3736 class PointerUpdateJobTraits {
3721 public: 3737 public:
3722 typedef int PerPageData; // Per page data is not used in this job. 3738 typedef int PerPageData; // Per page data is not used in this job.
3723 typedef int PerTaskData; // Per task data is not used in this job. 3739 typedef int PerTaskData; // Per task data is not used in this job.
3724 3740
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
4152 // The target is always in old space, we don't have to record the slot in 4168 // The target is always in old space, we don't have to record the slot in
4153 // the old-to-new remembered set. 4169 // the old-to-new remembered set.
4154 DCHECK(!heap()->InNewSpace(target)); 4170 DCHECK(!heap()->InNewSpace(target));
4155 RecordRelocSlot(host, &rinfo, target); 4171 RecordRelocSlot(host, &rinfo, target);
4156 } 4172 }
4157 } 4173 }
4158 } 4174 }
4159 4175
4160 } // namespace internal 4176 } // namespace internal
4161 } // namespace v8 4177 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698