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/heap.h" | 5 #include "src/heap/heap.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 3126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3137 DCHECK(CanMoveObjectStart(object)); | 3137 DCHECK(CanMoveObjectStart(object)); |
3138 Object** former_start = HeapObject::RawField(object, 0); | 3138 Object** former_start = HeapObject::RawField(object, 0); |
3139 int new_start_index = elements_to_trim * (element_size / kPointerSize); | 3139 int new_start_index = elements_to_trim * (element_size / kPointerSize); |
3140 former_start[new_start_index] = map; | 3140 former_start[new_start_index] = map; |
3141 former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim); | 3141 former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim); |
3142 FixedArrayBase* new_object = | 3142 FixedArrayBase* new_object = |
3143 FixedArrayBase::cast(HeapObject::FromAddress(new_start)); | 3143 FixedArrayBase::cast(HeapObject::FromAddress(new_start)); |
3144 | 3144 |
3145 // Maintain consistency of live bytes during incremental marking | 3145 // Maintain consistency of live bytes during incremental marking |
3146 Marking::TransferMark(this, object->address(), new_start); | 3146 Marking::TransferMark(this, object->address(), new_start); |
| 3147 if (mark_compact_collector()->sweeping_in_progress()) { |
| 3148 // Array trimming during sweeping can add invalid slots in free list. |
| 3149 ClearRecordedSlotRange(object, former_start, |
| 3150 HeapObject::RawField(new_object, 0)); |
| 3151 } |
3147 AdjustLiveBytes(new_object, -bytes_to_trim, Heap::CONCURRENT_TO_SWEEPER); | 3152 AdjustLiveBytes(new_object, -bytes_to_trim, Heap::CONCURRENT_TO_SWEEPER); |
3148 | 3153 |
3149 // Notify the heap profiler of change in object layout. | 3154 // Notify the heap profiler of change in object layout. |
3150 OnMoveEvent(new_object, object, new_object->Size()); | 3155 OnMoveEvent(new_object, object, new_object->Size()); |
3151 return new_object; | 3156 return new_object; |
3152 } | 3157 } |
3153 | 3158 |
3154 | 3159 |
3155 // Force instantiation of templatized method. | 3160 // Force instantiation of templatized method. |
3156 template void Heap::RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>( | 3161 template void Heap::RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>( |
(...skipping 29 matching lines...) Expand all Loading... |
3186 DCHECK(object->map() != fixed_cow_array_map()); | 3191 DCHECK(object->map() != fixed_cow_array_map()); |
3187 | 3192 |
3188 if (bytes_to_trim == 0) { | 3193 if (bytes_to_trim == 0) { |
3189 // No need to create filler and update live bytes counters, just initialize | 3194 // No need to create filler and update live bytes counters, just initialize |
3190 // header of the trimmed array. | 3195 // header of the trimmed array. |
3191 object->synchronized_set_length(len - elements_to_trim); | 3196 object->synchronized_set_length(len - elements_to_trim); |
3192 return; | 3197 return; |
3193 } | 3198 } |
3194 | 3199 |
3195 // Calculate location of new array end. | 3200 // Calculate location of new array end. |
3196 Address new_end = object->address() + object->Size() - bytes_to_trim; | 3201 Address old_end = object->address() + object->Size(); |
| 3202 Address new_end = old_end - bytes_to_trim; |
3197 | 3203 |
3198 // Technically in new space this write might be omitted (except for | 3204 // Technically in new space this write might be omitted (except for |
3199 // debug mode which iterates through the heap), but to play safer | 3205 // debug mode which iterates through the heap), but to play safer |
3200 // we still do it. | 3206 // we still do it. |
3201 // We do not create a filler for objects in large object space. | 3207 // We do not create a filler for objects in large object space. |
3202 // TODO(hpayer): We should shrink the large object page if the size | 3208 // TODO(hpayer): We should shrink the large object page if the size |
3203 // of the object changed significantly. | 3209 // of the object changed significantly. |
3204 if (!lo_space()->Contains(object)) { | 3210 if (!lo_space()->Contains(object)) { |
3205 CreateFillerObjectAt(new_end, bytes_to_trim); | 3211 CreateFillerObjectAt(new_end, bytes_to_trim); |
| 3212 if (mark_compact_collector()->sweeping_in_progress()) { |
| 3213 // Array trimming during sweeping can add invalid slots in free list. |
| 3214 ClearRecordedSlotRange(object, reinterpret_cast<Object**>(new_end), |
| 3215 reinterpret_cast<Object**>(old_end)); |
| 3216 } |
3206 } | 3217 } |
3207 | 3218 |
3208 // Initialize header of the trimmed array. We are storing the new length | 3219 // Initialize header of the trimmed array. We are storing the new length |
3209 // using release store after creating a filler for the left-over space to | 3220 // using release store after creating a filler for the left-over space to |
3210 // avoid races with the sweeper thread. | 3221 // avoid races with the sweeper thread. |
3211 object->synchronized_set_length(len - elements_to_trim); | 3222 object->synchronized_set_length(len - elements_to_trim); |
3212 | 3223 |
3213 // Maintain consistency of live bytes during incremental marking | 3224 // Maintain consistency of live bytes during incremental marking |
3214 AdjustLiveBytes(object, -bytes_to_trim, mode); | 3225 AdjustLiveBytes(object, -bytes_to_trim, mode); |
3215 | 3226 |
(...skipping 2310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5526 void Heap::ClearRecordedSlot(HeapObject* object, Object** slot) { | 5537 void Heap::ClearRecordedSlot(HeapObject* object, Object** slot) { |
5527 if (!InNewSpace(object)) { | 5538 if (!InNewSpace(object)) { |
5528 store_buffer()->MoveEntriesToRememberedSet(); | 5539 store_buffer()->MoveEntriesToRememberedSet(); |
5529 Address slot_addr = reinterpret_cast<Address>(slot); | 5540 Address slot_addr = reinterpret_cast<Address>(slot); |
5530 Page* page = Page::FromAddress(slot_addr); | 5541 Page* page = Page::FromAddress(slot_addr); |
5531 DCHECK_EQ(page->owner()->identity(), OLD_SPACE); | 5542 DCHECK_EQ(page->owner()->identity(), OLD_SPACE); |
5532 RememberedSet<OLD_TO_NEW>::Remove(page, slot_addr); | 5543 RememberedSet<OLD_TO_NEW>::Remove(page, slot_addr); |
5533 } | 5544 } |
5534 } | 5545 } |
5535 | 5546 |
| 5547 void Heap::ClearRecordedSlotRange(HeapObject* object, Object** start, |
| 5548 Object** end) { |
| 5549 if (!InNewSpace(object)) { |
| 5550 store_buffer()->MoveEntriesToRememberedSet(); |
| 5551 Address start_addr = reinterpret_cast<Address>(start); |
| 5552 Address end_addr = reinterpret_cast<Address>(end); |
| 5553 Page* page = Page::FromAddress(start_addr); |
| 5554 DCHECK_EQ(page->owner()->identity(), OLD_SPACE); |
| 5555 RememberedSet<OLD_TO_NEW>::RemoveRange(page, start_addr, end_addr); |
| 5556 } |
| 5557 } |
| 5558 |
5536 Space* AllSpaces::next() { | 5559 Space* AllSpaces::next() { |
5537 switch (counter_++) { | 5560 switch (counter_++) { |
5538 case NEW_SPACE: | 5561 case NEW_SPACE: |
5539 return heap_->new_space(); | 5562 return heap_->new_space(); |
5540 case OLD_SPACE: | 5563 case OLD_SPACE: |
5541 return heap_->old_space(); | 5564 return heap_->old_space(); |
5542 case CODE_SPACE: | 5565 case CODE_SPACE: |
5543 return heap_->code_space(); | 5566 return heap_->code_space(); |
5544 case MAP_SPACE: | 5567 case MAP_SPACE: |
5545 return heap_->map_space(); | 5568 return heap_->map_space(); |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6265 } | 6288 } |
6266 | 6289 |
6267 | 6290 |
6268 // static | 6291 // static |
6269 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6292 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6270 return StaticVisitorBase::GetVisitorId(map); | 6293 return StaticVisitorBase::GetVisitorId(map); |
6271 } | 6294 } |
6272 | 6295 |
6273 } // namespace internal | 6296 } // namespace internal |
6274 } // namespace v8 | 6297 } // namespace v8 |
OLD | NEW |