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
3 // found in the LICENSE file.
4
5 #ifndef V8_HEAP_INCREMENTAL_MARKING_INL_H_
6 #define V8_HEAP_INCREMENTAL_MARKING_INL_H_
7
8 #include "src/heap/incremental-marking.h"
9
10 namespace v8 {
11 namespace internal {
12
13
BaseRecordWrite(HeapObject * obj,Object ** slot,Object * value)14 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object** slot,
15 Object* value) {
16 HeapObject* value_heap_obj = HeapObject::cast(value);
17 MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj);
18 if (Marking::IsWhite(value_bit)) {
19 MarkBit obj_bit = Marking::MarkBitFrom(obj);
20 if (Marking::IsBlack(obj_bit)) {
21 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
22 if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) {
23 if (chunk->IsLeftOfProgressBar(slot)) {
24 WhiteToGreyAndPush(value_heap_obj, value_bit);
25 RestartIfNotMarking();
26 } else {
27 return false;
28 }
29 } else {
30 BlackToGreyAndUnshift(obj, obj_bit);
31 RestartIfNotMarking();
32 return false;
33 }
34 } else {
35 return false;
36 }
37 }
38 if (!is_compacting_) return false;
39 MarkBit obj_bit = Marking::MarkBitFrom(obj);
40 return Marking::IsBlack(obj_bit);
41 }
42
43
RecordWrite(HeapObject * obj,Object ** slot,Object * value)44 void IncrementalMarking::RecordWrite(HeapObject* obj, Object** slot,
45 Object* value) {
46 if (IsMarking() && value->IsHeapObject()) {
47 RecordWriteSlow(obj, slot, value);
48 }
49 }
50
51
RecordWriteOfCodeEntry(JSFunction * host,Object ** slot,Code * value)52 void IncrementalMarking::RecordWriteOfCodeEntry(JSFunction* host, Object** slot,
53 Code* value) {
54 if (IsMarking()) RecordWriteOfCodeEntrySlow(host, slot, value);
55 }
56
57
RecordWriteIntoCode(HeapObject * obj,RelocInfo * rinfo,Object * value)58 void IncrementalMarking::RecordWriteIntoCode(HeapObject* obj, RelocInfo* rinfo,
59 Object* value) {
60 if (IsMarking() && value->IsHeapObject()) {
61 RecordWriteIntoCodeSlow(obj, rinfo, value);
62 }
63 }
64
65
RecordWrites(HeapObject * obj)66 void IncrementalMarking::RecordWrites(HeapObject* obj) {
67 if (IsMarking()) {
68 MarkBit obj_bit = Marking::MarkBitFrom(obj);
69 if (Marking::IsBlack(obj_bit)) {
70 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
71 if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) {
72 chunk->set_progress_bar(0);
73 }
74 BlackToGreyAndUnshift(obj, obj_bit);
75 RestartIfNotMarking();
76 }
77 }
78 }
79
80
BlackToGreyAndUnshift(HeapObject * obj,MarkBit mark_bit)81 void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj,
82 MarkBit mark_bit) {
83 DCHECK(Marking::MarkBitFrom(obj) == mark_bit);
84 DCHECK(obj->Size() >= 2 * kPointerSize);
85 DCHECK(IsMarking());
86 Marking::BlackToGrey(mark_bit);
87 int obj_size = obj->Size();
88 MemoryChunk::IncrementLiveBytesFromGC(obj->address(), -obj_size);
89 bytes_scanned_ -= obj_size;
90 int64_t old_bytes_rescanned = bytes_rescanned_;
91 bytes_rescanned_ = old_bytes_rescanned + obj_size;
92 if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) {
93 if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSizeOfObjects()) {
94 // If we have queued twice the heap size for rescanning then we are
95 // going around in circles, scanning the same objects again and again
96 // as the program mutates the heap faster than we can incrementally
97 // trace it. In this case we switch to non-incremental marking in
98 // order to finish off this marking phase.
99 if (FLAG_trace_gc) {
100 PrintPID("Hurrying incremental marking because of lack of progress\n");
101 }
102 marking_speed_ = kMaxMarkingSpeed;
103 }
104 }
105
106 marking_deque_.UnshiftGrey(obj);
107 }
108
109
WhiteToGreyAndPush(HeapObject * obj,MarkBit mark_bit)110 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
111 Marking::WhiteToGrey(mark_bit);
112 marking_deque_.PushGrey(obj);
113 }
114 }
115 } // namespace v8::internal
116
117 #endif // V8_HEAP_INCREMENTAL_MARKING_INL_H_
118