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

Side by Side Diff: src/heap/incremental-marking.cc

Issue 2857743002: [heap] Use atomic marking operations in incremental marking if (Closed)
Patch Set: Created 3 years, 7 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
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/incremental-marking.h" 5 #include "src/heap/incremental-marking.h"
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/compilation-cache.h" 8 #include "src/compilation-cache.h"
9 #include "src/conversions.h" 9 #include "src/conversions.h"
10 #include "src/heap/concurrent-marking.h" 10 #include "src/heap/concurrent-marking.h"
(...skipping 25 matching lines...) Expand all
36 was_activated_(false), 36 was_activated_(false),
37 black_allocation_(false), 37 black_allocation_(false),
38 finalize_marking_completed_(false), 38 finalize_marking_completed_(false),
39 trace_wrappers_toggle_(false), 39 trace_wrappers_toggle_(false),
40 request_type_(NONE), 40 request_type_(NONE),
41 new_generation_observer_(*this, kAllocatedThreshold), 41 new_generation_observer_(*this, kAllocatedThreshold),
42 old_generation_observer_(*this, kAllocatedThreshold) {} 42 old_generation_observer_(*this, kAllocatedThreshold) {}
43 43
44 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) { 44 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) {
45 HeapObject* value_heap_obj = HeapObject::cast(value); 45 HeapObject* value_heap_obj = HeapObject::cast(value);
46 DCHECK(!ObjectMarking::IsImpossible(value_heap_obj, 46 DCHECK(!ObjectMarking::IsImpossible<kAtomicity>(
47 marking_state(value_heap_obj))); 47 value_heap_obj, marking_state(value_heap_obj)));
48 DCHECK(!ObjectMarking::IsImpossible(obj, marking_state(obj))); 48 DCHECK(!ObjectMarking::IsImpossible<kAtomicity>(obj, marking_state(obj)));
Michael Lippautz 2017/05/03 07:49:51 Is IsImpossible safe for concurrent marking? I rem
ulan 2017/05/03 09:00:28 It is not safe indeed. I will remove bunch of dche
Hannes Payer (out of office) 2017/05/03 10:08:53 Is the current implementation of the check not cor
ulan 2017/05/03 12:09:30 In general IsImpossible can produce false positive
49 const bool is_black = ObjectMarking::IsBlack(obj, marking_state(obj)); 49 const bool is_black =
50 ObjectMarking::IsBlack<kAtomicity>(obj, marking_state(obj));
50 51
51 if (is_black && WhiteToGreyAndPush(value_heap_obj)) { 52 if (is_black && WhiteToGreyAndPush(value_heap_obj)) {
52 RestartIfNotMarking(); 53 RestartIfNotMarking();
53 } 54 }
54 return is_compacting_ && is_black; 55 return is_compacting_ && is_black;
55 } 56 }
56 57
57 58
58 void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot, 59 void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot,
59 Object* value) { 60 Object* value) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 114
114 void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo, 115 void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo,
115 Object* value) { 116 Object* value) {
116 if (BaseRecordWrite(host, value)) { 117 if (BaseRecordWrite(host, value)) {
117 // Object is not going to be rescanned. We need to record the slot. 118 // Object is not going to be rescanned. We need to record the slot.
118 heap_->mark_compact_collector()->RecordRelocSlot(host, rinfo, value); 119 heap_->mark_compact_collector()->RecordRelocSlot(host, rinfo, value);
119 } 120 }
120 } 121 }
121 122
122 bool IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj) { 123 bool IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj) {
123 if (ObjectMarking::WhiteToGrey(obj, marking_state(obj))) { 124 if (ObjectMarking::WhiteToGrey<kAtomicity>(obj, marking_state(obj))) {
124 marking_deque()->Push(obj); 125 marking_deque()->Push(obj);
125 return true; 126 return true;
126 } 127 }
127 return false; 128 return false;
128 } 129 }
129 130
130 void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from, 131 void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from,
131 HeapObject* to) { 132 HeapObject* to) {
132 DCHECK(MemoryChunk::FromAddress(from->address())->SweepingDone()); 133 DCHECK(MemoryChunk::FromAddress(from->address())->SweepingDone());
133 // This is only used when resizing an object. 134 // This is only used when resizing an object.
134 DCHECK(MemoryChunk::FromAddress(from->address()) == 135 DCHECK(MemoryChunk::FromAddress(from->address()) ==
135 MemoryChunk::FromAddress(to->address())); 136 MemoryChunk::FromAddress(to->address()));
136 137
137 if (!IsMarking()) return; 138 if (!IsMarking()) return;
138 139
139 // If the mark doesn't move, we don't check the color of the object. 140 // If the mark doesn't move, we don't check the color of the object.
140 // It doesn't matter whether the object is black, since it hasn't changed 141 // It doesn't matter whether the object is black, since it hasn't changed
141 // size, so the adjustment to the live data count will be zero anyway. 142 // size, so the adjustment to the live data count will be zero anyway.
142 if (from == to) return; 143 if (from == to) return;
143 144
144 MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(to, marking_state(to)); 145 MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(to, marking_state(to));
145 MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(from, marking_state(from)); 146 MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(from, marking_state(from));
146 147
147 if (Marking::IsBlack(old_mark_bit)) { 148 if (Marking::IsBlack<kAtomicity>(old_mark_bit)) {
148 bool success = Marking::WhiteToBlack(new_mark_bit); 149 bool success = Marking::WhiteToBlack<kAtomicity>(new_mark_bit);
149 DCHECK(success); 150 DCHECK(success);
150 USE(success); 151 USE(success);
151 } else if (Marking::IsGrey(old_mark_bit)) { 152 } else if (Marking::IsGrey<kAtomicity>(old_mark_bit)) {
152 bool success = Marking::WhiteToGrey(new_mark_bit); 153 bool success = Marking::WhiteToGrey<kAtomicity>(new_mark_bit);
153 DCHECK(success); 154 DCHECK(success);
154 USE(success); 155 USE(success);
155 marking_deque()->Push(to); 156 marking_deque()->Push(to);
156 RestartIfNotMarking(); 157 RestartIfNotMarking();
157 } 158 }
158 } 159 }
159 160
160 class IncrementalMarkingMarkingVisitor 161 class IncrementalMarkingMarkingVisitor
161 : public StaticMarkingVisitor<IncrementalMarkingMarkingVisitor> { 162 : public StaticMarkingVisitor<IncrementalMarkingMarkingVisitor> {
162 public: 163 public:
(...skipping 24 matching lines...) Expand all
187 bool scan_until_end = false; 188 bool scan_until_end = false;
188 do { 189 do {
189 VisitPointers(heap, object, HeapObject::RawField(object, start_offset), 190 VisitPointers(heap, object, HeapObject::RawField(object, start_offset),
190 HeapObject::RawField(object, end_offset)); 191 HeapObject::RawField(object, end_offset));
191 start_offset = end_offset; 192 start_offset = end_offset;
192 end_offset = Min(object_size, end_offset + kProgressBarScanningChunk); 193 end_offset = Min(object_size, end_offset + kProgressBarScanningChunk);
193 scan_until_end = heap->incremental_marking()->marking_deque()->IsFull(); 194 scan_until_end = heap->incremental_marking()->marking_deque()->IsFull();
194 } while (scan_until_end && start_offset < object_size); 195 } while (scan_until_end && start_offset < object_size);
195 chunk->set_progress_bar(start_offset); 196 chunk->set_progress_bar(start_offset);
196 if (start_offset < object_size) { 197 if (start_offset < object_size) {
197 if (ObjectMarking::IsGrey( 198 if (ObjectMarking::IsGrey<IncrementalMarking::kAtomicity>(
198 object, heap->incremental_marking()->marking_state(object))) { 199 object, heap->incremental_marking()->marking_state(object))) {
199 heap->incremental_marking()->marking_deque()->Unshift(object); 200 heap->incremental_marking()->marking_deque()->Unshift(object);
200 } else { 201 } else {
201 DCHECK(ObjectMarking::IsBlack( 202 DCHECK(ObjectMarking::IsBlack<IncrementalMarking::kAtomicity>(
202 object, heap->incremental_marking()->marking_state(object))); 203 object, heap->incremental_marking()->marking_state(object)));
203 heap->mark_compact_collector()->UnshiftBlack(object); 204 heap->mark_compact_collector()->UnshiftBlack(object);
204 } 205 }
205 heap->incremental_marking()->NotifyIncompleteScanOfObject( 206 heap->incremental_marking()->NotifyIncompleteScanOfObject(
206 object_size - (start_offset - already_scanned_offset)); 207 object_size - (start_offset - already_scanned_offset));
207 } 208 }
208 } else { 209 } else {
209 FixedArrayVisitor::Visit(map, object); 210 FixedArrayVisitor::Visit(map, object);
210 } 211 }
211 } 212 }
212 213
213 static void VisitNativeContextIncremental(Map* map, HeapObject* object) { 214 static void VisitNativeContextIncremental(Map* map, HeapObject* object) {
214 Context* context = Context::cast(object); 215 Context* context = Context::cast(object);
215 216
216 // We will mark cache black with a separate pass when we finish marking. 217 // We will mark cache black with a separate pass when we finish marking.
217 // Note that GC can happen when the context is not fully initialized, 218 // Note that GC can happen when the context is not fully initialized,
218 // so the cache can be undefined. 219 // so the cache can be undefined.
219 Object* cache = context->get(Context::NORMALIZED_MAP_CACHE_INDEX); 220 Object* cache = context->get(Context::NORMALIZED_MAP_CACHE_INDEX);
220 if (!cache->IsUndefined(map->GetIsolate())) { 221 if (!cache->IsUndefined(map->GetIsolate())) {
221 if (cache->IsHeapObject()) { 222 if (cache->IsHeapObject()) {
222 HeapObject* heap_obj = HeapObject::cast(cache); 223 HeapObject* heap_obj = HeapObject::cast(cache);
223 // Mark the object grey if it is white, do not enque it into the marking 224 // Mark the object grey if it is white, do not enque it into the marking
224 // deque. 225 // deque.
225 Heap* heap = map->GetHeap(); 226 Heap* heap = map->GetHeap();
226 bool ignored = ObjectMarking::WhiteToGrey( 227 bool ignored =
227 heap_obj, heap->incremental_marking()->marking_state(heap_obj)); 228 ObjectMarking::WhiteToGrey<IncrementalMarking::kAtomicity>(
229 heap_obj, heap->incremental_marking()->marking_state(heap_obj));
228 USE(ignored); 230 USE(ignored);
229 } 231 }
230 } 232 }
231 VisitNativeContext(map, context); 233 VisitNativeContext(map, context);
232 } 234 }
233 235
234 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { 236 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) {
235 Object* target = *p; 237 Object* target = *p;
236 if (target->IsHeapObject()) { 238 if (target->IsHeapObject()) {
237 heap->mark_compact_collector()->RecordSlot(object, p, target); 239 heap->mark_compact_collector()->RecordSlot(object, p, target);
(...skipping 14 matching lines...) Expand all
252 254
253 // Marks the object grey and pushes it on the marking stack. 255 // Marks the object grey and pushes it on the marking stack.
254 INLINE(static void MarkObject(Heap* heap, Object* obj)) { 256 INLINE(static void MarkObject(Heap* heap, Object* obj)) {
255 heap->incremental_marking()->WhiteToGreyAndPush(HeapObject::cast(obj)); 257 heap->incremental_marking()->WhiteToGreyAndPush(HeapObject::cast(obj));
256 } 258 }
257 259
258 // Marks the object black without pushing it on the marking stack. 260 // Marks the object black without pushing it on the marking stack.
259 // Returns true if object needed marking and false otherwise. 261 // Returns true if object needed marking and false otherwise.
260 INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { 262 INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) {
261 HeapObject* heap_object = HeapObject::cast(obj); 263 HeapObject* heap_object = HeapObject::cast(obj);
262 return ObjectMarking::WhiteToBlack( 264 return ObjectMarking::WhiteToBlack<IncrementalMarking::kAtomicity>(
263 heap_object, heap->incremental_marking()->marking_state(heap_object)); 265 heap_object, heap->incremental_marking()->marking_state(heap_object));
264 } 266 }
265 }; 267 };
266 268
267 void IncrementalMarking::IterateBlackObject(HeapObject* object) { 269 void IncrementalMarking::IterateBlackObject(HeapObject* object) {
268 if (IsMarking() && ObjectMarking::IsBlack(object, marking_state(object))) { 270 if (IsMarking() &&
271 ObjectMarking::IsBlack<kAtomicity>(object, marking_state(object))) {
269 Page* page = Page::FromAddress(object->address()); 272 Page* page = Page::FromAddress(object->address());
270 if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) { 273 if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) {
271 // IterateBlackObject requires us to visit the whole object. 274 // IterateBlackObject requires us to visit the whole object.
272 page->ResetProgressBar(); 275 page->ResetProgressBar();
273 } 276 }
274 Map* map = object->map(); 277 Map* map = object->map();
275 WhiteToGreyAndPush(map); 278 WhiteToGreyAndPush(map);
276 IncrementalMarkingMarkingVisitor::IterateBody(map, object); 279 IncrementalMarkingMarkingVisitor::IterateBody(map, object);
277 } 280 }
278 } 281 }
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 Object* weak_cell_obj = heap()->encountered_weak_cells(); 605 Object* weak_cell_obj = heap()->encountered_weak_cells();
603 Object* weak_cell_head = Smi::kZero; 606 Object* weak_cell_head = Smi::kZero;
604 WeakCell* prev_weak_cell_obj = NULL; 607 WeakCell* prev_weak_cell_obj = NULL;
605 while (weak_cell_obj != Smi::kZero) { 608 while (weak_cell_obj != Smi::kZero) {
606 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); 609 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj);
607 // We do not insert cleared weak cells into the list, so the value 610 // We do not insert cleared weak cells into the list, so the value
608 // cannot be a Smi here. 611 // cannot be a Smi here.
609 HeapObject* value = HeapObject::cast(weak_cell->value()); 612 HeapObject* value = HeapObject::cast(weak_cell->value());
610 // Remove weak cells with live objects from the list, they do not need 613 // Remove weak cells with live objects from the list, they do not need
611 // clearing. 614 // clearing.
612 if (ObjectMarking::IsBlackOrGrey(value, marking_state(value))) { 615 if (ObjectMarking::IsBlackOrGrey<kAtomicity>(value, marking_state(value))) {
613 // Record slot, if value is pointing to an evacuation candidate. 616 // Record slot, if value is pointing to an evacuation candidate.
614 Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); 617 Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset);
615 heap_->mark_compact_collector()->RecordSlot(weak_cell, slot, *slot); 618 heap_->mark_compact_collector()->RecordSlot(weak_cell, slot, *slot);
616 // Remove entry somewhere after top. 619 // Remove entry somewhere after top.
617 if (prev_weak_cell_obj != NULL) { 620 if (prev_weak_cell_obj != NULL) {
618 prev_weak_cell_obj->set_next(weak_cell->next()); 621 prev_weak_cell_obj->set_next(weak_cell->next());
619 } 622 }
620 weak_cell_obj = weak_cell->next(); 623 weak_cell_obj = weak_cell->next();
621 weak_cell->clear_next(the_hole_value); 624 weak_cell->clear_next(the_hole_value);
622 } else { 625 } else {
(...skipping 10 matching lines...) Expand all
633 636
634 637
635 bool ShouldRetainMap(Map* map, int age) { 638 bool ShouldRetainMap(Map* map, int age) {
636 if (age == 0) { 639 if (age == 0) {
637 // The map has aged. Do not retain this map. 640 // The map has aged. Do not retain this map.
638 return false; 641 return false;
639 } 642 }
640 Object* constructor = map->GetConstructor(); 643 Object* constructor = map->GetConstructor();
641 Heap* heap = map->GetHeap(); 644 Heap* heap = map->GetHeap();
642 if (!constructor->IsHeapObject() || 645 if (!constructor->IsHeapObject() ||
643 ObjectMarking::IsWhite(HeapObject::cast(constructor), 646 ObjectMarking::IsWhite<IncrementalMarking::kAtomicity>(
644 heap->incremental_marking()->marking_state( 647 HeapObject::cast(constructor),
645 HeapObject::cast(constructor)))) { 648 heap->incremental_marking()->marking_state(
649 HeapObject::cast(constructor)))) {
646 // The constructor is dead, no new objects with this map can 650 // The constructor is dead, no new objects with this map can
647 // be created. Do not retain this map. 651 // be created. Do not retain this map.
648 return false; 652 return false;
649 } 653 }
650 return true; 654 return true;
651 } 655 }
652 656
653 657
654 void IncrementalMarking::RetainMaps() { 658 void IncrementalMarking::RetainMaps() {
655 // Do not retain dead maps if flag disables it or there is 659 // Do not retain dead maps if flag disables it or there is
656 // - memory pressure (reduce_memory_footprint_), 660 // - memory pressure (reduce_memory_footprint_),
657 // - GC is requested by tests or dev-tools (abort_incremental_marking_). 661 // - GC is requested by tests or dev-tools (abort_incremental_marking_).
658 bool map_retaining_is_disabled = heap()->ShouldReduceMemory() || 662 bool map_retaining_is_disabled = heap()->ShouldReduceMemory() ||
659 heap()->ShouldAbortIncrementalMarking() || 663 heap()->ShouldAbortIncrementalMarking() ||
660 FLAG_retain_maps_for_n_gc == 0; 664 FLAG_retain_maps_for_n_gc == 0;
661 ArrayList* retained_maps = heap()->retained_maps(); 665 ArrayList* retained_maps = heap()->retained_maps();
662 int length = retained_maps->Length(); 666 int length = retained_maps->Length();
663 // The number_of_disposed_maps separates maps in the retained_maps 667 // The number_of_disposed_maps separates maps in the retained_maps
664 // array that were created before and after context disposal. 668 // array that were created before and after context disposal.
665 // We do not age and retain disposed maps to avoid memory leaks. 669 // We do not age and retain disposed maps to avoid memory leaks.
666 int number_of_disposed_maps = heap()->number_of_disposed_maps_; 670 int number_of_disposed_maps = heap()->number_of_disposed_maps_;
667 for (int i = 0; i < length; i += 2) { 671 for (int i = 0; i < length; i += 2) {
668 DCHECK(retained_maps->Get(i)->IsWeakCell()); 672 DCHECK(retained_maps->Get(i)->IsWeakCell());
669 WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); 673 WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
670 if (cell->cleared()) continue; 674 if (cell->cleared()) continue;
671 int age = Smi::cast(retained_maps->Get(i + 1))->value(); 675 int age = Smi::cast(retained_maps->Get(i + 1))->value();
672 int new_age; 676 int new_age;
673 Map* map = Map::cast(cell->value()); 677 Map* map = Map::cast(cell->value());
674 if (i >= number_of_disposed_maps && !map_retaining_is_disabled && 678 if (i >= number_of_disposed_maps && !map_retaining_is_disabled &&
675 ObjectMarking::IsWhite(map, marking_state(map))) { 679 ObjectMarking::IsWhite<kAtomicity>(map, marking_state(map))) {
676 if (ShouldRetainMap(map, age)) { 680 if (ShouldRetainMap(map, age)) {
677 WhiteToGreyAndPush(map); 681 WhiteToGreyAndPush(map);
678 } 682 }
679 Object* prototype = map->prototype(); 683 Object* prototype = map->prototype();
680 if (age > 0 && prototype->IsHeapObject() && 684 if (age > 0 && prototype->IsHeapObject() &&
681 ObjectMarking::IsWhite(HeapObject::cast(prototype), 685 ObjectMarking::IsWhite<kAtomicity>(
682 marking_state(HeapObject::cast(prototype)))) { 686 HeapObject::cast(prototype),
687 marking_state(HeapObject::cast(prototype)))) {
683 // The prototype is not marked, age the map. 688 // The prototype is not marked, age the map.
684 new_age = age - 1; 689 new_age = age - 1;
685 } else { 690 } else {
686 // The prototype and the constructor are marked, this map keeps only 691 // The prototype and the constructor are marked, this map keeps only
687 // transition tree alive, not JSObjects. Do not age the map. 692 // transition tree alive, not JSObjects. Do not age the map.
688 new_age = age; 693 new_age = age;
689 } 694 }
690 } else { 695 } else {
691 new_age = FLAG_retain_maps_for_n_gc; 696 new_age = FLAG_retain_maps_for_n_gc;
692 } 697 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 MapWord map_word = obj->map_word(); 768 MapWord map_word = obj->map_word();
764 if (!map_word.IsForwardingAddress()) { 769 if (!map_word.IsForwardingAddress()) {
765 // There may be objects on the marking deque that do not exist anymore, 770 // There may be objects on the marking deque that do not exist anymore,
766 // e.g. left trimmed objects or objects from the root set (frames). 771 // e.g. left trimmed objects or objects from the root set (frames).
767 // If these object are dead at scavenging time, their marking deque 772 // If these object are dead at scavenging time, their marking deque
768 // entries will not point to forwarding addresses. Hence, we can discard 773 // entries will not point to forwarding addresses. Hence, we can discard
769 // them. 774 // them.
770 return nullptr; 775 return nullptr;
771 } 776 }
772 HeapObject* dest = map_word.ToForwardingAddress(); 777 HeapObject* dest = map_word.ToForwardingAddress();
773 if (ObjectMarking::IsBlack(dest, marking_state(dest))) { 778 if (ObjectMarking::IsBlack<kAtomicity>(dest, marking_state(dest))) {
774 // The object is already processed by the marker. 779 // The object is already processed by the marker.
775 return nullptr; 780 return nullptr;
776 } 781 }
777 DCHECK( 782 DCHECK(ObjectMarking::IsGrey<kAtomicity>(obj, marking_state(obj)) ||
778 ObjectMarking::IsGrey(obj, marking_state(obj)) || 783 (obj->IsFiller() &&
779 (obj->IsFiller() && ObjectMarking::IsWhite(obj, marking_state(obj)))); 784 ObjectMarking::IsWhite<kAtomicity>(obj, marking_state(obj))));
780 return dest; 785 return dest;
781 } else { 786 } else {
782 DCHECK(ObjectMarking::IsGrey(obj, marking_state(obj)) || 787 DCHECK(ObjectMarking::IsGrey<kAtomicity>(obj, marking_state(obj)) ||
783 (obj->IsFiller() && 788 (obj->IsFiller() &&
784 ObjectMarking::IsWhite(obj, marking_state(obj))) || 789 ObjectMarking::IsWhite<kAtomicity>(obj, marking_state(obj))) ||
785 (MemoryChunk::FromAddress(obj->address()) 790 (MemoryChunk::FromAddress(obj->address())
786 ->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && 791 ->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
787 ObjectMarking::IsBlack(obj, marking_state(obj)))); 792 ObjectMarking::IsBlack<kAtomicity>(obj, marking_state(obj))));
788 // Skip one word filler objects that appear on the 793 // Skip one word filler objects that appear on the
789 // stack when we perform in place array shift. 794 // stack when we perform in place array shift.
790 return (obj->map() == filler_map) ? nullptr : obj; 795 return (obj->map() == filler_map) ? nullptr : obj;
791 } 796 }
792 }); 797 });
793 } 798 }
794 799
795 800
796 void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { 801 void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) {
797 WhiteToGreyAndPush(map); 802 WhiteToGreyAndPush(map);
798 803
799 IncrementalMarkingMarkingVisitor::IterateBody(map, obj); 804 IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
800 805
801 #if ENABLE_SLOW_DCHECKS 806 #if ENABLE_SLOW_DCHECKS
802 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj, marking_state(obj)); 807 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj, marking_state(obj));
803 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); 808 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
804 SLOW_DCHECK(Marking::IsGrey(mark_bit) || 809 SLOW_DCHECK(Marking::IsGrey<kAtomicity>(mark_bit) ||
805 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && 810 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
806 Marking::IsBlack(mark_bit))); 811 Marking::IsBlack<kAtomicity>(mark_bit)));
807 #endif 812 #endif
808 ObjectMarking::GreyToBlack(obj, marking_state(obj)); 813 ObjectMarking::GreyToBlack<kAtomicity>(obj, marking_state(obj));
809 } 814 }
810 815
811 intptr_t IncrementalMarking::ProcessMarkingDeque( 816 intptr_t IncrementalMarking::ProcessMarkingDeque(
812 intptr_t bytes_to_process, ForceCompletionAction completion) { 817 intptr_t bytes_to_process, ForceCompletionAction completion) {
813 intptr_t bytes_processed = 0; 818 intptr_t bytes_processed = 0;
814 while (!marking_deque()->IsEmpty() && (bytes_processed < bytes_to_process || 819 while (!marking_deque()->IsEmpty() && (bytes_processed < bytes_to_process ||
815 completion == FORCE_COMPLETION)) { 820 completion == FORCE_COMPLETION)) {
816 HeapObject* obj = marking_deque()->Pop(); 821 HeapObject* obj = marking_deque()->Pop();
817 822
818 // Left trimming may result in white, grey, or black filler objects on the 823 // Left trimming may result in white, grey, or black filler objects on the
819 // marking deque. Ignore these objects. 824 // marking deque. Ignore these objects.
820 if (obj->IsFiller()) { 825 if (obj->IsFiller()) {
821 DCHECK(!ObjectMarking::IsImpossible(obj, marking_state(obj))); 826 DCHECK(!ObjectMarking::IsImpossible<kAtomicity>(obj, marking_state(obj)));
822 continue; 827 continue;
823 } 828 }
824 829
825 Map* map = obj->map(); 830 Map* map = obj->map();
826 int size = obj->SizeFromMap(map); 831 int size = obj->SizeFromMap(map);
827 unscanned_bytes_of_large_object_ = 0; 832 unscanned_bytes_of_large_object_ = 0;
828 VisitObject(map, obj, size); 833 VisitObject(map, obj, size);
829 bytes_processed += size - unscanned_bytes_of_large_object_; 834 bytes_processed += size - unscanned_bytes_of_large_object_;
830 } 835 }
831 // Report all found wrappers to the embedder. This is necessary as the 836 // Report all found wrappers to the embedder. This is necessary as the
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 } 872 }
868 873
869 Object* context = heap_->native_contexts_list(); 874 Object* context = heap_->native_contexts_list();
870 while (!context->IsUndefined(heap_->isolate())) { 875 while (!context->IsUndefined(heap_->isolate())) {
871 // GC can happen when the context is not fully initialized, 876 // GC can happen when the context is not fully initialized,
872 // so the cache can be undefined. 877 // so the cache can be undefined.
873 HeapObject* cache = HeapObject::cast( 878 HeapObject* cache = HeapObject::cast(
874 Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX)); 879 Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX));
875 if (!cache->IsUndefined(heap_->isolate())) { 880 if (!cache->IsUndefined(heap_->isolate())) {
876 // Mark the cache black if it is grey. 881 // Mark the cache black if it is grey.
877 bool ignored = ObjectMarking::GreyToBlack(cache, marking_state(cache)); 882 bool ignored =
883 ObjectMarking::GreyToBlack<kAtomicity>(cache, marking_state(cache));
878 USE(ignored); 884 USE(ignored);
879 } 885 }
880 context = Context::cast(context)->next_context_link(); 886 context = Context::cast(context)->next_context_link();
881 } 887 }
882 } 888 }
883 889
884 890
885 void IncrementalMarking::Stop() { 891 void IncrementalMarking::Stop() {
886 if (IsStopped()) return; 892 if (IsStopped()) return;
887 if (FLAG_trace_incremental_marking) { 893 if (FLAG_trace_incremental_marking) {
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 idle_marking_delay_counter_++; 1154 idle_marking_delay_counter_++;
1149 } 1155 }
1150 1156
1151 1157
1152 void IncrementalMarking::ClearIdleMarkingDelayCounter() { 1158 void IncrementalMarking::ClearIdleMarkingDelayCounter() {
1153 idle_marking_delay_counter_ = 0; 1159 idle_marking_delay_counter_ = 0;
1154 } 1160 }
1155 1161
1156 } // namespace internal 1162 } // namespace internal
1157 } // namespace v8 1163 } // namespace v8
OLDNEW
« src/heap/incremental-marking.h ('K') | « src/heap/incremental-marking.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698