blob: 496e02d9550b16cc16c7110e99dd24d7253c89d3 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
10namespace v8 {
11namespace internal {
12
13
14bool 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
44void IncrementalMarking::RecordWrite(HeapObject* obj, Object** slot,
45 Object* value) {
46 if (IsMarking() && value->IsHeapObject()) {
47 RecordWriteSlow(obj, slot, value);
48 }
49}
50
51
52void IncrementalMarking::RecordWriteOfCodeEntry(JSFunction* host, Object** slot,
53 Code* value) {
54 if (IsMarking()) RecordWriteOfCodeEntrySlow(host, slot, value);
55}
56
57
58void IncrementalMarking::RecordWriteIntoCode(HeapObject* obj, RelocInfo* rinfo,
59 Object* value) {
60 if (IsMarking() && value->IsHeapObject()) {
61 RecordWriteIntoCodeSlow(obj, rinfo, value);
62 }
63}
64
65
66void 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
81void 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400106 heap_->mark_compact_collector()->marking_deque()->UnshiftGrey(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107}
108
109
110void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
111 Marking::WhiteToGrey(mark_bit);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400112 heap_->mark_compact_collector()->marking_deque()->PushGrey(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113}
114}
115} // namespace v8::internal
116
117#endif // V8_HEAP_INCREMENTAL_MARKING_INL_H_