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 2973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2984 | 2984 |
2985 // Find the last live object in the cell. | 2985 // Find the last live object in the cell. |
2986 unsigned int leading_zeros = | 2986 unsigned int leading_zeros = |
2987 base::bits::CountLeadingZeros32(current_cell & slot_mask); | 2987 base::bits::CountLeadingZeros32(current_cell & slot_mask); |
2988 CHECK(leading_zeros != Bitmap::kBitsPerCell); | 2988 CHECK(leading_zeros != Bitmap::kBitsPerCell); |
2989 int offset = static_cast<int>(Bitmap::kBitIndexMask - leading_zeros) - 1; | 2989 int offset = static_cast<int>(Bitmap::kBitIndexMask - leading_zeros) - 1; |
2990 | 2990 |
2991 base_address += (cell_index - base_address_cell_index) * | 2991 base_address += (cell_index - base_address_cell_index) * |
2992 Bitmap::kBitsPerCell * kPointerSize; | 2992 Bitmap::kBitsPerCell * kPointerSize; |
2993 Address address = base_address + offset * kPointerSize; | 2993 Address address = base_address + offset * kPointerSize; |
| 2994 |
| 2995 // If the found mark bit is part of a black area, the slot cannot be part |
| 2996 // of a live object since it is not marked. |
| 2997 if (p->IsBlackAreaEndMarker(address + kPointerSize)) return false; |
| 2998 |
2994 HeapObject* object = HeapObject::FromAddress(address); | 2999 HeapObject* object = HeapObject::FromAddress(address); |
2995 CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); | 3000 CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); |
2996 CHECK(object->address() < reinterpret_cast<Address>(slot)); | 3001 CHECK(object->address() < reinterpret_cast<Address>(slot)); |
2997 if ((object->address() + kPointerSize) <= slot && | 3002 if ((object->address() + kPointerSize) <= slot && |
2998 (object->address() + object->Size()) > slot) { | 3003 (object->address() + object->Size()) > slot) { |
2999 // If the slot is within the last found object in the cell, the slot is | 3004 // If the slot is within the last found object in the cell, the slot is |
3000 // in a live object. | 3005 // in a live object. |
3001 // Slots pointing to the first word of an object are invalid and removed. | 3006 // Slots pointing to the first word of an object are invalid and removed. |
3002 // This can happen when we move the object header while left trimming. | 3007 // This can happen when we move the object header while left trimming. |
3003 return true; | 3008 return true; |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3365 Space* space = p->owner(); | 3370 Space* space = p->owner(); |
3366 DCHECK_NOT_NULL(space); | 3371 DCHECK_NOT_NULL(space); |
3367 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || | 3372 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || |
3368 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); | 3373 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); |
3369 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 3374 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); |
3370 | 3375 |
3371 // Before we sweep objects on the page, we free dead array buffers which | 3376 // Before we sweep objects on the page, we free dead array buffers which |
3372 // requires valid mark bits. | 3377 // requires valid mark bits. |
3373 ArrayBufferTracker::FreeDead(p); | 3378 ArrayBufferTracker::FreeDead(p); |
3374 | 3379 |
| 3380 // We also release the black area markers here. |
| 3381 p->ReleaseBlackAreaEndMarkerMap(); |
| 3382 |
3375 Address free_start = p->area_start(); | 3383 Address free_start = p->area_start(); |
3376 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3384 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
3377 | 3385 |
3378 // If we use the skip list for code space pages, we have to lock the skip | 3386 // If we use the skip list for code space pages, we have to lock the skip |
3379 // list because it could be accessed concurrently by the runtime or the | 3387 // list because it could be accessed concurrently by the runtime or the |
3380 // deoptimizer. | 3388 // deoptimizer. |
3381 const bool rebuild_skip_list = | 3389 const bool rebuild_skip_list = |
3382 space->identity() == CODE_SPACE && p->skip_list() != nullptr; | 3390 space->identity() == CODE_SPACE && p->skip_list() != nullptr; |
3383 SkipList* skip_list = p->skip_list(); | 3391 SkipList* skip_list = p->skip_list(); |
3384 if (rebuild_skip_list) { | 3392 if (rebuild_skip_list) { |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3908 bool unused_page_present = false; | 3916 bool unused_page_present = false; |
3909 | 3917 |
3910 // Loop needs to support deletion if live bytes == 0 for a page. | 3918 // Loop needs to support deletion if live bytes == 0 for a page. |
3911 for (auto it = space->begin(); it != space->end();) { | 3919 for (auto it = space->begin(); it != space->end();) { |
3912 Page* p = *(it++); | 3920 Page* p = *(it++); |
3913 DCHECK(p->SweepingDone()); | 3921 DCHECK(p->SweepingDone()); |
3914 | 3922 |
3915 if (p->IsEvacuationCandidate()) { | 3923 if (p->IsEvacuationCandidate()) { |
3916 // Will be processed in EvacuateNewSpaceAndCandidates. | 3924 // Will be processed in EvacuateNewSpaceAndCandidates. |
3917 DCHECK(evacuation_candidates_.length() > 0); | 3925 DCHECK(evacuation_candidates_.length() > 0); |
| 3926 DCHECK(!p->HasBlackAreas()); |
3918 continue; | 3927 continue; |
3919 } | 3928 } |
3920 | 3929 |
3921 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { | 3930 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { |
3922 // We need to sweep the page to get it into an iterable state again. Note | 3931 // We need to sweep the page to get it into an iterable state again. Note |
3923 // that this adds unusable memory into the free list that is later on | 3932 // that this adds unusable memory into the free list that is later on |
3924 // (in the free list) dropped again. Since we only use the flag for | 3933 // (in the free list) dropped again. Since we only use the flag for |
3925 // testing this is fine. | 3934 // testing this is fine. |
3926 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); | 3935 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); |
3927 Sweeper::RawSweep(p, Sweeper::IGNORE_FREE_LIST, | 3936 Sweeper::RawSweep(p, Sweeper::IGNORE_FREE_LIST, |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4028 // The target is always in old space, we don't have to record the slot in | 4037 // The target is always in old space, we don't have to record the slot in |
4029 // the old-to-new remembered set. | 4038 // the old-to-new remembered set. |
4030 DCHECK(!heap()->InNewSpace(target)); | 4039 DCHECK(!heap()->InNewSpace(target)); |
4031 RecordRelocSlot(host, &rinfo, target); | 4040 RecordRelocSlot(host, &rinfo, target); |
4032 } | 4041 } |
4033 } | 4042 } |
4034 } | 4043 } |
4035 | 4044 |
4036 } // namespace internal | 4045 } // namespace internal |
4037 } // namespace v8 | 4046 } // namespace v8 |
OLD | NEW |