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