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/context-slot-cache.h" | 9 #include "src/ast/context-slot-cache.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 3077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3088 if (isolate()->heap_profiler()->is_sampling_allocations()) return false; | 3088 if (isolate()->heap_profiler()->is_sampling_allocations()) return false; |
3089 | 3089 |
3090 Address address = object->address(); | 3090 Address address = object->address(); |
3091 | 3091 |
3092 if (lo_space()->Contains(object)) return false; | 3092 if (lo_space()->Contains(object)) return false; |
3093 | 3093 |
3094 // We can move the object start if the page was already swept. | 3094 // We can move the object start if the page was already swept. |
3095 return Page::FromAddress(address)->SweepingDone(); | 3095 return Page::FromAddress(address)->SweepingDone(); |
3096 } | 3096 } |
3097 | 3097 |
3098 | 3098 void Heap::AdjustLiveBytes(HeapObject* object, int by) { |
3099 void Heap::AdjustLiveBytes(HeapObject* object, int by, InvocationMode mode) { | |
3100 // As long as the inspected object is black and we are currently not iterating | 3099 // As long as the inspected object is black and we are currently not iterating |
3101 // the heap using HeapIterator, we can update the live byte count. We cannot | 3100 // the heap using HeapIterator, we can update the live byte count. We cannot |
3102 // update while using HeapIterator because the iterator is temporarily | 3101 // update while using HeapIterator because the iterator is temporarily |
3103 // marking the whole object graph, without updating live bytes. | 3102 // marking the whole object graph, without updating live bytes. |
3104 if (lo_space()->Contains(object)) { | 3103 if (lo_space()->Contains(object)) { |
3105 lo_space()->AdjustLiveBytes(by); | 3104 lo_space()->AdjustLiveBytes(by); |
3106 } else if (!in_heap_iterator() && | 3105 } else if (!in_heap_iterator() && |
3107 !mark_compact_collector()->sweeping_in_progress() && | 3106 !mark_compact_collector()->sweeping_in_progress() && |
3108 Marking::IsBlack(ObjectMarking::MarkBitFrom(object->address()))) { | 3107 Marking::IsBlack(ObjectMarking::MarkBitFrom(object->address()))) { |
3109 if (mode == SEQUENTIAL_TO_SWEEPER) { | 3108 DCHECK(MemoryChunk::FromAddress(object->address())->SweepingDone()); |
3110 MemoryChunk::IncrementLiveBytesFromGC(object, by); | 3109 MemoryChunk::IncrementLiveBytes(object, by); |
3111 } else { | |
3112 MemoryChunk::IncrementLiveBytesFromMutator(object, by); | |
3113 } | |
3114 } | 3110 } |
3115 } | 3111 } |
3116 | 3112 |
3117 | 3113 |
3118 FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, | 3114 FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, |
3119 int elements_to_trim) { | 3115 int elements_to_trim) { |
3120 CHECK_NOT_NULL(object); | 3116 CHECK_NOT_NULL(object); |
3121 DCHECK(!object->IsFixedTypedArrayBase()); | 3117 DCHECK(!object->IsFixedTypedArrayBase()); |
3122 DCHECK(!object->IsByteArray()); | 3118 DCHECK(!object->IsByteArray()); |
3123 const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize; | 3119 const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3158 DCHECK(CanMoveObjectStart(object)); | 3154 DCHECK(CanMoveObjectStart(object)); |
3159 Object** former_start = HeapObject::RawField(object, 0); | 3155 Object** former_start = HeapObject::RawField(object, 0); |
3160 int new_start_index = elements_to_trim * (element_size / kPointerSize); | 3156 int new_start_index = elements_to_trim * (element_size / kPointerSize); |
3161 former_start[new_start_index] = map; | 3157 former_start[new_start_index] = map; |
3162 former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim); | 3158 former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim); |
3163 | 3159 |
3164 FixedArrayBase* new_object = | 3160 FixedArrayBase* new_object = |
3165 FixedArrayBase::cast(HeapObject::FromAddress(new_start)); | 3161 FixedArrayBase::cast(HeapObject::FromAddress(new_start)); |
3166 | 3162 |
3167 // Maintain consistency of live bytes during incremental marking | 3163 // Maintain consistency of live bytes during incremental marking |
3168 AdjustLiveBytes(new_object, -bytes_to_trim, Heap::CONCURRENT_TO_SWEEPER); | 3164 AdjustLiveBytes(new_object, -bytes_to_trim); |
3169 | 3165 |
3170 // Remove recorded slots for the new map and length offset. | 3166 // Remove recorded slots for the new map and length offset. |
3171 ClearRecordedSlot(new_object, HeapObject::RawField(new_object, 0)); | 3167 ClearRecordedSlot(new_object, HeapObject::RawField(new_object, 0)); |
3172 ClearRecordedSlot(new_object, HeapObject::RawField( | 3168 ClearRecordedSlot(new_object, HeapObject::RawField( |
3173 new_object, FixedArrayBase::kLengthOffset)); | 3169 new_object, FixedArrayBase::kLengthOffset)); |
3174 | 3170 |
3175 // Notify the heap profiler of change in object layout. | 3171 // Notify the heap profiler of change in object layout. |
3176 OnMoveEvent(new_object, object, new_object->Size()); | 3172 OnMoveEvent(new_object, object, new_object->Size()); |
3177 return new_object; | 3173 return new_object; |
3178 } | 3174 } |
3179 | 3175 |
3180 | |
3181 // Force instantiation of templatized method. | |
3182 template void Heap::RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>( | |
3183 FixedArrayBase*, int); | |
3184 template void Heap::RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( | |
3185 FixedArrayBase*, int); | |
3186 | |
3187 | |
3188 template<Heap::InvocationMode mode> | |
3189 void Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) { | 3176 void Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) { |
3190 const int len = object->length(); | 3177 const int len = object->length(); |
3191 DCHECK_LE(elements_to_trim, len); | 3178 DCHECK_LE(elements_to_trim, len); |
3192 DCHECK_GE(elements_to_trim, 0); | 3179 DCHECK_GE(elements_to_trim, 0); |
3193 | 3180 |
3194 int bytes_to_trim; | 3181 int bytes_to_trim; |
3195 if (object->IsFixedTypedArrayBase()) { | 3182 if (object->IsFixedTypedArrayBase()) { |
3196 InstanceType type = object->map()->instance_type(); | 3183 InstanceType type = object->map()->instance_type(); |
3197 bytes_to_trim = | 3184 bytes_to_trim = |
3198 FixedTypedArrayBase::TypedArraySize(type, len) - | 3185 FixedTypedArrayBase::TypedArraySize(type, len) - |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3231 if (!lo_space()->Contains(object)) { | 3218 if (!lo_space()->Contains(object)) { |
3232 CreateFillerObjectAt(new_end, bytes_to_trim, ClearRecordedSlots::kYes); | 3219 CreateFillerObjectAt(new_end, bytes_to_trim, ClearRecordedSlots::kYes); |
3233 } | 3220 } |
3234 | 3221 |
3235 // Initialize header of the trimmed array. We are storing the new length | 3222 // Initialize header of the trimmed array. We are storing the new length |
3236 // using release store after creating a filler for the left-over space to | 3223 // using release store after creating a filler for the left-over space to |
3237 // avoid races with the sweeper thread. | 3224 // avoid races with the sweeper thread. |
3238 object->synchronized_set_length(len - elements_to_trim); | 3225 object->synchronized_set_length(len - elements_to_trim); |
3239 | 3226 |
3240 // Maintain consistency of live bytes during incremental marking | 3227 // Maintain consistency of live bytes during incremental marking |
3241 AdjustLiveBytes(object, -bytes_to_trim, mode); | 3228 AdjustLiveBytes(object, -bytes_to_trim); |
3242 | 3229 |
3243 // Notify the heap profiler of change in object layout. The array may not be | 3230 // Notify the heap profiler of change in object layout. The array may not be |
3244 // moved during GC, and size has to be adjusted nevertheless. | 3231 // moved during GC, and size has to be adjusted nevertheless. |
3245 HeapProfiler* profiler = isolate()->heap_profiler(); | 3232 HeapProfiler* profiler = isolate()->heap_profiler(); |
3246 if (profiler->is_tracking_allocations()) { | 3233 if (profiler->is_tracking_allocations()) { |
3247 profiler->UpdateObjectSizeEvent(object->address(), object->Size()); | 3234 profiler->UpdateObjectSizeEvent(object->address(), object->Size()); |
3248 } | 3235 } |
3249 } | 3236 } |
3250 | 3237 |
3251 | 3238 |
(...skipping 3219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6471 } | 6458 } |
6472 | 6459 |
6473 | 6460 |
6474 // static | 6461 // static |
6475 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6462 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6476 return StaticVisitorBase::GetVisitorId(map); | 6463 return StaticVisitorBase::GetVisitorId(map); |
6477 } | 6464 } |
6478 | 6465 |
6479 } // namespace internal | 6466 } // namespace internal |
6480 } // namespace v8 | 6467 } // namespace v8 |
OLD | NEW |