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

Side by Side Diff: src/heap/incremental-marking.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/incremental-marking.h ('k') | src/heap/mark-compact.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/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/gc-idle-time-handler.h" 10 #include "src/heap/gc-idle-time-handler.h"
(...skipping 22 matching lines...) Expand all
33 was_activated_(false), 33 was_activated_(false),
34 black_allocation_(false), 34 black_allocation_(false),
35 finalize_marking_completed_(false), 35 finalize_marking_completed_(false),
36 trace_wrappers_toggle_(false), 36 trace_wrappers_toggle_(false),
37 request_type_(NONE), 37 request_type_(NONE),
38 new_generation_observer_(*this, kAllocatedThreshold), 38 new_generation_observer_(*this, kAllocatedThreshold),
39 old_generation_observer_(*this, kAllocatedThreshold) {} 39 old_generation_observer_(*this, kAllocatedThreshold) {}
40 40
41 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) { 41 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) {
42 HeapObject* value_heap_obj = HeapObject::cast(value); 42 HeapObject* value_heap_obj = HeapObject::cast(value);
43 DCHECK(!ObjectMarking::IsImpossible(value_heap_obj)); 43 DCHECK(!ObjectMarking::IsImpossible(value_heap_obj,
44 DCHECK(!ObjectMarking::IsImpossible(obj)); 44 MarkingState::Internal(value_heap_obj)));
45 const bool is_black = ObjectMarking::IsBlack(obj); 45 DCHECK(!ObjectMarking::IsImpossible(obj, MarkingState::Internal(obj)));
46 const bool is_black =
47 ObjectMarking::IsBlack(obj, MarkingState::Internal(obj));
46 48
47 if (is_black && ObjectMarking::IsWhite(value_heap_obj)) { 49 if (is_black && ObjectMarking::IsWhite(
50 value_heap_obj, MarkingState::Internal(value_heap_obj))) {
48 WhiteToGreyAndPush(value_heap_obj); 51 WhiteToGreyAndPush(value_heap_obj);
49 RestartIfNotMarking(); 52 RestartIfNotMarking();
50 } 53 }
51 return is_compacting_ && is_black; 54 return is_compacting_ && is_black;
52 } 55 }
53 56
54 57
55 void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot, 58 void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot,
56 Object* value) { 59 Object* value) {
57 if (BaseRecordWrite(obj, value) && slot != NULL) { 60 if (BaseRecordWrite(obj, value) && slot != NULL) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 113
111 void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo, 114 void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo,
112 Object* value) { 115 Object* value) {
113 if (BaseRecordWrite(host, value)) { 116 if (BaseRecordWrite(host, value)) {
114 // Object is not going to be rescanned. We need to record the slot. 117 // Object is not going to be rescanned. We need to record the slot.
115 heap_->mark_compact_collector()->RecordRelocSlot(host, rinfo, value); 118 heap_->mark_compact_collector()->RecordRelocSlot(host, rinfo, value);
116 } 119 }
117 } 120 }
118 121
119 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj) { 122 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj) {
120 ObjectMarking::WhiteToGrey(obj); 123 ObjectMarking::WhiteToGrey(obj, MarkingState::Internal(obj));
121 heap_->mark_compact_collector()->marking_deque()->Push(obj); 124 heap_->mark_compact_collector()->marking_deque()->Push(obj);
122 } 125 }
123 126
124 void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from, 127 void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from,
125 HeapObject* to) { 128 HeapObject* to) {
126 DCHECK(MemoryChunk::FromAddress(from->address())->SweepingDone()); 129 DCHECK(MemoryChunk::FromAddress(from->address())->SweepingDone());
127 // This is only used when resizing an object. 130 // This is only used when resizing an object.
128 DCHECK(MemoryChunk::FromAddress(from->address()) == 131 DCHECK(MemoryChunk::FromAddress(from->address()) ==
129 MemoryChunk::FromAddress(to->address())); 132 MemoryChunk::FromAddress(to->address()));
130 133
131 if (!heap->incremental_marking()->IsMarking()) return; 134 if (!heap->incremental_marking()->IsMarking()) return;
132 135
133 // If the mark doesn't move, we don't check the color of the object. 136 // If the mark doesn't move, we don't check the color of the object.
134 // It doesn't matter whether the object is black, since it hasn't changed 137 // It doesn't matter whether the object is black, since it hasn't changed
135 // size, so the adjustment to the live data count will be zero anyway. 138 // size, so the adjustment to the live data count will be zero anyway.
136 if (from == to) return; 139 if (from == to) return;
137 140
138 MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(to); 141 MarkBit new_mark_bit =
139 MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(from); 142 ObjectMarking::MarkBitFrom(to, MarkingState::Internal(to));
143 MarkBit old_mark_bit =
144 ObjectMarking::MarkBitFrom(from, MarkingState::Internal(from));
140 145
141 if (Marking::IsBlack(old_mark_bit)) { 146 if (Marking::IsBlack(old_mark_bit)) {
142 Marking::MarkBlack(new_mark_bit); 147 Marking::MarkBlack(new_mark_bit);
143 } else if (Marking::IsGrey(old_mark_bit)) { 148 } else if (Marking::IsGrey(old_mark_bit)) {
144 Marking::WhiteToGrey(new_mark_bit); 149 Marking::WhiteToGrey(new_mark_bit);
145 heap->mark_compact_collector()->marking_deque()->Push(to); 150 heap->mark_compact_collector()->marking_deque()->Push(to);
146 heap->incremental_marking()->RestartIfNotMarking(); 151 heap->incremental_marking()->RestartIfNotMarking();
147 } 152 }
148 } 153 }
149 154
(...skipping 28 matching lines...) Expand all
178 do { 183 do {
179 VisitPointers(heap, object, HeapObject::RawField(object, start_offset), 184 VisitPointers(heap, object, HeapObject::RawField(object, start_offset),
180 HeapObject::RawField(object, end_offset)); 185 HeapObject::RawField(object, end_offset));
181 start_offset = end_offset; 186 start_offset = end_offset;
182 end_offset = Min(object_size, end_offset + kProgressBarScanningChunk); 187 end_offset = Min(object_size, end_offset + kProgressBarScanningChunk);
183 scan_until_end = 188 scan_until_end =
184 heap->mark_compact_collector()->marking_deque()->IsFull(); 189 heap->mark_compact_collector()->marking_deque()->IsFull();
185 } while (scan_until_end && start_offset < object_size); 190 } while (scan_until_end && start_offset < object_size);
186 chunk->set_progress_bar(start_offset); 191 chunk->set_progress_bar(start_offset);
187 if (start_offset < object_size) { 192 if (start_offset < object_size) {
188 if (ObjectMarking::IsGrey(object)) { 193 if (ObjectMarking::IsGrey(object, MarkingState::Internal(object))) {
189 heap->mark_compact_collector()->marking_deque()->Unshift(object); 194 heap->mark_compact_collector()->marking_deque()->Unshift(object);
190 } else { 195 } else {
191 DCHECK(ObjectMarking::IsBlack(object)); 196 DCHECK(
197 ObjectMarking::IsBlack(object, MarkingState::Internal(object)));
192 heap->mark_compact_collector()->UnshiftBlack(object); 198 heap->mark_compact_collector()->UnshiftBlack(object);
193 } 199 }
194 heap->incremental_marking()->NotifyIncompleteScanOfObject( 200 heap->incremental_marking()->NotifyIncompleteScanOfObject(
195 object_size - (start_offset - already_scanned_offset)); 201 object_size - (start_offset - already_scanned_offset));
196 } 202 }
197 } else { 203 } else {
198 FixedArrayVisitor::Visit(map, object); 204 FixedArrayVisitor::Visit(map, object);
199 } 205 }
200 } 206 }
201 207
202 static void VisitNativeContextIncremental(Map* map, HeapObject* object) { 208 static void VisitNativeContextIncremental(Map* map, HeapObject* object) {
203 Context* context = Context::cast(object); 209 Context* context = Context::cast(object);
204 210
205 // We will mark cache black with a separate pass when we finish marking. 211 // We will mark cache black with a separate pass when we finish marking.
206 // Note that GC can happen when the context is not fully initialized, 212 // Note that GC can happen when the context is not fully initialized,
207 // so the cache can be undefined. 213 // so the cache can be undefined.
208 Object* cache = context->get(Context::NORMALIZED_MAP_CACHE_INDEX); 214 Object* cache = context->get(Context::NORMALIZED_MAP_CACHE_INDEX);
209 if (!cache->IsUndefined(map->GetIsolate())) { 215 if (!cache->IsUndefined(map->GetIsolate())) {
210 if (cache->IsHeapObject()) { 216 if (cache->IsHeapObject()) {
211 HeapObject* heap_obj = HeapObject::cast(cache); 217 HeapObject* heap_obj = HeapObject::cast(cache);
212 // Mark the object grey if it is white, do not enque it into the marking 218 // Mark the object grey if it is white, do not enque it into the marking
213 // deque. 219 // deque.
214 if (ObjectMarking::IsWhite(heap_obj)) { 220 if (ObjectMarking::IsWhite(heap_obj,
215 ObjectMarking::WhiteToGrey(heap_obj); 221 MarkingState::Internal(heap_obj))) {
222 ObjectMarking::WhiteToGrey(heap_obj,
223 MarkingState::Internal(heap_obj));
216 } 224 }
217 } 225 }
218 } 226 }
219 VisitNativeContext(map, context); 227 VisitNativeContext(map, context);
220 } 228 }
221 229
222 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { 230 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) {
223 Object* target = *p; 231 Object* target = *p;
224 if (target->IsHeapObject()) { 232 if (target->IsHeapObject()) {
225 heap->mark_compact_collector()->RecordSlot(object, p, target); 233 heap->mark_compact_collector()->RecordSlot(object, p, target);
(...skipping 14 matching lines...) Expand all
240 248
241 // Marks the object grey and pushes it on the marking stack. 249 // Marks the object grey and pushes it on the marking stack.
242 INLINE(static void MarkObject(Heap* heap, Object* obj)) { 250 INLINE(static void MarkObject(Heap* heap, Object* obj)) {
243 IncrementalMarking::MarkGrey(heap, HeapObject::cast(obj)); 251 IncrementalMarking::MarkGrey(heap, HeapObject::cast(obj));
244 } 252 }
245 253
246 // Marks the object black without pushing it on the marking stack. 254 // Marks the object black without pushing it on the marking stack.
247 // Returns true if object needed marking and false otherwise. 255 // Returns true if object needed marking and false otherwise.
248 INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { 256 INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) {
249 HeapObject* heap_object = HeapObject::cast(obj); 257 HeapObject* heap_object = HeapObject::cast(obj);
250 if (ObjectMarking::IsWhite(heap_object)) { 258 if (ObjectMarking::IsWhite(heap_object,
251 ObjectMarking::WhiteToBlack(heap_object); 259 MarkingState::Internal(heap_object))) {
260 ObjectMarking::WhiteToBlack(heap_object,
261 MarkingState::Internal(heap_object));
252 return true; 262 return true;
253 } 263 }
254 return false; 264 return false;
255 } 265 }
256 }; 266 };
257 267
258 void IncrementalMarking::IterateBlackObject(HeapObject* object) { 268 void IncrementalMarking::IterateBlackObject(HeapObject* object) {
259 if (IsMarking() && ObjectMarking::IsBlack(object)) { 269 if (IsMarking() &&
270 ObjectMarking::IsBlack(object, MarkingState::Internal(object))) {
260 Page* page = Page::FromAddress(object->address()); 271 Page* page = Page::FromAddress(object->address());
261 if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) { 272 if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) {
262 // IterateBlackObject requires us to visit the whole object. 273 // IterateBlackObject requires us to visit the whole object.
263 page->ResetProgressBar(); 274 page->ResetProgressBar();
264 } 275 }
265 Map* map = object->map(); 276 Map* map = object->map();
266 MarkGrey(heap_, map); 277 MarkGrey(heap_, map);
267 IncrementalMarkingMarkingVisitor::IterateBody(map, object); 278 IncrementalMarkingMarkingVisitor::IterateBody(map, object);
268 } 279 }
269 } 280 }
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 Object* weak_cell_obj = heap()->encountered_weak_cells(); 597 Object* weak_cell_obj = heap()->encountered_weak_cells();
587 Object* weak_cell_head = Smi::kZero; 598 Object* weak_cell_head = Smi::kZero;
588 WeakCell* prev_weak_cell_obj = NULL; 599 WeakCell* prev_weak_cell_obj = NULL;
589 while (weak_cell_obj != Smi::kZero) { 600 while (weak_cell_obj != Smi::kZero) {
590 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); 601 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj);
591 // We do not insert cleared weak cells into the list, so the value 602 // We do not insert cleared weak cells into the list, so the value
592 // cannot be a Smi here. 603 // cannot be a Smi here.
593 HeapObject* value = HeapObject::cast(weak_cell->value()); 604 HeapObject* value = HeapObject::cast(weak_cell->value());
594 // Remove weak cells with live objects from the list, they do not need 605 // Remove weak cells with live objects from the list, they do not need
595 // clearing. 606 // clearing.
596 if (ObjectMarking::IsBlackOrGrey(value)) { 607 if (ObjectMarking::IsBlackOrGrey(value, MarkingState::Internal(value))) {
597 // Record slot, if value is pointing to an evacuation candidate. 608 // Record slot, if value is pointing to an evacuation candidate.
598 Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); 609 Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset);
599 heap_->mark_compact_collector()->RecordSlot(weak_cell, slot, *slot); 610 heap_->mark_compact_collector()->RecordSlot(weak_cell, slot, *slot);
600 // Remove entry somewhere after top. 611 // Remove entry somewhere after top.
601 if (prev_weak_cell_obj != NULL) { 612 if (prev_weak_cell_obj != NULL) {
602 prev_weak_cell_obj->set_next(weak_cell->next()); 613 prev_weak_cell_obj->set_next(weak_cell->next());
603 } 614 }
604 weak_cell_obj = weak_cell->next(); 615 weak_cell_obj = weak_cell->next();
605 weak_cell->clear_next(the_hole_value); 616 weak_cell->clear_next(the_hole_value);
606 } else { 617 } else {
607 if (weak_cell_head == Smi::kZero) { 618 if (weak_cell_head == Smi::kZero) {
608 weak_cell_head = weak_cell; 619 weak_cell_head = weak_cell;
609 } 620 }
610 prev_weak_cell_obj = weak_cell; 621 prev_weak_cell_obj = weak_cell;
611 weak_cell_obj = weak_cell->next(); 622 weak_cell_obj = weak_cell->next();
612 } 623 }
613 } 624 }
614 // Top may have changed. 625 // Top may have changed.
615 heap()->set_encountered_weak_cells(weak_cell_head); 626 heap()->set_encountered_weak_cells(weak_cell_head);
616 } 627 }
617 628
618 629
619 bool ShouldRetainMap(Map* map, int age) { 630 bool ShouldRetainMap(Map* map, int age) {
620 if (age == 0) { 631 if (age == 0) {
621 // The map has aged. Do not retain this map. 632 // The map has aged. Do not retain this map.
622 return false; 633 return false;
623 } 634 }
624 Object* constructor = map->GetConstructor(); 635 Object* constructor = map->GetConstructor();
625 if (!constructor->IsHeapObject() || 636 if (!constructor->IsHeapObject() ||
626 ObjectMarking::IsWhite(HeapObject::cast(constructor))) { 637 ObjectMarking::IsWhite(
638 HeapObject::cast(constructor),
639 MarkingState::Internal(HeapObject::cast(constructor)))) {
627 // The constructor is dead, no new objects with this map can 640 // The constructor is dead, no new objects with this map can
628 // be created. Do not retain this map. 641 // be created. Do not retain this map.
629 return false; 642 return false;
630 } 643 }
631 return true; 644 return true;
632 } 645 }
633 646
634 647
635 void IncrementalMarking::RetainMaps() { 648 void IncrementalMarking::RetainMaps() {
636 // Do not retain dead maps if flag disables it or there is 649 // Do not retain dead maps if flag disables it or there is
637 // - memory pressure (reduce_memory_footprint_), 650 // - memory pressure (reduce_memory_footprint_),
638 // - GC is requested by tests or dev-tools (abort_incremental_marking_). 651 // - GC is requested by tests or dev-tools (abort_incremental_marking_).
639 bool map_retaining_is_disabled = heap()->ShouldReduceMemory() || 652 bool map_retaining_is_disabled = heap()->ShouldReduceMemory() ||
640 heap()->ShouldAbortIncrementalMarking() || 653 heap()->ShouldAbortIncrementalMarking() ||
641 FLAG_retain_maps_for_n_gc == 0; 654 FLAG_retain_maps_for_n_gc == 0;
642 ArrayList* retained_maps = heap()->retained_maps(); 655 ArrayList* retained_maps = heap()->retained_maps();
643 int length = retained_maps->Length(); 656 int length = retained_maps->Length();
644 // The number_of_disposed_maps separates maps in the retained_maps 657 // The number_of_disposed_maps separates maps in the retained_maps
645 // array that were created before and after context disposal. 658 // array that were created before and after context disposal.
646 // We do not age and retain disposed maps to avoid memory leaks. 659 // We do not age and retain disposed maps to avoid memory leaks.
647 int number_of_disposed_maps = heap()->number_of_disposed_maps_; 660 int number_of_disposed_maps = heap()->number_of_disposed_maps_;
648 for (int i = 0; i < length; i += 2) { 661 for (int i = 0; i < length; i += 2) {
649 DCHECK(retained_maps->Get(i)->IsWeakCell()); 662 DCHECK(retained_maps->Get(i)->IsWeakCell());
650 WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); 663 WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
651 if (cell->cleared()) continue; 664 if (cell->cleared()) continue;
652 int age = Smi::cast(retained_maps->Get(i + 1))->value(); 665 int age = Smi::cast(retained_maps->Get(i + 1))->value();
653 int new_age; 666 int new_age;
654 Map* map = Map::cast(cell->value()); 667 Map* map = Map::cast(cell->value());
655 if (i >= number_of_disposed_maps && !map_retaining_is_disabled && 668 if (i >= number_of_disposed_maps && !map_retaining_is_disabled &&
656 ObjectMarking::IsWhite(map)) { 669 ObjectMarking::IsWhite(map, MarkingState::Internal(map))) {
657 if (ShouldRetainMap(map, age)) { 670 if (ShouldRetainMap(map, age)) {
658 MarkGrey(heap(), map); 671 MarkGrey(heap(), map);
659 } 672 }
660 Object* prototype = map->prototype(); 673 Object* prototype = map->prototype();
661 if (age > 0 && prototype->IsHeapObject() && 674 if (age > 0 && prototype->IsHeapObject() &&
662 ObjectMarking::IsWhite(HeapObject::cast(prototype))) { 675 ObjectMarking::IsWhite(
676 HeapObject::cast(prototype),
677 MarkingState::Internal(HeapObject::cast(prototype)))) {
663 // The prototype is not marked, age the map. 678 // The prototype is not marked, age the map.
664 new_age = age - 1; 679 new_age = age - 1;
665 } else { 680 } else {
666 // The prototype and the constructor are marked, this map keeps only 681 // The prototype and the constructor are marked, this map keeps only
667 // transition tree alive, not JSObjects. Do not age the map. 682 // transition tree alive, not JSObjects. Do not age the map.
668 new_age = age; 683 new_age = age;
669 } 684 }
670 } else { 685 } else {
671 new_age = FLAG_retain_maps_for_n_gc; 686 new_age = FLAG_retain_maps_for_n_gc;
672 } 687 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 // Only pointers to from space have to be updated. 771 // Only pointers to from space have to be updated.
757 if (heap_->InFromSpace(obj)) { 772 if (heap_->InFromSpace(obj)) {
758 MapWord map_word = obj->map_word(); 773 MapWord map_word = obj->map_word();
759 // There may be objects on the marking deque that do not exist anymore, 774 // There may be objects on the marking deque that do not exist anymore,
760 // e.g. left trimmed objects or objects from the root set (frames). 775 // e.g. left trimmed objects or objects from the root set (frames).
761 // If these object are dead at scavenging time, their marking deque 776 // If these object are dead at scavenging time, their marking deque
762 // entries will not point to forwarding addresses. Hence, we can discard 777 // entries will not point to forwarding addresses. Hence, we can discard
763 // them. 778 // them.
764 if (map_word.IsForwardingAddress()) { 779 if (map_word.IsForwardingAddress()) {
765 HeapObject* dest = map_word.ToForwardingAddress(); 780 HeapObject* dest = map_word.ToForwardingAddress();
766 if (ObjectMarking::IsBlack(dest)) continue; 781 if (ObjectMarking::IsBlack(dest, MarkingState::Internal(dest)))
782 continue;
767 array[new_top] = dest; 783 array[new_top] = dest;
768 new_top = ((new_top + 1) & mask); 784 new_top = ((new_top + 1) & mask);
769 DCHECK(new_top != marking_deque->bottom()); 785 DCHECK(new_top != marking_deque->bottom());
770 DCHECK(ObjectMarking::IsGrey(obj) || 786 DCHECK(ObjectMarking::IsGrey(obj, MarkingState::Internal(obj)) ||
771 (obj->IsFiller() && ObjectMarking::IsWhite(obj))); 787 (obj->IsFiller() &&
788 ObjectMarking::IsWhite(obj, MarkingState::Internal(obj))));
772 } 789 }
773 } else if (obj->map() != filler_map) { 790 } else if (obj->map() != filler_map) {
774 // Skip one word filler objects that appear on the 791 // Skip one word filler objects that appear on the
775 // stack when we perform in place array shift. 792 // stack when we perform in place array shift.
776 array[new_top] = obj; 793 array[new_top] = obj;
777 new_top = ((new_top + 1) & mask); 794 new_top = ((new_top + 1) & mask);
778 DCHECK(new_top != marking_deque->bottom()); 795 DCHECK(new_top != marking_deque->bottom());
779 DCHECK(ObjectMarking::IsGrey(obj) || 796 DCHECK(ObjectMarking::IsGrey(obj, MarkingState::Internal(obj)) ||
780 (obj->IsFiller() && ObjectMarking::IsWhite(obj)) || 797 (obj->IsFiller() &&
798 ObjectMarking::IsWhite(obj, MarkingState::Internal(obj))) ||
781 (MemoryChunk::FromAddress(obj->address()) 799 (MemoryChunk::FromAddress(obj->address())
782 ->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && 800 ->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
783 ObjectMarking::IsBlack(obj))); 801 ObjectMarking::IsBlack(obj, MarkingState::Internal(obj))));
784 } 802 }
785 } 803 }
786 marking_deque->set_top(new_top); 804 marking_deque->set_top(new_top);
787 } 805 }
788 806
789 807
790 void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { 808 void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) {
791 MarkGrey(heap_, map); 809 MarkGrey(heap_, map);
792 810
793 IncrementalMarkingMarkingVisitor::IterateBody(map, obj); 811 IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
794 812
795 #if ENABLE_SLOW_DCHECKS 813 #if ENABLE_SLOW_DCHECKS
796 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); 814 MarkBit mark_bit =
815 ObjectMarking::MarkBitFrom(obj, MarkingState::Internal(obj));
797 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); 816 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
798 SLOW_DCHECK(Marking::IsGrey(mark_bit) || 817 SLOW_DCHECK(Marking::IsGrey(mark_bit) ||
799 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && 818 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
800 Marking::IsBlack(mark_bit))); 819 Marking::IsBlack(mark_bit)));
801 #endif 820 #endif
802 MarkBlack(obj, size); 821 MarkBlack(obj, size);
803 } 822 }
804 823
805 void IncrementalMarking::MarkGrey(Heap* heap, HeapObject* object) { 824 void IncrementalMarking::MarkGrey(Heap* heap, HeapObject* object) {
806 if (ObjectMarking::IsWhite(object)) { 825 if (ObjectMarking::IsWhite(object, MarkingState::Internal(object))) {
807 heap->incremental_marking()->WhiteToGreyAndPush(object); 826 heap->incremental_marking()->WhiteToGreyAndPush(object);
808 } 827 }
809 } 828 }
810 829
811 void IncrementalMarking::MarkBlack(HeapObject* obj, int size) { 830 void IncrementalMarking::MarkBlack(HeapObject* obj, int size) {
812 if (ObjectMarking::IsBlack(obj)) return; 831 if (ObjectMarking::IsBlack(obj, MarkingState::Internal(obj))) return;
813 ObjectMarking::GreyToBlack(obj); 832 ObjectMarking::GreyToBlack(obj, MarkingState::Internal(obj));
814 } 833 }
815 834
816 intptr_t IncrementalMarking::ProcessMarkingDeque( 835 intptr_t IncrementalMarking::ProcessMarkingDeque(
817 intptr_t bytes_to_process, ForceCompletionAction completion) { 836 intptr_t bytes_to_process, ForceCompletionAction completion) {
818 intptr_t bytes_processed = 0; 837 intptr_t bytes_processed = 0;
819 MarkingDeque* marking_deque = 838 MarkingDeque* marking_deque =
820 heap_->mark_compact_collector()->marking_deque(); 839 heap_->mark_compact_collector()->marking_deque();
821 while (!marking_deque->IsEmpty() && (bytes_processed < bytes_to_process || 840 while (!marking_deque->IsEmpty() && (bytes_processed < bytes_to_process ||
822 completion == FORCE_COMPLETION)) { 841 completion == FORCE_COMPLETION)) {
823 HeapObject* obj = marking_deque->Pop(); 842 HeapObject* obj = marking_deque->Pop();
824 843
825 // Left trimming may result in white, grey, or black filler objects on the 844 // Left trimming may result in white, grey, or black filler objects on the
826 // marking deque. Ignore these objects. 845 // marking deque. Ignore these objects.
827 if (obj->IsFiller()) { 846 if (obj->IsFiller()) {
828 DCHECK(!ObjectMarking::IsImpossible(obj)); 847 DCHECK(!ObjectMarking::IsImpossible(obj, MarkingState::Internal(obj)));
829 continue; 848 continue;
830 } 849 }
831 850
832 Map* map = obj->map(); 851 Map* map = obj->map();
833 int size = obj->SizeFromMap(map); 852 int size = obj->SizeFromMap(map);
834 unscanned_bytes_of_large_object_ = 0; 853 unscanned_bytes_of_large_object_ = 0;
835 VisitObject(map, obj, size); 854 VisitObject(map, obj, size);
836 bytes_processed += size - unscanned_bytes_of_large_object_; 855 bytes_processed += size - unscanned_bytes_of_large_object_;
837 } 856 }
838 // Report all found wrappers to the embedder. This is necessary as the 857 // Report all found wrappers to the embedder. This is necessary as the
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 } 892 }
874 } 893 }
875 894
876 Object* context = heap_->native_contexts_list(); 895 Object* context = heap_->native_contexts_list();
877 while (!context->IsUndefined(heap_->isolate())) { 896 while (!context->IsUndefined(heap_->isolate())) {
878 // GC can happen when the context is not fully initialized, 897 // GC can happen when the context is not fully initialized,
879 // so the cache can be undefined. 898 // so the cache can be undefined.
880 HeapObject* cache = HeapObject::cast( 899 HeapObject* cache = HeapObject::cast(
881 Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX)); 900 Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX));
882 if (!cache->IsUndefined(heap_->isolate())) { 901 if (!cache->IsUndefined(heap_->isolate())) {
883 if (ObjectMarking::IsGrey(cache)) { 902 if (ObjectMarking::IsGrey(cache, MarkingState::Internal(cache))) {
884 ObjectMarking::GreyToBlack(cache); 903 ObjectMarking::GreyToBlack(cache, MarkingState::Internal(cache));
885 } 904 }
886 } 905 }
887 context = Context::cast(context)->next_context_link(); 906 context = Context::cast(context)->next_context_link();
888 } 907 }
889 } 908 }
890 909
891 910
892 void IncrementalMarking::Stop() { 911 void IncrementalMarking::Stop() {
893 if (IsStopped()) return; 912 if (IsStopped()) return;
894 if (FLAG_trace_incremental_marking) { 913 if (FLAG_trace_incremental_marking) {
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 idle_marking_delay_counter_++; 1174 idle_marking_delay_counter_++;
1156 } 1175 }
1157 1176
1158 1177
1159 void IncrementalMarking::ClearIdleMarkingDelayCounter() { 1178 void IncrementalMarking::ClearIdleMarkingDelayCounter() {
1160 idle_marking_delay_counter_ = 0; 1179 idle_marking_delay_counter_ = 0;
1161 } 1180 }
1162 1181
1163 } // namespace internal 1182 } // namespace internal
1164 } // namespace v8 1183 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/incremental-marking.h ('k') | src/heap/mark-compact.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698