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