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 3051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3062 reinterpret_cast<Map*>(root(kTwoPointerFillerMapRootIndex))); | 3062 reinterpret_cast<Map*>(root(kTwoPointerFillerMapRootIndex))); |
3063 } else { | 3063 } else { |
3064 DCHECK_GT(size, 2 * kPointerSize); | 3064 DCHECK_GT(size, 2 * kPointerSize); |
3065 filler->set_map_no_write_barrier( | 3065 filler->set_map_no_write_barrier( |
3066 reinterpret_cast<Map*>(root(kFreeSpaceMapRootIndex))); | 3066 reinterpret_cast<Map*>(root(kFreeSpaceMapRootIndex))); |
3067 FreeSpace::cast(filler)->nobarrier_set_size(size); | 3067 FreeSpace::cast(filler)->nobarrier_set_size(size); |
3068 } | 3068 } |
3069 if (mode == ClearRecordedSlots::kYes) { | 3069 if (mode == ClearRecordedSlots::kYes) { |
3070 ClearRecordedSlotRange(addr, addr + size); | 3070 ClearRecordedSlotRange(addr, addr + size); |
3071 } | 3071 } |
| 3072 |
| 3073 // If the location where the filler is created is within a black area we have |
| 3074 // to clear the mark bits of the filler space. |
| 3075 if (incremental_marking()->black_allocation() && |
| 3076 Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(addr))) { |
| 3077 Page* page = Page::FromAddress(addr); |
| 3078 page->markbits()->ClearRange(page->AddressToMarkbitIndex(addr), |
| 3079 page->AddressToMarkbitIndex(addr + size)); |
| 3080 } |
| 3081 |
3072 // At this point, we may be deserializing the heap from a snapshot, and | 3082 // At this point, we may be deserializing the heap from a snapshot, and |
3073 // none of the maps have been created yet and are NULL. | 3083 // none of the maps have been created yet and are NULL. |
3074 DCHECK((filler->map() == NULL && !deserialization_complete_) || | 3084 DCHECK((filler->map() == NULL && !deserialization_complete_) || |
3075 filler->map()->IsMap()); | 3085 filler->map()->IsMap()); |
3076 } | 3086 } |
3077 | 3087 |
3078 | 3088 |
3079 bool Heap::CanMoveObjectStart(HeapObject* object) { | 3089 bool Heap::CanMoveObjectStart(HeapObject* object) { |
3080 if (!FLAG_move_object_start) return false; | 3090 if (!FLAG_move_object_start) return false; |
3081 | 3091 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3134 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); | 3144 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); |
3135 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); | 3145 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); |
3136 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); | 3146 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); |
3137 | 3147 |
3138 const int len = object->length(); | 3148 const int len = object->length(); |
3139 DCHECK(elements_to_trim <= len); | 3149 DCHECK(elements_to_trim <= len); |
3140 | 3150 |
3141 // Calculate location of new array start. | 3151 // Calculate location of new array start. |
3142 Address new_start = object->address() + bytes_to_trim; | 3152 Address new_start = object->address() + bytes_to_trim; |
3143 | 3153 |
| 3154 // Transfer the mark bits to their new location. |
| 3155 IncrementalMarking::TransferMark(this, object->address(), new_start); |
| 3156 |
3144 // Technically in new space this write might be omitted (except for | 3157 // Technically in new space this write might be omitted (except for |
3145 // debug mode which iterates through the heap), but to play safer | 3158 // debug mode which iterates through the heap), but to play safer |
3146 // we still do it. | 3159 // we still do it. |
3147 CreateFillerObjectAt(object->address(), bytes_to_trim, | 3160 CreateFillerObjectAt(object->address(), bytes_to_trim, |
3148 ClearRecordedSlots::kYes); | 3161 ClearRecordedSlots::kYes); |
3149 // Initialize header of the trimmed array. Since left trimming is only | 3162 // Initialize header of the trimmed array. Since left trimming is only |
3150 // performed on pages which are not concurrently swept creating a filler | 3163 // performed on pages which are not concurrently swept creating a filler |
3151 // object does not require synchronization. | 3164 // object does not require synchronization. |
3152 DCHECK(CanMoveObjectStart(object)); | 3165 DCHECK(CanMoveObjectStart(object)); |
3153 Object** former_start = HeapObject::RawField(object, 0); | 3166 Object** former_start = HeapObject::RawField(object, 0); |
3154 int new_start_index = elements_to_trim * (element_size / kPointerSize); | 3167 int new_start_index = elements_to_trim * (element_size / kPointerSize); |
3155 former_start[new_start_index] = map; | 3168 former_start[new_start_index] = map; |
3156 former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim); | 3169 former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim); |
| 3170 |
3157 FixedArrayBase* new_object = | 3171 FixedArrayBase* new_object = |
3158 FixedArrayBase::cast(HeapObject::FromAddress(new_start)); | 3172 FixedArrayBase::cast(HeapObject::FromAddress(new_start)); |
3159 | 3173 |
| 3174 // Maintain consistency of live bytes during incremental marking |
| 3175 AdjustLiveBytes(new_object, -bytes_to_trim, Heap::CONCURRENT_TO_SWEEPER); |
| 3176 |
3160 // Remove recorded slots for the new map and length offset. | 3177 // Remove recorded slots for the new map and length offset. |
3161 ClearRecordedSlot(new_object, HeapObject::RawField(new_object, 0)); | 3178 ClearRecordedSlot(new_object, HeapObject::RawField(new_object, 0)); |
3162 ClearRecordedSlot(new_object, HeapObject::RawField( | 3179 ClearRecordedSlot(new_object, HeapObject::RawField( |
3163 new_object, FixedArrayBase::kLengthOffset)); | 3180 new_object, FixedArrayBase::kLengthOffset)); |
3164 | 3181 |
3165 // Maintain consistency of live bytes during incremental marking | |
3166 IncrementalMarking::TransferMark(this, object->address(), new_start); | |
3167 AdjustLiveBytes(new_object, -bytes_to_trim, Heap::CONCURRENT_TO_SWEEPER); | |
3168 | |
3169 // Notify the heap profiler of change in object layout. | 3182 // Notify the heap profiler of change in object layout. |
3170 OnMoveEvent(new_object, object, new_object->Size()); | 3183 OnMoveEvent(new_object, object, new_object->Size()); |
3171 return new_object; | 3184 return new_object; |
3172 } | 3185 } |
3173 | 3186 |
3174 | 3187 |
3175 // Force instantiation of templatized method. | 3188 // Force instantiation of templatized method. |
3176 template void Heap::RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>( | 3189 template void Heap::RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>( |
3177 FixedArrayBase*, int); | 3190 FixedArrayBase*, int); |
3178 template void Heap::RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( | 3191 template void Heap::RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( |
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4172 | 4185 |
4173 void Heap::RegisterReservationsForBlackAllocation(Reservation* reservations) { | 4186 void Heap::RegisterReservationsForBlackAllocation(Reservation* reservations) { |
4174 // TODO(hpayer): We do not have to iterate reservations on black objects | 4187 // TODO(hpayer): We do not have to iterate reservations on black objects |
4175 // for marking. We just have to execute the special visiting side effect | 4188 // for marking. We just have to execute the special visiting side effect |
4176 // code that adds objects to global data structures, e.g. for array buffers. | 4189 // code that adds objects to global data structures, e.g. for array buffers. |
4177 | 4190 |
4178 // Code space, map space, and large object space do not use black pages. | 4191 // Code space, map space, and large object space do not use black pages. |
4179 // Hence we have to color all objects of the reservation first black to avoid | 4192 // Hence we have to color all objects of the reservation first black to avoid |
4180 // unnecessary marking deque load. | 4193 // unnecessary marking deque load. |
4181 if (incremental_marking()->black_allocation()) { | 4194 if (incremental_marking()->black_allocation()) { |
4182 for (int i = CODE_SPACE; i < Serializer::kNumberOfSpaces; i++) { | 4195 for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) { |
4183 const Heap::Reservation& res = reservations[i]; | 4196 const Heap::Reservation& res = reservations[i]; |
4184 for (auto& chunk : res) { | 4197 for (auto& chunk : res) { |
4185 Address addr = chunk.start; | 4198 Address addr = chunk.start; |
4186 while (addr < chunk.end) { | 4199 while (addr < chunk.end) { |
4187 HeapObject* obj = HeapObject::FromAddress(addr); | 4200 HeapObject* obj = HeapObject::FromAddress(addr); |
4188 Marking::MarkBlack(ObjectMarking::MarkBitFrom(obj)); | 4201 Marking::MarkBlack(ObjectMarking::MarkBitFrom(obj)); |
4189 MemoryChunk::IncrementLiveBytesFromGC(obj, obj->Size()); | |
4190 addr += obj->Size(); | 4202 addr += obj->Size(); |
4191 } | 4203 } |
4192 } | 4204 } |
4193 } | 4205 } |
4194 for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) { | 4206 for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) { |
4195 const Heap::Reservation& res = reservations[i]; | 4207 const Heap::Reservation& res = reservations[i]; |
4196 for (auto& chunk : res) { | 4208 for (auto& chunk : res) { |
4197 Address addr = chunk.start; | 4209 Address addr = chunk.start; |
4198 while (addr < chunk.end) { | 4210 while (addr < chunk.end) { |
4199 HeapObject* obj = HeapObject::FromAddress(addr); | 4211 HeapObject* obj = HeapObject::FromAddress(addr); |
(...skipping 2240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6440 } | 6452 } |
6441 | 6453 |
6442 | 6454 |
6443 // static | 6455 // static |
6444 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6456 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6445 return StaticVisitorBase::GetVisitorId(map); | 6457 return StaticVisitorBase::GetVisitorId(map); |
6446 } | 6458 } |
6447 | 6459 |
6448 } // namespace internal | 6460 } // namespace internal |
6449 } // namespace v8 | 6461 } // namespace v8 |
OLD | NEW |