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

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

Issue 1517993003: [heap] Black is encoded with 11, grey with 10. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 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 | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | 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 15 matching lines...) Expand all
26 #include "src/ic/ic.h" 26 #include "src/ic/ic.h"
27 #include "src/ic/stub-cache.h" 27 #include "src/ic/stub-cache.h"
28 #include "src/profiler/cpu-profiler.h" 28 #include "src/profiler/cpu-profiler.h"
29 #include "src/v8.h" 29 #include "src/v8.h"
30 30
31 namespace v8 { 31 namespace v8 {
32 namespace internal { 32 namespace internal {
33 33
34 34
35 const char* Marking::kWhiteBitPattern = "00"; 35 const char* Marking::kWhiteBitPattern = "00";
36 const char* Marking::kBlackBitPattern = "10"; 36 const char* Marking::kBlackBitPattern = "11";
37 const char* Marking::kGreyBitPattern = "11"; 37 const char* Marking::kGreyBitPattern = "10";
38 const char* Marking::kImpossibleBitPattern = "01"; 38 const char* Marking::kImpossibleBitPattern = "01";
39 39
40 40
41 // The following has to hold in order for {Marking::MarkBitFrom} to not produce 41 // The following has to hold in order for {Marking::MarkBitFrom} to not produce
42 // invalid {kImpossibleBitPattern} in the marking bitmap by overlapping. 42 // invalid {kImpossibleBitPattern} in the marking bitmap by overlapping.
43 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2); 43 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2);
44 44
45 45
46 // ------------------------------------------------------------------------- 46 // -------------------------------------------------------------------------
47 // MarkCompactCollector 47 // MarkCompactCollector
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 HeapObject* object; 108 HeapObject* object;
109 Address next_object_must_be_here_or_later = bottom; 109 Address next_object_must_be_here_or_later = bottom;
110 110
111 for (Address current = bottom; current < top; current += kPointerSize) { 111 for (Address current = bottom; current < top; current += kPointerSize) {
112 object = HeapObject::FromAddress(current); 112 object = HeapObject::FromAddress(current);
113 if (MarkCompactCollector::IsMarked(object)) { 113 if (MarkCompactCollector::IsMarked(object)) {
114 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); 114 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
115 CHECK(current >= next_object_must_be_here_or_later); 115 CHECK(current >= next_object_must_be_here_or_later);
116 object->Iterate(&visitor); 116 object->Iterate(&visitor);
117 next_object_must_be_here_or_later = current + object->Size(); 117 next_object_must_be_here_or_later = current + object->Size();
118 // The next word for sure belongs to the current object, jump over it.
119 current += kPointerSize;
118 } 120 }
119 } 121 }
120 } 122 }
121 123
122 124
123 static void VerifyMarking(NewSpace* space) { 125 static void VerifyMarking(NewSpace* space) {
124 Address end = space->top(); 126 Address end = space->top();
125 NewSpacePageIterator it(space->bottom(), end); 127 NewSpacePageIterator it(space->bottom(), end);
126 // The bottom position is at the start of its page. Allows us to use 128 // The bottom position is at the start of its page. Allows us to use
127 // page->area_start() as start of range on all pages. 129 // page->area_start() as start of range on all pages.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 VerifyEvacuation(heap->new_space()); 232 VerifyEvacuation(heap->new_space());
231 233
232 VerifyEvacuationVisitor visitor; 234 VerifyEvacuationVisitor visitor;
233 heap->IterateStrongRoots(&visitor, VISIT_ALL); 235 heap->IterateStrongRoots(&visitor, VISIT_ALL);
234 } 236 }
235 #endif // VERIFY_HEAP 237 #endif // VERIFY_HEAP
236 238
237 239
238 void MarkCompactCollector::SetUp() { 240 void MarkCompactCollector::SetUp() {
239 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 241 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
240 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); 242 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0);
241 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); 243 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0);
242 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 244 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
243 245
244 free_list_old_space_.Reset(new FreeList(heap_->old_space())); 246 free_list_old_space_.Reset(new FreeList(heap_->old_space()));
245 free_list_code_space_.Reset(new FreeList(heap_->code_space())); 247 free_list_code_space_.Reset(new FreeList(heap_->code_space()));
246 free_list_map_space_.Reset(new FreeList(heap_->map_space())); 248 free_list_map_space_.Reset(new FreeList(heap_->map_space()));
247 EnsureMarkingDequeIsReserved(); 249 EnsureMarkingDequeIsReserved();
248 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); 250 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize);
249 slots_buffer_allocator_ = new SlotsBufferAllocator(); 251 slots_buffer_allocator_ = new SlotsBufferAllocator();
250 252
251 if (FLAG_flush_code) { 253 if (FLAG_flush_code) {
(...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 MarkBit markbit = Marking::MarkBitFrom(object); 1520 MarkBit markbit = Marking::MarkBitFrom(object);
1519 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) { 1521 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) {
1520 Marking::GreyToBlack(markbit); 1522 Marking::GreyToBlack(markbit);
1521 PushBlack(object); 1523 PushBlack(object);
1522 if (marking_deque()->IsFull()) return; 1524 if (marking_deque()->IsFull()) return;
1523 } 1525 }
1524 } 1526 }
1525 } 1527 }
1526 1528
1527 1529
1528 static inline int MarkWordToObjectStarts(uint32_t mark_bits,
1529 uint32_t next_mark_bits, Address base,
1530 Address* starts);
1531
1532
1533 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) { 1530 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
1534 DCHECK(!marking_deque()->IsFull()); 1531 DCHECK(!marking_deque()->IsFull());
1535 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 1532 LiveObjectIterator<kGreyObjects> it(p);
1536 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); 1533 HeapObject* object = NULL;
1537 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); 1534 while ((object = it.Next()) != NULL) {
1538 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 1535 MarkBit markbit = Marking::MarkBitFrom(object);
1539 1536 DCHECK(Marking::IsGrey(markbit));
1540 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { 1537 Marking::GreyToBlack(markbit);
1541 Address cell_base = it.CurrentCellBase(); 1538 PushBlack(object);
1542 MarkBit::CellType* cell = it.CurrentCell(); 1539 if (marking_deque()->IsFull()) return;
1543
1544 const MarkBit::CellType current_cell = *cell;
1545 if (current_cell == 0) continue;
1546
1547 MarkBit::CellType grey_objects;
1548 if (it.HasNext()) {
1549 const MarkBit::CellType next_cell = *(cell + 1);
1550 grey_objects = current_cell & ((current_cell >> 1) |
1551 (next_cell << (Bitmap::kBitsPerCell - 1)));
1552 } else {
1553 grey_objects = current_cell & (current_cell >> 1);
1554 }
1555
1556 int offset = 0;
1557 while (grey_objects != 0) {
1558 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects);
1559 grey_objects >>= trailing_zeros;
1560 offset += trailing_zeros;
1561 MarkBit markbit(cell, 1 << offset);
1562 DCHECK(Marking::IsGrey(markbit));
1563 Marking::GreyToBlack(markbit);
1564 Address addr = cell_base + offset * kPointerSize;
1565 HeapObject* object = HeapObject::FromAddress(addr);
1566 PushBlack(object);
1567 if (marking_deque()->IsFull()) return;
1568 offset += 2;
1569 grey_objects >>= 2;
1570 }
1571
1572 grey_objects >>= (Bitmap::kBitsPerCell - 1);
1573 } 1540 }
1574 } 1541 }
1575 1542
1576 1543
1577 class MarkCompactCollector::HeapObjectVisitor { 1544 class MarkCompactCollector::HeapObjectVisitor {
1578 public: 1545 public:
1579 virtual ~HeapObjectVisitor() {} 1546 virtual ~HeapObjectVisitor() {}
1580 virtual bool Visit(HeapObject* object) = 0; 1547 virtual bool Visit(HeapObject* object) = 0;
1581 }; 1548 };
1582 1549
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 CHECK(large_object->IsHeapObject()); 2908 CHECK(large_object->IsHeapObject());
2942 HeapObject* large_heap_object = HeapObject::cast(large_object); 2909 HeapObject* large_heap_object = HeapObject::cast(large_object);
2943 if (IsMarked(large_heap_object)) { 2910 if (IsMarked(large_heap_object)) {
2944 *out_object = large_heap_object; 2911 *out_object = large_heap_object;
2945 return true; 2912 return true;
2946 } 2913 }
2947 return false; 2914 return false;
2948 } 2915 }
2949 2916
2950 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); 2917 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot);
2951 unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; 2918 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2;
2952 MarkBit::CellType index_in_cell = 1U 2919 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index);
2953 << (mark_bit_index & Bitmap::kBitIndexMask);
2954 MarkBit::CellType* cells = p->markbits()->cells(); 2920 MarkBit::CellType* cells = p->markbits()->cells();
2955 Address cell_base = p->area_start(); 2921 Address base_address = p->area_start();
2956 unsigned int cell_base_start_index = Bitmap::IndexToCell( 2922 unsigned int base_address_cell_index = Bitmap::IndexToCell(
2957 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(cell_base))); 2923 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address)));
2958 2924
2959 // Check if the slot points to the start of an object. This can happen e.g. 2925 // Check if the slot points to the start of an object. This can happen e.g.
2960 // when we left trim a fixed array. Such slots are invalid and we can remove 2926 // when we left trim a fixed array. Such slots are invalid and we can remove
2961 // them. 2927 // them.
2962 if ((cells[start_index] & index_in_cell) != 0) { 2928 if (index_mask > 1) {
2963 return false; 2929 if ((cells[cell_index] & index_mask) != 0 &&
2930 (cells[cell_index] & (index_mask >> 1)) == 0) {
2931 return false;
2932 }
2933 } else {
2934 // Left trimming moves the mark bits so we cannot be in the very first cell.
2935 DCHECK(cell_index != base_address_cell_index);
2936 if ((cells[cell_index] & index_mask) != 0 &&
2937 (cells[cell_index - 1] & (1u << Bitmap::kBitIndexMask)) == 0) {
2938 return false;
2939 }
2964 } 2940 }
2965 2941
2966 // Check if the object is in the current cell. 2942 // Check if the object is in the current cell.
2967 MarkBit::CellType slot_mask; 2943 MarkBit::CellType slot_mask;
2968 if ((cells[start_index] == 0) || 2944 if ((cells[cell_index] == 0) ||
2969 (base::bits::CountTrailingZeros32(cells[start_index]) > 2945 (base::bits::CountTrailingZeros32(cells[cell_index]) >
2970 base::bits::CountTrailingZeros32(cells[start_index] | index_in_cell))) { 2946 base::bits::CountTrailingZeros32(cells[cell_index] | index_mask))) {
2971 // If we are already in the first cell, there is no live object. 2947 // If we are already in the first cell, there is no live object.
2972 if (start_index == cell_base_start_index) return false; 2948 if (cell_index == base_address_cell_index) return false;
2973 2949
2974 // If not, find a cell in a preceding cell slot that has a mark bit set. 2950 // If not, find a cell in a preceding cell slot that has a mark bit set.
2975 do { 2951 do {
2976 start_index--; 2952 cell_index--;
2977 } while (start_index > cell_base_start_index && cells[start_index] == 0); 2953 } while (cell_index > base_address_cell_index && cells[cell_index] == 0);
2978 2954
2979 // The slot must be in a dead object if there are no preceding cells that 2955 // The slot must be in a dead object if there are no preceding cells that
2980 // have mark bits set. 2956 // have mark bits set.
2981 if (cells[start_index] == 0) { 2957 if (cells[cell_index] == 0) {
2982 return false; 2958 return false;
2983 } 2959 }
2984 2960
2985 // The object is in a preceding cell. Set the mask to find any object. 2961 // The object is in a preceding cell. Set the mask to find any object.
2986 slot_mask = 0xffffffff; 2962 slot_mask = ~0u;
2987 } else { 2963 } else {
2988 // The object start is before the the slot index. Hence, in this case the
2989 // slot index can not be at the beginning of the cell.
2990 CHECK(index_in_cell > 1);
2991 // We are interested in object mark bits right before the slot. 2964 // We are interested in object mark bits right before the slot.
2992 slot_mask = index_in_cell - 1; 2965 slot_mask = index_mask + (index_mask - 1);
2993 } 2966 }
2994 2967
2995 MarkBit::CellType current_cell = cells[start_index]; 2968 MarkBit::CellType current_cell = cells[cell_index];
2996 CHECK(current_cell != 0); 2969 CHECK(current_cell != 0);
2997 2970
2998 // Find the last live object in the cell. 2971 // Find the last live object in the cell.
2999 unsigned int leading_zeros = 2972 unsigned int leading_zeros =
3000 base::bits::CountLeadingZeros32(current_cell & slot_mask); 2973 base::bits::CountLeadingZeros32(current_cell & slot_mask);
3001 CHECK(leading_zeros != 32); 2974 CHECK(leading_zeros != Bitmap::kBitsPerCell);
3002 unsigned int offset = Bitmap::kBitIndexMask - leading_zeros; 2975 int offset = static_cast<int>(Bitmap::kBitIndexMask - leading_zeros) - 1;
3003 2976
3004 cell_base += (start_index - cell_base_start_index) * 32 * kPointerSize; 2977 base_address += (cell_index - base_address_cell_index) *
3005 Address address = cell_base + offset * kPointerSize; 2978 Bitmap::kBitsPerCell * kPointerSize;
2979 Address address = base_address + offset * kPointerSize;
3006 HeapObject* object = HeapObject::FromAddress(address); 2980 HeapObject* object = HeapObject::FromAddress(address);
3007 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); 2981 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3008 CHECK(object->address() < reinterpret_cast<Address>(slot)); 2982 CHECK(object->address() < reinterpret_cast<Address>(slot));
3009 if (object->address() <= slot && 2983 if ((object->address() + kPointerSize) <= slot &&
3010 (object->address() + object->Size()) > slot) { 2984 (object->address() + object->Size()) > slot) {
3011 // If the slot is within the last found object in the cell, the slot is 2985 // If the slot is within the last found object in the cell, the slot is
3012 // in a live object. 2986 // in a live object.
2987 // Slots pointing to the first word of an object are invalid and removed.
2988 // This can happen when we move the object header while left trimming.
3013 *out_object = object; 2989 *out_object = object;
3014 return true; 2990 return true;
3015 } 2991 }
3016 return false; 2992 return false;
3017 } 2993 }
3018 2994
3019 2995
3020 bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) { 2996 bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) {
3021 // This function does not support large objects right now. 2997 // This function does not support large objects right now.
3022 Space* owner = p->owner(); 2998 Space* owner = p->owner();
3023 if (owner == heap_->lo_space() || owner == NULL) return true; 2999 if (owner == heap_->lo_space() || owner == NULL) {
3000 Object* large_object = heap_->lo_space()->FindObject(slot);
3001 // This object has to exist, otherwise we would not have recorded a slot
3002 // for it.
3003 CHECK(large_object->IsHeapObject());
3004 HeapObject* large_heap_object = HeapObject::cast(large_object);
3005 if (IsMarked(large_heap_object)) {
3006 return true;
3007 }
3008 return false;
3009 }
3024 3010
3025 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { 3011 LiveObjectIterator<kBlackObjects> it(p);
3026 Address cell_base = it.CurrentCellBase(); 3012 HeapObject* object = NULL;
3027 MarkBit::CellType* cell = it.CurrentCell(); 3013 while ((object = it.Next()) != NULL) {
3014 int size = object->Size();
3028 3015
3029 MarkBit::CellType current_cell = *cell; 3016 if (object->address() > slot) return false;
3030 if (current_cell == 0) continue; 3017 if (object->address() <= slot && slot < (object->address() + size)) {
3031 3018 return true;
3032 int offset = 0;
3033 while (current_cell != 0) {
3034 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell);
3035 current_cell >>= trailing_zeros;
3036 offset += trailing_zeros;
3037 Address address = cell_base + offset * kPointerSize;
3038
3039 HeapObject* object = HeapObject::FromAddress(address);
3040 int size = object->Size();
3041
3042 if (object->address() > slot) return false;
3043 if (object->address() <= slot && slot < (object->address() + size)) {
3044 return true;
3045 }
3046
3047 offset++;
3048 current_cell >>= 1;
3049 } 3019 }
3050 } 3020 }
3051 return false; 3021 return false;
3052 } 3022 }
3053 3023
3054 3024
3055 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { 3025 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) {
3056 HeapObject* object = NULL; 3026 HeapObject* object = NULL;
3057 // The target object is black but we don't know if the source slot is black. 3027 // The target object is black but we don't know if the source slot is black.
3058 // The source object could have died and the slot could be part of a free 3028 // The source object could have died and the slot could be part of a free
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
3377 ObjectVisitor* v) { 3347 ObjectVisitor* v) {
3378 DCHECK(!p->IsEvacuationCandidate() && !p->WasSwept()); 3348 DCHECK(!p->IsEvacuationCandidate() && !p->WasSwept());
3379 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, 3349 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST,
3380 space->identity() == CODE_SPACE); 3350 space->identity() == CODE_SPACE);
3381 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); 3351 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST));
3382 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || 3352 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD ||
3383 sweeping_mode == SWEEP_ONLY); 3353 sweeping_mode == SWEEP_ONLY);
3384 3354
3385 Address free_start = p->area_start(); 3355 Address free_start = p->area_start();
3386 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 3356 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
3387 Address starts[16];
3388 3357
3389 // If we use the skip list for code space pages, we have to lock the skip 3358 // If we use the skip list for code space pages, we have to lock the skip
3390 // list because it could be accessed concurrently by the runtime or the 3359 // list because it could be accessed concurrently by the runtime or the
3391 // deoptimizer. 3360 // deoptimizer.
3392 SkipList* skip_list = p->skip_list(); 3361 SkipList* skip_list = p->skip_list();
3393 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { 3362 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) {
3394 skip_list->Clear(); 3363 skip_list->Clear();
3395 } 3364 }
3396 3365
3397 intptr_t freed_bytes = 0; 3366 intptr_t freed_bytes = 0;
3398 intptr_t max_freed_bytes = 0; 3367 intptr_t max_freed_bytes = 0;
3399 int curr_region = -1; 3368 int curr_region = -1;
3400 3369
3401 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { 3370 LiveObjectIterator<kBlackObjects> it(p);
3402 Address cell_base = it.CurrentCellBase(); 3371 HeapObject* object = NULL;
3403 MarkBit::CellType* cell = it.CurrentCell(); 3372 while ((object = it.Next()) != NULL) {
3404 int live_objects = 3373 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3405 MarkWordToObjectStarts(*cell, it.PeekNext(), cell_base, starts); 3374 Address free_end = object->address();
3406 int live_index = 0; 3375 if (free_end != free_start) {
3407 for (; live_objects != 0; live_objects--) { 3376 int size = static_cast<int>(free_end - free_start);
3408 Address free_end = starts[live_index++]; 3377 if (free_space_mode == ZAP_FREE_SPACE) {
3409 if (free_end != free_start) { 3378 memset(free_start, 0xcc, size);
3410 int size = static_cast<int>(free_end - free_start);
3411 if (free_space_mode == ZAP_FREE_SPACE) {
3412 memset(free_start, 0xcc, size);
3413 }
3414 freed_bytes = Free<parallelism>(space, free_list, free_start, size);
3415 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3416 } 3379 }
3417 HeapObject* live_object = HeapObject::FromAddress(free_end); 3380 freed_bytes = Free<parallelism>(space, free_list, free_start, size);
3418 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 3381 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3419 Map* map = live_object->synchronized_map(); 3382 }
3420 int size = live_object->SizeFromMap(map); 3383 Map* map = object->synchronized_map();
3421 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { 3384 int size = object->SizeFromMap(map);
3422 live_object->IterateBody(map->instance_type(), size, v); 3385 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) {
3386 object->IterateBody(map->instance_type(), size, v);
3387 }
3388 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) {
3389 int new_region_start = SkipList::RegionNumber(free_end);
3390 int new_region_end =
3391 SkipList::RegionNumber(free_end + size - kPointerSize);
3392 if (new_region_start != curr_region || new_region_end != curr_region) {
3393 skip_list->AddObject(free_end, size);
3394 curr_region = new_region_end;
3423 } 3395 }
3424 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) {
3425 int new_region_start = SkipList::RegionNumber(free_end);
3426 int new_region_end =
3427 SkipList::RegionNumber(free_end + size - kPointerSize);
3428 if (new_region_start != curr_region || new_region_end != curr_region) {
3429 skip_list->AddObject(free_end, size);
3430 curr_region = new_region_end;
3431 }
3432 }
3433 free_start = free_end + size;
3434 } 3396 }
3435 // Clear marking bits for current cell. 3397 free_start = free_end + size;
3436 *cell = 0;
3437 } 3398 }
3399
3400 // Clear the mark bits of that page and reset live bytes count.
3401 Bitmap::Clear(p);
3402
3438 if (free_start != p->area_end()) { 3403 if (free_start != p->area_end()) {
3439 int size = static_cast<int>(p->area_end() - free_start); 3404 int size = static_cast<int>(p->area_end() - free_start);
3440 if (free_space_mode == ZAP_FREE_SPACE) { 3405 if (free_space_mode == ZAP_FREE_SPACE) {
3441 memset(free_start, 0xcc, size); 3406 memset(free_start, 0xcc, size);
3442 } 3407 }
3443 freed_bytes = Free<parallelism>(space, free_list, free_start, size); 3408 freed_bytes = Free<parallelism>(space, free_list, free_start, size);
3444 max_freed_bytes = Max(freed_bytes, max_freed_bytes); 3409 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3445 } 3410 }
3446 p->ResetLiveBytes();
3447 3411
3448 if (parallelism == MarkCompactCollector::SWEEP_IN_PARALLEL) { 3412 if (parallelism == MarkCompactCollector::SWEEP_IN_PARALLEL) {
3449 // When concurrent sweeping is active, the page will be marked after 3413 // When concurrent sweeping is active, the page will be marked after
3450 // sweeping by the main thread. 3414 // sweeping by the main thread.
3451 p->parallel_sweeping_state().SetValue(MemoryChunk::kSweepingFinalize); 3415 p->parallel_sweeping_state().SetValue(MemoryChunk::kSweepingFinalize);
3452 } else { 3416 } else {
3453 p->SetWasSwept(); 3417 p->SetWasSwept();
3454 } 3418 }
3455 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); 3419 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
3456 } 3420 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3489 Page* p = evacuation_candidates_[i]; 3453 Page* p = evacuation_candidates_[i];
3490 DCHECK(p->IsEvacuationCandidate() || 3454 DCHECK(p->IsEvacuationCandidate() ||
3491 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 3455 p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
3492 if (p->IsEvacuationCandidate()) { 3456 if (p->IsEvacuationCandidate()) {
3493 SlotsBuffer::RemoveObjectSlots(heap_, p->slots_buffer(), start_slot, 3457 SlotsBuffer::RemoveObjectSlots(heap_, p->slots_buffer(), start_slot,
3494 end_slot); 3458 end_slot);
3495 } 3459 }
3496 } 3460 }
3497 } 3461 }
3498 3462
3463 #ifdef VERIFY_HEAP
3464 static void VerifyAllBlackObjects(MemoryChunk* page) {
3465 LiveObjectIterator<kAllLiveObjects> it(page);
3466 HeapObject* object = NULL;
3467 while ((object = it.Next()) != NULL) {
3468 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3469 }
3470 }
3471 #endif // VERIFY_HEAP
3499 3472
3500 bool MarkCompactCollector::VisitLiveObjects(MemoryChunk* page, 3473 bool MarkCompactCollector::VisitLiveObjects(MemoryChunk* page,
3501 HeapObjectVisitor* visitor, 3474 HeapObjectVisitor* visitor,
3502 IterationMode mode) { 3475 IterationMode mode) {
3503 Address offsets[16]; 3476 #ifdef VERIFY_HEAP
3504 for (MarkBitCellIterator it(page); !it.Done(); it.Advance()) { 3477 VerifyAllBlackObjects(page);
3505 Address cell_base = it.CurrentCellBase(); 3478 #endif // VERIFY_HEAP
3506 MarkBit::CellType* cell = it.CurrentCell(); 3479
3507 if (*cell == 0) continue; 3480 LiveObjectIterator<kBlackObjects> it(page);
3508 int live_objects = 3481 HeapObject* object = NULL;
3509 MarkWordToObjectStarts(*cell, it.PeekNext(), cell_base, offsets); 3482 while ((object = it.Next()) != NULL) {
3510 for (int i = 0; i < live_objects; i++) { 3483 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3511 HeapObject* object = HeapObject::FromAddress(offsets[i]); 3484 if (!visitor->Visit(object)) {
3512 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); 3485 if (mode == kClearMarkbits) {
3513 if (!visitor->Visit(object)) { 3486 page->markbits()->ClearRange(
3514 if ((mode == kClearMarkbits) && (i > 0)) { 3487 page->AddressToMarkbitIndex(page->area_start()),
3515 page->markbits()->ClearRange( 3488 page->AddressToMarkbitIndex(object->address()));
3516 page->AddressToMarkbitIndex(page->area_start()),
3517 page->AddressToMarkbitIndex(offsets[i]));
3518 }
3519 return false;
3520 } 3489 }
3490 return false;
3521 } 3491 }
3522 if (mode == kClearMarkbits) { 3492 }
3523 *cell = 0; 3493 if (mode == kClearMarkbits) {
3524 } 3494 Bitmap::Clear(page);
3525 } 3495 }
3526 return true; 3496 return true;
3527 } 3497 }
3528 3498
3529 3499
3530 void MarkCompactCollector::VisitLiveObjectsBody(Page* page, 3500 void MarkCompactCollector::VisitLiveObjectsBody(Page* page,
3531 ObjectVisitor* visitor) { 3501 ObjectVisitor* visitor) {
3532 Address starts[16]; 3502 #ifdef VERIFY_HEAP
3533 for (MarkBitCellIterator it(page); !it.Done(); it.Advance()) { 3503 VerifyAllBlackObjects(page);
3534 Address cell_base = it.CurrentCellBase(); 3504 #endif // VERIFY_HEAP
3535 MarkBit::CellType* cell = it.CurrentCell(); 3505
3536 if (*cell == 0) continue; 3506 LiveObjectIterator<kBlackObjects> it(page);
3537 int live_objects = 3507 HeapObject* object = NULL;
3538 MarkWordToObjectStarts(*cell, it.PeekNext(), cell_base, starts); 3508 while ((object = it.Next()) != NULL) {
3539 for (int i = 0; i < live_objects; i++) { 3509 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3540 HeapObject* live_object = HeapObject::FromAddress(starts[i]); 3510 Map* map = object->synchronized_map();
3541 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 3511 int size = object->SizeFromMap(map);
3542 Map* map = live_object->synchronized_map(); 3512 object->IterateBody(map->instance_type(), size, visitor);
3543 int size = live_object->SizeFromMap(map);
3544 live_object->IterateBody(map->instance_type(), size, visitor);
3545 }
3546 } 3513 }
3547 } 3514 }
3548 3515
3549 3516
3550 void MarkCompactCollector::SweepAbortedPages() { 3517 void MarkCompactCollector::SweepAbortedPages() {
3551 // Second pass on aborted pages. 3518 // Second pass on aborted pages.
3552 for (int i = 0; i < evacuation_candidates_.length(); i++) { 3519 for (int i = 0; i < evacuation_candidates_.length(); i++) {
3553 Page* p = evacuation_candidates_[i]; 3520 Page* p = evacuation_candidates_[i];
3554 if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { 3521 if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) {
3555 p->ClearFlag(MemoryChunk::COMPACTION_WAS_ABORTED); 3522 p->ClearFlag(MemoryChunk::COMPACTION_WAS_ABORTED);
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
3772 CHECK(p->WasSwept()); 3739 CHECK(p->WasSwept());
3773 space->ReleasePage(p); 3740 space->ReleasePage(p);
3774 } 3741 }
3775 evacuation_candidates_.Rewind(0); 3742 evacuation_candidates_.Rewind(0);
3776 compacting_ = false; 3743 compacting_ = false;
3777 heap()->FilterStoreBufferEntriesOnAboutToBeFreedPages(); 3744 heap()->FilterStoreBufferEntriesOnAboutToBeFreedPages();
3778 heap()->FreeQueuedChunks(); 3745 heap()->FreeQueuedChunks();
3779 } 3746 }
3780 3747
3781 3748
3782 #ifdef VERIFY_HEAP
3783 static bool VerifyAllBlackObjects(uint32_t mark_bits, uint32_t next_mark_bits) {
3784 // Check for overlapping mark bits.
3785 if ((mark_bits & 0x80000000) && (next_mark_bits & 0x1)) return false;
3786
3787 unsigned index = 0;
3788 while ((index = base::bits::CountTrailingZeros32(mark_bits)) != 32) {
3789 if (index > 0) mark_bits >>= index;
3790 if ((mark_bits & 0x3) == 0x3) {
3791 // There should not be any grey (11) objects.
3792 return false;
3793 }
3794 mark_bits &= 0xFFFFFFFE;
3795 }
3796 return true;
3797 }
3798 #endif // VERIFY_HEAP
3799
3800
3801 // Takes a word of mark bits and a base address. Returns the number of objects
3802 // that start in the range. Puts the object starts in the supplied array.
3803 static inline int MarkWordToObjectStarts(uint32_t mark_bits,
3804 uint32_t next_mark_bits, Address base,
3805 Address* starts) {
3806 int objects = 0;
3807
3808 #ifdef VERIFY_HEAP
3809 if (FLAG_verify_heap) {
3810 CHECK(VerifyAllBlackObjects(mark_bits, next_mark_bits));
3811 }
3812 #endif // VERIFY_HEAP
3813
3814 unsigned index = 0;
3815 while ((index = base::bits::CountTrailingZeros32(mark_bits)) != 32) {
3816 starts[objects++] = base + kPointerSize * index;
3817 mark_bits &= ~(1u << index);
3818 }
3819 return objects;
3820 }
3821
3822
3823 int MarkCompactCollector::SweepInParallel(PagedSpace* space, 3749 int MarkCompactCollector::SweepInParallel(PagedSpace* space,
3824 int required_freed_bytes) { 3750 int required_freed_bytes) {
3825 int max_freed = 0; 3751 int max_freed = 0;
3826 int max_freed_overall = 0; 3752 int max_freed_overall = 0;
3827 PageIterator it(space); 3753 PageIterator it(space);
3828 while (it.has_next()) { 3754 while (it.has_next()) {
3829 Page* p = it.next(); 3755 Page* p = it.next();
3830 max_freed = SweepInParallel(p, space); 3756 max_freed = SweepInParallel(p, space);
3831 DCHECK(max_freed >= 0); 3757 DCHECK(max_freed >= 0);
3832 if (required_freed_bytes > 0 && max_freed >= required_freed_bytes) { 3758 if (required_freed_bytes > 0 && max_freed >= required_freed_bytes) {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
4096 MarkBit mark_bit = Marking::MarkBitFrom(host); 4022 MarkBit mark_bit = Marking::MarkBitFrom(host);
4097 if (Marking::IsBlack(mark_bit)) { 4023 if (Marking::IsBlack(mark_bit)) {
4098 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 4024 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
4099 RecordRelocSlot(&rinfo, target); 4025 RecordRelocSlot(&rinfo, target);
4100 } 4026 }
4101 } 4027 }
4102 } 4028 }
4103 4029
4104 } // namespace internal 4030 } // namespace internal
4105 } // namespace v8 4031 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698