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/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-tracer.h" | 10 #include "src/heap/gc-tracer.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 write_barriers_invoked_since_last_step_(0), | 39 write_barriers_invoked_since_last_step_(0), |
40 idle_marking_delay_counter_(0), | 40 idle_marking_delay_counter_(0), |
41 no_marking_scope_depth_(0), | 41 no_marking_scope_depth_(0), |
42 unscanned_bytes_of_large_object_(0), | 42 unscanned_bytes_of_large_object_(0), |
43 was_activated_(false), | 43 was_activated_(false), |
44 weak_closure_was_overapproximated_(false), | 44 weak_closure_was_overapproximated_(false), |
45 weak_closure_approximation_rounds_(0), | 45 weak_closure_approximation_rounds_(0), |
46 request_type_(COMPLETE_MARKING) {} | 46 request_type_(COMPLETE_MARKING) {} |
47 | 47 |
48 | 48 |
| 49 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object** slot, |
| 50 Object* value) { |
| 51 HeapObject* value_heap_obj = HeapObject::cast(value); |
| 52 MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj); |
| 53 if (Marking::IsWhite(value_bit)) { |
| 54 MarkBit obj_bit = Marking::MarkBitFrom(obj); |
| 55 if (Marking::IsBlack(obj_bit)) { |
| 56 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
| 57 if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { |
| 58 if (chunk->IsLeftOfProgressBar(slot)) { |
| 59 WhiteToGreyAndPush(value_heap_obj, value_bit); |
| 60 RestartIfNotMarking(); |
| 61 } else { |
| 62 return false; |
| 63 } |
| 64 } else { |
| 65 BlackToGreyAndUnshift(obj, obj_bit); |
| 66 RestartIfNotMarking(); |
| 67 return false; |
| 68 } |
| 69 } else { |
| 70 return false; |
| 71 } |
| 72 } |
| 73 if (!is_compacting_) return false; |
| 74 MarkBit obj_bit = Marking::MarkBitFrom(obj); |
| 75 return Marking::IsBlack(obj_bit); |
| 76 } |
| 77 |
| 78 |
49 void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot, | 79 void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot, |
50 Object* value) { | 80 Object* value) { |
51 if (BaseRecordWrite(obj, slot, value) && slot != NULL) { | 81 if (BaseRecordWrite(obj, slot, value) && slot != NULL) { |
52 MarkBit obj_bit = Marking::MarkBitFrom(obj); | 82 MarkBit obj_bit = Marking::MarkBitFrom(obj); |
53 if (Marking::IsBlack(obj_bit)) { | 83 if (Marking::IsBlack(obj_bit)) { |
54 // Object is not going to be rescanned we need to record the slot. | 84 // Object is not going to be rescanned we need to record the slot. |
55 heap_->mark_compact_collector()->RecordSlot(obj, slot, value); | 85 heap_->mark_compact_collector()->RecordSlot(obj, slot, value); |
56 } | 86 } |
57 } | 87 } |
58 } | 88 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 MarkBit obj_bit = Marking::MarkBitFrom(obj); | 156 MarkBit obj_bit = Marking::MarkBitFrom(obj); |
127 if (Marking::IsBlack(obj_bit)) { | 157 if (Marking::IsBlack(obj_bit)) { |
128 // Object is not going to be rescanned. We need to record the slot. | 158 // Object is not going to be rescanned. We need to record the slot. |
129 heap_->mark_compact_collector()->RecordRelocSlot(rinfo, | 159 heap_->mark_compact_collector()->RecordRelocSlot(rinfo, |
130 Code::cast(value)); | 160 Code::cast(value)); |
131 } | 161 } |
132 } | 162 } |
133 } | 163 } |
134 | 164 |
135 | 165 |
| 166 void IncrementalMarking::RecordWrites(HeapObject* obj) { |
| 167 if (IsMarking()) { |
| 168 MarkBit obj_bit = Marking::MarkBitFrom(obj); |
| 169 if (Marking::IsBlack(obj_bit)) { |
| 170 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
| 171 if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { |
| 172 chunk->set_progress_bar(0); |
| 173 } |
| 174 BlackToGreyAndUnshift(obj, obj_bit); |
| 175 RestartIfNotMarking(); |
| 176 } |
| 177 } |
| 178 } |
| 179 |
| 180 |
| 181 void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj, |
| 182 MarkBit mark_bit) { |
| 183 DCHECK(Marking::MarkBitFrom(obj) == mark_bit); |
| 184 DCHECK(obj->Size() >= 2 * kPointerSize); |
| 185 DCHECK(IsMarking()); |
| 186 Marking::BlackToGrey(mark_bit); |
| 187 int obj_size = obj->Size(); |
| 188 MemoryChunk::IncrementLiveBytesFromGC(obj, -obj_size); |
| 189 bytes_scanned_ -= obj_size; |
| 190 int64_t old_bytes_rescanned = bytes_rescanned_; |
| 191 bytes_rescanned_ = old_bytes_rescanned + obj_size; |
| 192 if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) { |
| 193 if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSizeOfObjects()) { |
| 194 // If we have queued twice the heap size for rescanning then we are |
| 195 // going around in circles, scanning the same objects again and again |
| 196 // as the program mutates the heap faster than we can incrementally |
| 197 // trace it. In this case we switch to non-incremental marking in |
| 198 // order to finish off this marking phase. |
| 199 if (FLAG_trace_incremental_marking) { |
| 200 PrintIsolate( |
| 201 heap()->isolate(), |
| 202 "Hurrying incremental marking because of lack of progress\n"); |
| 203 } |
| 204 marking_speed_ = kMaxMarkingSpeed; |
| 205 } |
| 206 } |
| 207 |
| 208 heap_->mark_compact_collector()->marking_deque()->Unshift(obj); |
| 209 } |
| 210 |
| 211 |
| 212 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { |
| 213 Marking::WhiteToGrey(mark_bit); |
| 214 heap_->mark_compact_collector()->marking_deque()->Push(obj); |
| 215 } |
| 216 |
| 217 |
136 static void MarkObjectGreyDoNotEnqueue(Object* obj) { | 218 static void MarkObjectGreyDoNotEnqueue(Object* obj) { |
137 if (obj->IsHeapObject()) { | 219 if (obj->IsHeapObject()) { |
138 HeapObject* heap_obj = HeapObject::cast(obj); | 220 HeapObject* heap_obj = HeapObject::cast(obj); |
139 MarkBit mark_bit = Marking::MarkBitFrom(HeapObject::cast(obj)); | 221 MarkBit mark_bit = Marking::MarkBitFrom(HeapObject::cast(obj)); |
140 if (Marking::IsBlack(mark_bit)) { | 222 if (Marking::IsBlack(mark_bit)) { |
141 MemoryChunk::IncrementLiveBytesFromGC(heap_obj, -heap_obj->Size()); | 223 MemoryChunk::IncrementLiveBytesFromGC(heap_obj, -heap_obj->Size()); |
142 } | 224 } |
143 Marking::AnyToGrey(mark_bit); | 225 Marking::AnyToGrey(mark_bit); |
144 } | 226 } |
145 } | 227 } |
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { | 1099 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { |
1018 idle_marking_delay_counter_++; | 1100 idle_marking_delay_counter_++; |
1019 } | 1101 } |
1020 | 1102 |
1021 | 1103 |
1022 void IncrementalMarking::ClearIdleMarkingDelayCounter() { | 1104 void IncrementalMarking::ClearIdleMarkingDelayCounter() { |
1023 idle_marking_delay_counter_ = 0; | 1105 idle_marking_delay_counter_ = 0; |
1024 } | 1106 } |
1025 } // namespace internal | 1107 } // namespace internal |
1026 } // namespace v8 | 1108 } // namespace v8 |
OLD | NEW |