| 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 |