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/assembler-inl.h" | 9 #include "src/assembler-inl.h" |
10 #include "src/ast/context-slot-cache.h" | 10 #include "src/ast/context-slot-cache.h" |
(...skipping 3146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3157 | 3157 |
3158 void Heap::AdjustLiveBytes(HeapObject* object, int by) { | 3158 void Heap::AdjustLiveBytes(HeapObject* object, int by) { |
3159 // As long as the inspected object is black and we are currently not iterating | 3159 // As long as the inspected object is black and we are currently not iterating |
3160 // the heap using HeapIterator, we can update the live byte count. We cannot | 3160 // the heap using HeapIterator, we can update the live byte count. We cannot |
3161 // update while using HeapIterator because the iterator is temporarily | 3161 // update while using HeapIterator because the iterator is temporarily |
3162 // marking the whole object graph, without updating live bytes. | 3162 // marking the whole object graph, without updating live bytes. |
3163 if (lo_space()->Contains(object)) { | 3163 if (lo_space()->Contains(object)) { |
3164 lo_space()->AdjustLiveBytes(by); | 3164 lo_space()->AdjustLiveBytes(by); |
3165 } else if (!in_heap_iterator() && | 3165 } else if (!in_heap_iterator() && |
3166 !mark_compact_collector()->sweeping_in_progress() && | 3166 !mark_compact_collector()->sweeping_in_progress() && |
3167 ObjectMarking::IsBlack(object)) { | 3167 ObjectMarking::IsBlack(object, MarkingState::Internal(object))) { |
3168 DCHECK(MemoryChunk::FromAddress(object->address())->SweepingDone()); | 3168 DCHECK(MemoryChunk::FromAddress(object->address())->SweepingDone()); |
3169 MemoryChunk::IncrementLiveBytes(object, by); | 3169 MarkingState::Internal(object).IncrementLiveBytes(by); |
3170 } | 3170 } |
3171 } | 3171 } |
3172 | 3172 |
3173 | 3173 |
3174 FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, | 3174 FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, |
3175 int elements_to_trim) { | 3175 int elements_to_trim) { |
3176 CHECK_NOT_NULL(object); | 3176 CHECK_NOT_NULL(object); |
3177 DCHECK(CanMoveObjectStart(object)); | 3177 DCHECK(CanMoveObjectStart(object)); |
3178 DCHECK(!object->IsFixedTypedArrayBase()); | 3178 DCHECK(!object->IsFixedTypedArrayBase()); |
3179 DCHECK(!object->IsByteArray()); | 3179 DCHECK(!object->IsByteArray()); |
(...skipping 14 matching lines...) Expand all Loading... |
3194 const int len = object->length(); | 3194 const int len = object->length(); |
3195 DCHECK(elements_to_trim <= len); | 3195 DCHECK(elements_to_trim <= len); |
3196 | 3196 |
3197 // Calculate location of new array start. | 3197 // Calculate location of new array start. |
3198 Address old_start = object->address(); | 3198 Address old_start = object->address(); |
3199 Address new_start = old_start + bytes_to_trim; | 3199 Address new_start = old_start + bytes_to_trim; |
3200 | 3200 |
3201 // Transfer the mark bits to their new location if the object is not within | 3201 // Transfer the mark bits to their new location if the object is not within |
3202 // a black area. | 3202 // a black area. |
3203 if (!incremental_marking()->black_allocation() || | 3203 if (!incremental_marking()->black_allocation() || |
3204 !Marking::IsBlack( | 3204 !Marking::IsBlack(ObjectMarking::MarkBitFrom( |
3205 ObjectMarking::MarkBitFrom(HeapObject::FromAddress(new_start)))) { | 3205 HeapObject::FromAddress(new_start), |
| 3206 MarkingState::Internal(HeapObject::FromAddress(new_start))))) { |
3206 IncrementalMarking::TransferMark(this, object, | 3207 IncrementalMarking::TransferMark(this, object, |
3207 HeapObject::FromAddress(new_start)); | 3208 HeapObject::FromAddress(new_start)); |
3208 } | 3209 } |
3209 | 3210 |
3210 // Technically in new space this write might be omitted (except for | 3211 // Technically in new space this write might be omitted (except for |
3211 // debug mode which iterates through the heap), but to play safer | 3212 // debug mode which iterates through the heap), but to play safer |
3212 // we still do it. | 3213 // we still do it. |
3213 CreateFillerObjectAt(old_start, bytes_to_trim, ClearRecordedSlots::kYes); | 3214 CreateFillerObjectAt(old_start, bytes_to_trim, ClearRecordedSlots::kYes); |
3214 | 3215 |
3215 // Initialize header of the trimmed array. Since left trimming is only | 3216 // Initialize header of the trimmed array. Since left trimming is only |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3278 // We do not create a filler for objects in large object space. | 3279 // We do not create a filler for objects in large object space. |
3279 // TODO(hpayer): We should shrink the large object page if the size | 3280 // TODO(hpayer): We should shrink the large object page if the size |
3280 // of the object changed significantly. | 3281 // of the object changed significantly. |
3281 if (!lo_space()->Contains(object)) { | 3282 if (!lo_space()->Contains(object)) { |
3282 HeapObject* filler = | 3283 HeapObject* filler = |
3283 CreateFillerObjectAt(new_end, bytes_to_trim, ClearRecordedSlots::kYes); | 3284 CreateFillerObjectAt(new_end, bytes_to_trim, ClearRecordedSlots::kYes); |
3284 DCHECK_NOT_NULL(filler); | 3285 DCHECK_NOT_NULL(filler); |
3285 // Clear the mark bits of the black area that belongs now to the filler. | 3286 // Clear the mark bits of the black area that belongs now to the filler. |
3286 // This is an optimization. The sweeper will release black fillers anyway. | 3287 // This is an optimization. The sweeper will release black fillers anyway. |
3287 if (incremental_marking()->black_allocation() && | 3288 if (incremental_marking()->black_allocation() && |
3288 ObjectMarking::IsBlackOrGrey(filler)) { | 3289 ObjectMarking::IsBlackOrGrey(filler, MarkingState::Internal(filler))) { |
3289 Page* page = Page::FromAddress(new_end); | 3290 Page* page = Page::FromAddress(new_end); |
3290 page->markbits()->ClearRange( | 3291 MarkingState::Internal(page).bitmap()->ClearRange( |
3291 page->AddressToMarkbitIndex(new_end), | 3292 page->AddressToMarkbitIndex(new_end), |
3292 page->AddressToMarkbitIndex(new_end + bytes_to_trim)); | 3293 page->AddressToMarkbitIndex(new_end + bytes_to_trim)); |
3293 } | 3294 } |
3294 } | 3295 } |
3295 | 3296 |
3296 // Initialize header of the trimmed array. We are storing the new length | 3297 // Initialize header of the trimmed array. We are storing the new length |
3297 // using release store after creating a filler for the left-over space to | 3298 // using release store after creating a filler for the left-over space to |
3298 // avoid races with the sweeper thread. | 3299 // avoid races with the sweeper thread. |
3299 object->synchronized_set_length(len - elements_to_trim); | 3300 object->synchronized_set_length(len - elements_to_trim); |
3300 | 3301 |
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4267 // Iterate black objects in old space, code space, map space, and large | 4268 // Iterate black objects in old space, code space, map space, and large |
4268 // object space for side effects. | 4269 // object space for side effects. |
4269 for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) { | 4270 for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) { |
4270 const Heap::Reservation& res = reservations[i]; | 4271 const Heap::Reservation& res = reservations[i]; |
4271 for (auto& chunk : res) { | 4272 for (auto& chunk : res) { |
4272 Address addr = chunk.start; | 4273 Address addr = chunk.start; |
4273 while (addr < chunk.end) { | 4274 while (addr < chunk.end) { |
4274 HeapObject* obj = HeapObject::FromAddress(addr); | 4275 HeapObject* obj = HeapObject::FromAddress(addr); |
4275 // There might be grey objects due to black to grey transitions in | 4276 // There might be grey objects due to black to grey transitions in |
4276 // incremental marking. E.g. see VisitNativeContextIncremental. | 4277 // incremental marking. E.g. see VisitNativeContextIncremental. |
4277 DCHECK(ObjectMarking::IsBlackOrGrey(obj)); | 4278 DCHECK( |
4278 if (ObjectMarking::IsBlack(obj)) { | 4279 ObjectMarking::IsBlackOrGrey(obj, MarkingState::Internal(obj))); |
| 4280 if (ObjectMarking::IsBlack(obj, MarkingState::Internal(obj))) { |
4279 incremental_marking()->IterateBlackObject(obj); | 4281 incremental_marking()->IterateBlackObject(obj); |
4280 } | 4282 } |
4281 addr += obj->Size(); | 4283 addr += obj->Size(); |
4282 } | 4284 } |
4283 } | 4285 } |
4284 } | 4286 } |
4285 } | 4287 } |
4286 } | 4288 } |
4287 | 4289 |
4288 void Heap::NotifyObjectLayoutChange(HeapObject* object, | 4290 void Heap::NotifyObjectLayoutChange(HeapObject* object, |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4866 void Heap::IterateAndScavengePromotedObject(HeapObject* target, int size, | 4868 void Heap::IterateAndScavengePromotedObject(HeapObject* target, int size, |
4867 bool was_marked_black) { | 4869 bool was_marked_black) { |
4868 // We are not collecting slots on new space objects during mutation | 4870 // We are not collecting slots on new space objects during mutation |
4869 // thus we have to scan for pointers to evacuation candidates when we | 4871 // thus we have to scan for pointers to evacuation candidates when we |
4870 // promote objects. But we should not record any slots in non-black | 4872 // promote objects. But we should not record any slots in non-black |
4871 // objects. Grey object's slots would be rescanned. | 4873 // objects. Grey object's slots would be rescanned. |
4872 // White object might not survive until the end of collection | 4874 // White object might not survive until the end of collection |
4873 // it would be a violation of the invariant to record it's slots. | 4875 // it would be a violation of the invariant to record it's slots. |
4874 bool record_slots = false; | 4876 bool record_slots = false; |
4875 if (incremental_marking()->IsCompacting()) { | 4877 if (incremental_marking()->IsCompacting()) { |
4876 record_slots = ObjectMarking::IsBlack(target); | 4878 record_slots = |
| 4879 ObjectMarking::IsBlack(target, MarkingState::Internal(target)); |
4877 } | 4880 } |
4878 | 4881 |
4879 IterateAndScavengePromotedObjectsVisitor visitor(this, target, record_slots); | 4882 IterateAndScavengePromotedObjectsVisitor visitor(this, target, record_slots); |
4880 if (target->IsJSFunction()) { | 4883 if (target->IsJSFunction()) { |
4881 // JSFunctions reachable through kNextFunctionLinkOffset are weak. Slots for | 4884 // JSFunctions reachable through kNextFunctionLinkOffset are weak. Slots for |
4882 // this links are recorded during processing of weak lists. | 4885 // this links are recorded during processing of weak lists. |
4883 JSFunction::BodyDescriptorWeakCode::IterateBody(target, size, &visitor); | 4886 JSFunction::BodyDescriptorWeakCode::IterateBody(target, size, &visitor); |
4884 } else { | 4887 } else { |
4885 target->IterateBody(target->map()->instance_type(), size, &visitor); | 4888 target->IterateBody(target->map()->instance_type(), size, &visitor); |
4886 } | 4889 } |
(...skipping 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6100 explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) { | 6103 explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) { |
6101 MarkReachableObjects(); | 6104 MarkReachableObjects(); |
6102 } | 6105 } |
6103 | 6106 |
6104 ~UnreachableObjectsFilter() { | 6107 ~UnreachableObjectsFilter() { |
6105 heap_->mark_compact_collector()->ClearMarkbits(); | 6108 heap_->mark_compact_collector()->ClearMarkbits(); |
6106 } | 6109 } |
6107 | 6110 |
6108 bool SkipObject(HeapObject* object) { | 6111 bool SkipObject(HeapObject* object) { |
6109 if (object->IsFiller()) return true; | 6112 if (object->IsFiller()) return true; |
6110 return ObjectMarking::IsWhite(object); | 6113 return ObjectMarking::IsWhite(object, MarkingState::Internal(object)); |
6111 } | 6114 } |
6112 | 6115 |
6113 private: | 6116 private: |
6114 class MarkingVisitor : public ObjectVisitor { | 6117 class MarkingVisitor : public ObjectVisitor { |
6115 public: | 6118 public: |
6116 MarkingVisitor() : marking_stack_(10) {} | 6119 MarkingVisitor() : marking_stack_(10) {} |
6117 | 6120 |
6118 void VisitPointers(Object** start, Object** end) override { | 6121 void VisitPointers(Object** start, Object** end) override { |
6119 for (Object** p = start; p < end; p++) { | 6122 for (Object** p = start; p < end; p++) { |
6120 if (!(*p)->IsHeapObject()) continue; | 6123 if (!(*p)->IsHeapObject()) continue; |
6121 HeapObject* obj = HeapObject::cast(*p); | 6124 HeapObject* obj = HeapObject::cast(*p); |
6122 // Use Marking instead of ObjectMarking to avoid adjusting live bytes | 6125 // Use Marking instead of ObjectMarking to avoid adjusting live bytes |
6123 // counter. | 6126 // counter. |
6124 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); | 6127 MarkBit mark_bit = |
| 6128 ObjectMarking::MarkBitFrom(obj, MarkingState::Internal(obj)); |
6125 if (Marking::IsWhite(mark_bit)) { | 6129 if (Marking::IsWhite(mark_bit)) { |
6126 Marking::WhiteToBlack(mark_bit); | 6130 Marking::WhiteToBlack(mark_bit); |
6127 marking_stack_.Add(obj); | 6131 marking_stack_.Add(obj); |
6128 } | 6132 } |
6129 } | 6133 } |
6130 } | 6134 } |
6131 | 6135 |
6132 void TransitiveClosure() { | 6136 void TransitiveClosure() { |
6133 while (!marking_stack_.is_empty()) { | 6137 while (!marking_stack_.is_empty()) { |
6134 HeapObject* obj = marking_stack_.RemoveLast(); | 6138 HeapObject* obj = marking_stack_.RemoveLast(); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6397 } | 6401 } |
6398 | 6402 |
6399 | 6403 |
6400 // static | 6404 // static |
6401 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6405 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6402 return StaticVisitorBase::GetVisitorId(map); | 6406 return StaticVisitorBase::GetVisitorId(map); |
6403 } | 6407 } |
6404 | 6408 |
6405 } // namespace internal | 6409 } // namespace internal |
6406 } // namespace v8 | 6410 } // namespace v8 |
OLD | NEW |