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/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 3047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3058 reinterpret_cast<Map*>(root(kFreeSpaceMapRootIndex))); | 3058 reinterpret_cast<Map*>(root(kFreeSpaceMapRootIndex))); |
3059 FreeSpace::cast(filler)->nobarrier_set_size(size); | 3059 FreeSpace::cast(filler)->nobarrier_set_size(size); |
3060 } | 3060 } |
3061 // At this point, we may be deserializing the heap from a snapshot, and | 3061 // At this point, we may be deserializing the heap from a snapshot, and |
3062 // none of the maps have been created yet and are NULL. | 3062 // none of the maps have been created yet and are NULL. |
3063 DCHECK((filler->map() == NULL && !deserialization_complete_) || | 3063 DCHECK((filler->map() == NULL && !deserialization_complete_) || |
3064 filler->map()->IsMap()); | 3064 filler->map()->IsMap()); |
3065 } | 3065 } |
3066 | 3066 |
3067 | 3067 |
3068 bool Heap::CanMoveObjectStart(HeapObject* object) { | |
3069 if (!FLAG_move_object_start) return false; | |
3070 | |
3071 Address address = object->address(); | |
3072 | |
3073 if (lo_space()->Contains(object)) return false; | |
3074 | |
3075 Page* page = Page::FromAddress(address); | |
3076 // We can move the object start if: | |
3077 // (1) the object is not in old space, | |
3078 // (2) the page of the object was already swept, | |
3079 // (3) the page was already concurrently swept. This case is an optimization | |
3080 // for concurrent sweeping. The WasSwept predicate for concurrently swept | |
3081 // pages is set after sweeping all pages. | |
3082 return !InOldSpace(address) || page->WasSwept() || page->SweepingCompleted(); | |
3083 } | |
3084 | |
3085 | |
3086 void Heap::AdjustLiveBytes(HeapObject* object, int by, InvocationMode mode) { | 3068 void Heap::AdjustLiveBytes(HeapObject* object, int by, InvocationMode mode) { |
3087 if (incremental_marking()->IsMarking() && | 3069 if (incremental_marking()->IsMarking() && |
3088 Marking::IsBlack(Marking::MarkBitFrom(object->address()))) { | 3070 Marking::IsBlack(Marking::MarkBitFrom(object->address()))) { |
3089 if (mode == SEQUENTIAL_TO_SWEEPER) { | 3071 if (mode == SEQUENTIAL_TO_SWEEPER) { |
3090 MemoryChunk::IncrementLiveBytesFromGC(object, by); | 3072 MemoryChunk::IncrementLiveBytesFromGC(object, by); |
3091 } else { | 3073 } else { |
3092 MemoryChunk::IncrementLiveBytesFromMutator(object, by); | 3074 MemoryChunk::IncrementLiveBytesFromMutator(object, by); |
3093 } | 3075 } |
3094 } | 3076 } |
3095 } | 3077 } |
3096 | 3078 |
3097 | 3079 |
3098 FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, | |
3099 int elements_to_trim) { | |
3100 DCHECK(!object->IsFixedTypedArrayBase()); | |
3101 const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize; | |
3102 const int bytes_to_trim = elements_to_trim * element_size; | |
3103 Map* map = object->map(); | |
3104 | |
3105 // For now this trick is only applied to objects in new and paged space. | |
3106 // In large object space the object's start must coincide with chunk | |
3107 // and thus the trick is just not applicable. | |
3108 DCHECK(!lo_space()->Contains(object)); | |
3109 DCHECK(object->map() != fixed_cow_array_map()); | |
3110 | |
3111 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); | |
3112 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); | |
3113 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); | |
3114 | |
3115 const int len = object->length(); | |
3116 DCHECK(elements_to_trim <= len); | |
3117 | |
3118 // Calculate location of new array start. | |
3119 Address new_start = object->address() + bytes_to_trim; | |
3120 | |
3121 // Technically in new space this write might be omitted (except for | |
3122 // debug mode which iterates through the heap), but to play safer | |
3123 // we still do it. | |
3124 CreateFillerObjectAt(object->address(), bytes_to_trim); | |
3125 | |
3126 // Initialize header of the trimmed array. Since left trimming is only | |
3127 // performed on pages which are not concurrently swept creating a filler | |
3128 // object does not require synchronization. | |
3129 DCHECK(CanMoveObjectStart(object)); | |
3130 Object** former_start = HeapObject::RawField(object, 0); | |
3131 int new_start_index = elements_to_trim * (element_size / kPointerSize); | |
3132 former_start[new_start_index] = map; | |
3133 former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim); | |
3134 FixedArrayBase* new_object = | |
3135 FixedArrayBase::cast(HeapObject::FromAddress(new_start)); | |
3136 | |
3137 // Maintain consistency of live bytes during incremental marking | |
3138 Marking::TransferMark(this, object->address(), new_start); | |
3139 AdjustLiveBytes(new_object, -bytes_to_trim, Heap::CONCURRENT_TO_SWEEPER); | |
3140 | |
3141 // Notify the heap profiler of change in object layout. | |
3142 OnMoveEvent(new_object, object, new_object->Size()); | |
3143 return new_object; | |
3144 } | |
3145 | |
3146 | |
3147 // Force instantiation of templatized method. | 3080 // Force instantiation of templatized method. |
3148 template void Heap::RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>( | 3081 template void Heap::RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>( |
3149 FixedArrayBase*, int); | 3082 FixedArrayBase*, int); |
3150 template void Heap::RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( | 3083 template void Heap::RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( |
3151 FixedArrayBase*, int); | 3084 FixedArrayBase*, int); |
3152 | 3085 |
3153 | 3086 |
3154 template<Heap::InvocationMode mode> | 3087 template<Heap::InvocationMode mode> |
3155 void Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) { | 3088 void Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) { |
3156 const int len = object->length(); | 3089 const int len = object->length(); |
(...skipping 3004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6161 } | 6094 } |
6162 | 6095 |
6163 | 6096 |
6164 // static | 6097 // static |
6165 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6098 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6166 return StaticVisitorBase::GetVisitorId(map); | 6099 return StaticVisitorBase::GetVisitorId(map); |
6167 } | 6100 } |
6168 | 6101 |
6169 } // namespace internal | 6102 } // namespace internal |
6170 } // namespace v8 | 6103 } // namespace v8 |
OLD | NEW |