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

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

Issue 2793323002: Reland of [heap] Refactor evacuation verifier (Closed)
Patch Set: Fix 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())) {
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 if (p->Contains(space->top()))
Michael Lippautz 2017/04/04 14:50:27 Previously we used the HeapObjectIterator for this
263 heap_->CreateFillerObjectAt(space->top(), space->limit() - space->top(),
264 ClearRecordedSlots::kNo);
265
266 VerifyEvacuationOnPage(p->area_start(), p->area_end());
273 } 267 }
274 } 268 }
275 269
270 class FullEvacuationVerifier : public EvacuationVerifier {
271 public:
272 explicit FullEvacuationVerifier(Heap* heap) : EvacuationVerifier(heap) {}
276 273
277 static void VerifyEvacuation(Heap* heap) { 274 void Run() override {
278 VerifyEvacuation(heap, heap->old_space()); 275 VerifyRoots(VISIT_ALL);
279 VerifyEvacuation(heap, heap->code_space()); 276 VerifyEvacuation(heap_->new_space());
280 VerifyEvacuation(heap, heap->map_space()); 277 VerifyEvacuation(heap_->old_space());
281 VerifyEvacuation(heap->new_space()); 278 VerifyEvacuation(heap_->code_space());
279 VerifyEvacuation(heap_->map_space());
280 }
281 };
282 282
283 VerifyEvacuationVisitor visitor; 283 } // namespace
284 heap->IterateStrongRoots(&visitor, VISIT_ALL);
285 }
286 #endif // VERIFY_HEAP 284 #endif // VERIFY_HEAP
287 285
286 // =============================================================================
287 // MarkCompactCollector
288 // =============================================================================
289
290 MarkCompactCollector::MarkCompactCollector(Heap* heap)
291 : // NOLINT
292 heap_(heap),
293 page_parallel_job_semaphore_(0),
294 #ifdef DEBUG
295 state_(IDLE),
296 #endif
297 was_marked_incrementally_(false),
298 evacuation_(false),
299 compacting_(false),
300 black_allocation_(false),
301 have_code_to_deoptimize_(false),
302 marking_deque_(heap),
303 code_flusher_(nullptr),
304 sweeper_(heap) {
305 }
288 306
289 void MarkCompactCollector::SetUp() { 307 void MarkCompactCollector::SetUp() {
290 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 308 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
291 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 309 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0);
292 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); 310 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0);
293 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 311 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
294 marking_deque()->SetUp(); 312 marking_deque()->SetUp();
295 313
296 if (FLAG_flush_code) { 314 if (FLAG_flush_code) {
297 code_flusher_ = new CodeFlusher(isolate()); 315 code_flusher_ = new CodeFlusher(isolate());
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 void MarkCompactCollector::EnsureSweepingCompleted() { 597 void MarkCompactCollector::EnsureSweepingCompleted() {
580 if (!sweeper().sweeping_in_progress()) return; 598 if (!sweeper().sweeping_in_progress()) return;
581 599
582 sweeper().EnsureCompleted(); 600 sweeper().EnsureCompleted();
583 heap()->old_space()->RefillFreeList(); 601 heap()->old_space()->RefillFreeList();
584 heap()->code_space()->RefillFreeList(); 602 heap()->code_space()->RefillFreeList();
585 heap()->map_space()->RefillFreeList(); 603 heap()->map_space()->RefillFreeList();
586 604
587 #ifdef VERIFY_HEAP 605 #ifdef VERIFY_HEAP
588 if (FLAG_verify_heap && !evacuation()) { 606 if (FLAG_verify_heap && !evacuation()) {
589 VerifyEvacuation(heap_); 607 FullEvacuationVerifier verifier(heap_);
608 verifier.Run();
590 } 609 }
591 #endif 610 #endif
592 611
593 if (heap()->memory_allocator()->unmapper()->has_delayed_chunks()) 612 if (heap()->memory_allocator()->unmapper()->has_delayed_chunks())
594 heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); 613 heap()->memory_allocator()->unmapper()->FreeQueuedChunks();
595 } 614 }
596 615
597 bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() { 616 bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() {
598 return num_sweeping_tasks_.Value() != 0; 617 return num_sweeping_tasks_.Value() != 0;
599 } 618 }
(...skipping 3104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3704 } 3723 }
3705 } 3724 }
3706 3725
3707 { 3726 {
3708 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_EPILOGUE); 3727 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_EPILOGUE);
3709 EvacuateEpilogue(); 3728 EvacuateEpilogue();
3710 } 3729 }
3711 3730
3712 #ifdef VERIFY_HEAP 3731 #ifdef VERIFY_HEAP
3713 if (FLAG_verify_heap && !sweeper().sweeping_in_progress()) { 3732 if (FLAG_verify_heap && !sweeper().sweeping_in_progress()) {
3714 VerifyEvacuation(heap()); 3733 FullEvacuationVerifier verifier(heap());
3734 verifier.Run();
3715 } 3735 }
3716 #endif 3736 #endif
3717 } 3737 }
3718 3738
3719 template <RememberedSetType type> 3739 template <RememberedSetType type>
3720 class PointerUpdateJobTraits { 3740 class PointerUpdateJobTraits {
3721 public: 3741 public:
3722 typedef int PerPageData; // Per page data is not used in this job. 3742 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. 3743 typedef int PerTaskData; // Per task data is not used in this job.
3724 3744
(...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 4172 // The target is always in old space, we don't have to record the slot in
4153 // the old-to-new remembered set. 4173 // the old-to-new remembered set.
4154 DCHECK(!heap()->InNewSpace(target)); 4174 DCHECK(!heap()->InNewSpace(target));
4155 RecordRelocSlot(host, &rinfo, target); 4175 RecordRelocSlot(host, &rinfo, target);
4156 } 4176 }
4157 } 4177 }
4158 } 4178 }
4159 4179
4160 } // namespace internal 4180 } // namespace internal
4161 } // namespace v8 4181 } // 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