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 |