Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(794)

Side by Side Diff: src/heap/heap.cc

Issue 2770253002: [heap] Enforce explicit MarkingState (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/array-buffer-tracker.cc ('k') | src/heap/incremental-marking.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/heap/array-buffer-tracker.cc ('k') | src/heap/incremental-marking.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698