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

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

Issue 1514693010: [heap] Verify mark bits when iterating mark bits. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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 | « src/heap/mark-compact.h ('k') | 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 1470 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 MarkBit markbit = Marking::MarkBitFrom(object); 1481 MarkBit markbit = Marking::MarkBitFrom(object);
1482 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) { 1482 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) {
1483 Marking::GreyToBlack(markbit); 1483 Marking::GreyToBlack(markbit);
1484 PushBlack(object); 1484 PushBlack(object);
1485 if (marking_deque()->IsFull()) return; 1485 if (marking_deque()->IsFull()) return;
1486 } 1486 }
1487 } 1487 }
1488 } 1488 }
1489 1489
1490 1490
1491 static inline int MarkWordToObjectStarts(uint32_t mark_bits, Address base, 1491 static inline int MarkWordToObjectStarts(uint32_t mark_bits,
1492 uint32_t next_mark_bits, Address base,
1492 Address* starts); 1493 Address* starts);
1493 1494
1494 1495
1495 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) { 1496 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
1496 DCHECK(!marking_deque()->IsFull()); 1497 DCHECK(!marking_deque()->IsFull());
1497 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 1498 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
1498 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); 1499 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
1499 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); 1500 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0);
1500 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 1501 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
1501 1502
(...skipping 1764 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 skip_list->Clear(); 3267 skip_list->Clear();
3267 } 3268 }
3268 3269
3269 intptr_t freed_bytes = 0; 3270 intptr_t freed_bytes = 0;
3270 intptr_t max_freed_bytes = 0; 3271 intptr_t max_freed_bytes = 0;
3271 int curr_region = -1; 3272 int curr_region = -1;
3272 3273
3273 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { 3274 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) {
3274 Address cell_base = it.CurrentCellBase(); 3275 Address cell_base = it.CurrentCellBase();
3275 MarkBit::CellType* cell = it.CurrentCell(); 3276 MarkBit::CellType* cell = it.CurrentCell();
3276 int live_objects = MarkWordToObjectStarts(*cell, cell_base, starts); 3277 int live_objects =
3278 MarkWordToObjectStarts(*cell, it.PeekNext(), cell_base, starts);
3277 int live_index = 0; 3279 int live_index = 0;
3278 for (; live_objects != 0; live_objects--) { 3280 for (; live_objects != 0; live_objects--) {
3279 Address free_end = starts[live_index++]; 3281 Address free_end = starts[live_index++];
3280 if (free_end != free_start) { 3282 if (free_end != free_start) {
3281 int size = static_cast<int>(free_end - free_start); 3283 int size = static_cast<int>(free_end - free_start);
3282 if (free_space_mode == ZAP_FREE_SPACE) { 3284 if (free_space_mode == ZAP_FREE_SPACE) {
3283 memset(free_start, 0xcc, size); 3285 memset(free_start, 0xcc, size);
3284 } 3286 }
3285 freed_bytes = Free<parallelism>(space, free_list, free_start, size); 3287 freed_bytes = Free<parallelism>(space, free_list, free_start, size);
3286 max_freed_bytes = Max(freed_bytes, max_freed_bytes); 3288 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3369 3371
3370 3372
3371 bool MarkCompactCollector::VisitLiveObjects(MemoryChunk* page, 3373 bool MarkCompactCollector::VisitLiveObjects(MemoryChunk* page,
3372 HeapObjectVisitor* visitor, 3374 HeapObjectVisitor* visitor,
3373 IterationMode mode) { 3375 IterationMode mode) {
3374 Address offsets[16]; 3376 Address offsets[16];
3375 for (MarkBitCellIterator it(page); !it.Done(); it.Advance()) { 3377 for (MarkBitCellIterator it(page); !it.Done(); it.Advance()) {
3376 Address cell_base = it.CurrentCellBase(); 3378 Address cell_base = it.CurrentCellBase();
3377 MarkBit::CellType* cell = it.CurrentCell(); 3379 MarkBit::CellType* cell = it.CurrentCell();
3378 if (*cell == 0) continue; 3380 if (*cell == 0) continue;
3379 int live_objects = MarkWordToObjectStarts(*cell, cell_base, offsets); 3381 int live_objects =
3382 MarkWordToObjectStarts(*cell, it.PeekNext(), cell_base, offsets);
3380 for (int i = 0; i < live_objects; i++) { 3383 for (int i = 0; i < live_objects; i++) {
3381 HeapObject* object = HeapObject::FromAddress(offsets[i]); 3384 HeapObject* object = HeapObject::FromAddress(offsets[i]);
3382 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); 3385 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3383 if (!visitor->Visit(object)) { 3386 if (!visitor->Visit(object)) {
3384 if ((mode == kClearMarkbits) && (i > 0)) { 3387 if ((mode == kClearMarkbits) && (i > 0)) {
3385 page->markbits()->ClearRange( 3388 page->markbits()->ClearRange(
3386 page->AddressToMarkbitIndex(page->area_start()), 3389 page->AddressToMarkbitIndex(page->area_start()),
3387 page->AddressToMarkbitIndex(offsets[i])); 3390 page->AddressToMarkbitIndex(offsets[i]));
3388 } 3391 }
3389 return false; 3392 return false;
3390 } 3393 }
3391 } 3394 }
3392 if (mode == kClearMarkbits) { 3395 if (mode == kClearMarkbits) {
3393 *cell = 0; 3396 *cell = 0;
3394 } 3397 }
3395 } 3398 }
3396 return true; 3399 return true;
3397 } 3400 }
3398 3401
3399 3402
3400 void MarkCompactCollector::VisitLiveObjectsBody(Page* page, 3403 void MarkCompactCollector::VisitLiveObjectsBody(Page* page,
3401 ObjectVisitor* visitor) { 3404 ObjectVisitor* visitor) {
3402 Address starts[16]; 3405 Address starts[16];
3403 for (MarkBitCellIterator it(page); !it.Done(); it.Advance()) { 3406 for (MarkBitCellIterator it(page); !it.Done(); it.Advance()) {
3404 Address cell_base = it.CurrentCellBase(); 3407 Address cell_base = it.CurrentCellBase();
3405 MarkBit::CellType* cell = it.CurrentCell(); 3408 MarkBit::CellType* cell = it.CurrentCell();
3406 if (*cell == 0) continue; 3409 if (*cell == 0) continue;
3407 int live_objects = MarkWordToObjectStarts(*cell, cell_base, starts); 3410 int live_objects =
3411 MarkWordToObjectStarts(*cell, it.PeekNext(), cell_base, starts);
3408 for (int i = 0; i < live_objects; i++) { 3412 for (int i = 0; i < live_objects; i++) {
3409 HeapObject* live_object = HeapObject::FromAddress(starts[i]); 3413 HeapObject* live_object = HeapObject::FromAddress(starts[i]);
3410 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 3414 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(live_object)));
3411 Map* map = live_object->synchronized_map(); 3415 Map* map = live_object->synchronized_map();
3412 int size = live_object->SizeFromMap(map); 3416 int size = live_object->SizeFromMap(map);
3413 live_object->IterateBody(map->instance_type(), size, visitor); 3417 live_object->IterateBody(map->instance_type(), size, visitor);
3414 } 3418 }
3415 } 3419 }
3416 } 3420 }
3417 3421
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
3641 CHECK(p->WasSwept()); 3645 CHECK(p->WasSwept());
3642 space->ReleasePage(p); 3646 space->ReleasePage(p);
3643 } 3647 }
3644 evacuation_candidates_.Rewind(0); 3648 evacuation_candidates_.Rewind(0);
3645 compacting_ = false; 3649 compacting_ = false;
3646 heap()->FilterStoreBufferEntriesOnAboutToBeFreedPages(); 3650 heap()->FilterStoreBufferEntriesOnAboutToBeFreedPages();
3647 heap()->FreeQueuedChunks(); 3651 heap()->FreeQueuedChunks();
3648 } 3652 }
3649 3653
3650 3654
3655 #ifdef VERIFY_HEAP
3656 static bool VerifyAllBlackObjects(uint32_t mark_bits, uint32_t next_mark_bits) {
3657 // Check for overlapping mark bits.
3658 if ((mark_bits & 0x80000000) && (next_mark_bits & 0x1)) return false;
3659
3660 unsigned index = 0;
3661 while ((index = base::bits::CountTrailingZeros32(mark_bits)) != 32) {
3662 if (index > 0) mark_bits >>= index;
3663 if ((mark_bits & 0x3) == 0x3) {
3664 // There should not be any grey (11) objects.
3665 return false;
3666 }
3667 mark_bits &= 0xFFFFFFFE;
3668 }
3669 return true;
3670 }
3671 #endif // VERIFY_HEAP
3672
3673
3651 // Takes a word of mark bits and a base address. Returns the number of objects 3674 // Takes a word of mark bits and a base address. Returns the number of objects
3652 // that start in the range. Puts the object starts in the supplied array. 3675 // that start in the range. Puts the object starts in the supplied array.
3653 static inline int MarkWordToObjectStarts(uint32_t mark_bits, Address base, 3676 static inline int MarkWordToObjectStarts(uint32_t mark_bits,
3677 uint32_t next_mark_bits, Address base,
3654 Address* starts) { 3678 Address* starts) {
3655 int objects = 0; 3679 int objects = 0;
3656 3680
3657 // No consecutive 1 bits. 3681 #ifdef VERIFY_HEAP
3658 DCHECK((mark_bits & 0x180) != 0x180); 3682 if (FLAG_verify_heap) {
3659 DCHECK((mark_bits & 0x18000) != 0x18000); 3683 CHECK(VerifyAllBlackObjects(mark_bits, next_mark_bits));
3660 DCHECK((mark_bits & 0x1800000) != 0x1800000); 3684 }
3685 #endif // VERIFY_HEAP
3661 3686
3662 unsigned index = 0; 3687 unsigned index = 0;
3663 while ((index = base::bits::CountTrailingZeros32(mark_bits)) != 32) { 3688 while ((index = base::bits::CountTrailingZeros32(mark_bits)) != 32) {
3664 starts[objects++] = base + kPointerSize * index; 3689 starts[objects++] = base + kPointerSize * index;
3665 mark_bits &= ~(1u << index); 3690 mark_bits &= ~(1u << index);
3666 } 3691 }
3667 return objects; 3692 return objects;
3668 } 3693 }
3669 3694
3670 3695
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3934 MarkBit mark_bit = Marking::MarkBitFrom(host); 3959 MarkBit mark_bit = Marking::MarkBitFrom(host);
3935 if (Marking::IsBlack(mark_bit)) { 3960 if (Marking::IsBlack(mark_bit)) {
3936 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 3961 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
3937 RecordRelocSlot(&rinfo, target); 3962 RecordRelocSlot(&rinfo, target);
3938 } 3963 }
3939 } 3964 }
3940 } 3965 }
3941 3966
3942 } // namespace internal 3967 } // namespace internal
3943 } // namespace v8 3968 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698