| 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 |