incremental-marking-inl.h revision 3ef787dbeca8a5fb1086949cda830dccee07bfbd
1// Copyright 2011 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_INCREMENTAL_MARKING_INL_H_
29#define V8_INCREMENTAL_MARKING_INL_H_
30
31#include "incremental-marking.h"
32
33namespace v8 {
34namespace internal {
35
36
37bool IncrementalMarking::BaseRecordWrite(HeapObject* obj,
38                                         Object** slot,
39                                         Object* value) {
40  MarkBit value_bit = Marking::MarkBitFrom(HeapObject::cast(value));
41  if (Marking::IsWhite(value_bit)) {
42    MarkBit obj_bit = Marking::MarkBitFrom(obj);
43    if (Marking::IsBlack(obj_bit)) {
44      BlackToGreyAndUnshift(obj, obj_bit);
45      RestartIfNotMarking();
46    }
47
48    // Object is either grey or white.  It will be scanned if survives.
49    return false;
50  }
51  return true;
52}
53
54
55void IncrementalMarking::RecordWrite(HeapObject* obj,
56                                     Object** slot,
57                                     Object* value) {
58  if (IsMarking() && value->NonFailureIsHeapObject()) {
59    RecordWriteSlow(obj, slot, value);
60  }
61}
62
63
64void IncrementalMarking::RecordWriteOfCodeEntry(JSFunction* host,
65                                                Object** slot,
66                                                Code* value) {
67  if (IsMarking()) RecordWriteOfCodeEntrySlow(host, slot, value);
68}
69
70
71void IncrementalMarking::RecordWriteIntoCode(HeapObject* obj,
72                                             RelocInfo* rinfo,
73                                             Object* value) {
74  if (IsMarking() && value->NonFailureIsHeapObject()) {
75    RecordWriteIntoCodeSlow(obj, rinfo, value);
76  }
77}
78
79
80void IncrementalMarking::RecordWrites(HeapObject* obj) {
81  if (IsMarking()) {
82    MarkBit obj_bit = Marking::MarkBitFrom(obj);
83    if (Marking::IsBlack(obj_bit)) {
84      BlackToGreyAndUnshift(obj, obj_bit);
85      RestartIfNotMarking();
86    }
87  }
88}
89
90
91void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj,
92                                               MarkBit mark_bit) {
93  ASSERT(Marking::MarkBitFrom(obj) == mark_bit);
94  ASSERT(obj->Size() >= 2*kPointerSize);
95  ASSERT(IsMarking());
96  Marking::BlackToGrey(mark_bit);
97  int obj_size = obj->Size();
98  MemoryChunk::IncrementLiveBytesFromGC(obj->address(), -obj_size);
99  bytes_scanned_ -= obj_size;
100  int64_t old_bytes_rescanned = bytes_rescanned_;
101  bytes_rescanned_ = old_bytes_rescanned + obj_size;
102  if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) {
103    if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSize()) {
104      // If we have queued twice the heap size for rescanning then we are
105      // going around in circles, scanning the same objects again and again
106      // as the program mutates the heap faster than we can incrementally
107      // trace it.  In this case we switch to non-incremental marking in
108      // order to finish off this marking phase.
109      if (FLAG_trace_gc) {
110        PrintF("Hurrying incremental marking because of lack of progress\n");
111      }
112      allocation_marking_factor_ = kMaxAllocationMarkingFactor;
113    }
114  }
115
116  marking_deque_.UnshiftGrey(obj);
117}
118
119
120void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
121  WhiteToGrey(obj, mark_bit);
122  marking_deque_.PushGrey(obj);
123}
124
125
126void IncrementalMarking::WhiteToGrey(HeapObject* obj, MarkBit mark_bit) {
127  Marking::WhiteToGrey(mark_bit);
128}
129
130
131} }  // namespace v8::internal
132
133#endif  // V8_INCREMENTAL_MARKING_INL_H_
134