v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
incremental-marking.h
Go to the documentation of this file.
1 // Copyright 2012 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_H_
29 #define V8_INCREMENTAL_MARKING_H_
30 
31 
32 #include "execution.h"
33 #include "mark-compact.h"
34 #include "objects.h"
35 
36 namespace v8 {
37 namespace internal {
38 
39 
41  public:
42  enum State {
47  };
48 
52  };
53 
54  explicit IncrementalMarking(Heap* heap);
55 
56  void TearDown();
57 
59  ASSERT(state_ == STOPPED || FLAG_incremental_marking);
60  return state_;
61  }
62 
63  bool should_hurry() { return should_hurry_; }
64  void set_should_hurry(bool val) { should_hurry_ = val; }
65 
66  inline bool IsStopped() { return state() == STOPPED; }
67 
68  INLINE(bool IsMarking()) { return state() >= MARKING; }
69 
70  inline bool IsMarkingIncomplete() { return state() == MARKING; }
71 
72  inline bool IsComplete() { return state() == COMPLETE; }
73 
74  bool WorthActivating();
75 
76  void Start();
77 
78  void Stop();
79 
80  void PrepareForScavenge();
81 
83 
84  void Hurry();
85 
86  void Finalize();
87 
88  void Abort();
89 
90  void MarkingComplete(CompletionAction action);
91 
92  // It's hard to know how much work the incremental marker should do to make
93  // progress in the face of the mutator creating new work for it. We start
94  // of at a moderate rate of work and gradually increase the speed of the
95  // incremental marker until it completes.
96  // Do some marking every time this much memory has been allocated.
97  static const intptr_t kAllocatedThreshold = 65536;
98  // Start off by marking this many times more memory than has been allocated.
99  static const intptr_t kInitialAllocationMarkingFactor = 1;
100  // But if we are promoting a lot of data we need to mark faster to keep up
101  // with the data that is entering the old space through promotion.
102  static const intptr_t kFastMarking = 3;
103  // After this many steps we increase the marking/allocating factor.
104  static const intptr_t kAllocationMarkingFactorSpeedupInterval = 1024;
105  // This is how much we increase the marking/allocating factor by.
106  static const intptr_t kAllocationMarkingFactorSpeedup = 2;
107  static const intptr_t kMaxAllocationMarkingFactor = 1000;
108 
109  void OldSpaceStep(intptr_t allocated) {
112  }
113 
114  void Step(intptr_t allocated, CompletionAction action);
115 
116  inline void RestartIfNotMarking() {
117  if (state_ == COMPLETE) {
118  state_ = MARKING;
119  if (FLAG_trace_incremental_marking) {
120  PrintF("[IncrementalMarking] Restarting (new grey objects)\n");
121  }
122  }
123  }
124 
125  static void RecordWriteFromCode(HeapObject* obj,
126  Object* value,
127  Isolate* isolate);
128 
130  Object** slot,
131  Isolate* isolate);
132 
133  INLINE(bool BaseRecordWrite(HeapObject* obj, Object** slot, Object* value));
134  INLINE(void RecordWrite(HeapObject* obj, Object** slot, Object* value));
135  INLINE(void RecordWriteIntoCode(HeapObject* obj,
136  RelocInfo* rinfo,
137  Object* value));
138  INLINE(void RecordWriteOfCodeEntry(JSFunction* host,
139  Object** slot,
140  Code* value));
141 
142 
143  void RecordWriteSlow(HeapObject* obj, Object** slot, Object* value);
145  RelocInfo* rinfo,
146  Object* value);
147  void RecordWriteOfCodeEntrySlow(JSFunction* host, Object** slot, Code* value);
148  void RecordCodeTargetPatch(Code* host, Address pc, HeapObject* value);
150 
151  inline void RecordWrites(HeapObject* obj);
152 
153  inline void BlackToGreyAndUnshift(HeapObject* obj, MarkBit mark_bit);
154 
155  inline void WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit);
156 
157  // Does white->black or keeps gray or black color. Returns true if converting
158  // white to black.
159  inline bool MarkBlackOrKeepGrey(MarkBit mark_bit) {
160  ASSERT(!Marking::IsImpossible(mark_bit));
161  if (mark_bit.Get()) {
162  // Grey or black: Keep the color.
163  return false;
164  }
165  mark_bit.Set();
166  ASSERT(Marking::IsBlack(mark_bit));
167  return true;
168  }
169 
170  // Marks the object grey and pushes it on the marking stack.
171  // Returns true if object needed marking and false otherwise.
172  // This is for incremental marking only.
173  INLINE(bool MarkObjectAndPush(HeapObject* obj));
174 
175  // Marks the object black without pushing it on the marking stack.
176  // Returns true if object needed marking and false otherwise.
177  // This is for incremental marking only.
178  INLINE(bool MarkObjectWithoutPush(HeapObject* obj));
179 
180  inline int steps_count() {
181  return steps_count_;
182  }
183 
184  inline double steps_took() {
185  return steps_took_;
186  }
187 
188  inline double longest_step() {
189  return longest_step_;
190  }
191 
193  return steps_count_since_last_gc_;
194  }
195 
196  inline double steps_took_since_last_gc() {
197  return steps_took_since_last_gc_;
198  }
199 
200  inline void SetOldSpacePageFlags(MemoryChunk* chunk) {
201  SetOldSpacePageFlags(chunk, IsMarking(), IsCompacting());
202  }
203 
204  inline void SetNewSpacePageFlags(NewSpacePage* chunk) {
205  SetNewSpacePageFlags(chunk, IsMarking());
206  }
207 
208  MarkingDeque* marking_deque() { return &marking_deque_; }
209 
210  bool IsCompacting() { return IsMarking() && is_compacting_; }
211 
212  void ActivateGeneratedStub(Code* stub);
213 
215  if (IsMarking()) {
216  if (allocation_marking_factor_ < kFastMarking) {
217  if (FLAG_trace_gc) {
218  PrintF("Increasing marking speed to %d due to high promotion rate\n",
219  static_cast<int>(kFastMarking));
220  }
221  allocation_marking_factor_ = kFastMarking;
222  }
223  }
224  }
225 
227  no_marking_scope_depth_++;
228  }
229 
231  no_marking_scope_depth_--;
232  }
233 
234  void UncommitMarkingDeque();
235 
236  private:
237  int64_t SpaceLeftInOldSpace();
238 
239  void ResetStepCounters();
240 
241  enum CompactionFlag { ALLOW_COMPACTION, PREVENT_COMPACTION };
242 
243  void StartMarking(CompactionFlag flag);
244 
245  void ActivateIncrementalWriteBarrier(PagedSpace* space);
246  static void ActivateIncrementalWriteBarrier(NewSpace* space);
247  void ActivateIncrementalWriteBarrier();
248 
249  static void DeactivateIncrementalWriteBarrierForSpace(PagedSpace* space);
250  static void DeactivateIncrementalWriteBarrierForSpace(NewSpace* space);
251  void DeactivateIncrementalWriteBarrier();
252 
253  static void SetOldSpacePageFlags(MemoryChunk* chunk,
254  bool is_marking,
255  bool is_compacting);
256 
257  static void SetNewSpacePageFlags(NewSpacePage* chunk, bool is_marking);
258 
259  void EnsureMarkingDequeIsCommitted();
260 
261  void VisitGlobalContext(Context* ctx, ObjectVisitor* v);
262 
263  Heap* heap_;
264 
265  State state_;
266  bool is_compacting_;
267 
268  VirtualMemory* marking_deque_memory_;
269  bool marking_deque_memory_committed_;
270  MarkingDeque marking_deque_;
271  Marker<IncrementalMarking> marker_;
272 
273  int steps_count_;
274  double steps_took_;
275  double longest_step_;
276  int64_t old_generation_space_available_at_start_of_incremental_;
277  int64_t old_generation_space_used_at_start_of_incremental_;
278  int steps_count_since_last_gc_;
279  double steps_took_since_last_gc_;
280  int64_t bytes_rescanned_;
281  bool should_hurry_;
282  int allocation_marking_factor_;
283  intptr_t bytes_scanned_;
284  intptr_t allocated_;
285 
286  int no_marking_scope_depth_;
287 
288  DISALLOW_IMPLICIT_CONSTRUCTORS(IncrementalMarking);
289 };
290 
291 } } // namespace v8::internal
292 
293 #endif // V8_INCREMENTAL_MARKING_H_
static bool IsBlack(MarkBit mark_bit)
Definition: mark-compact.h:70
byte * Address
Definition: globals.h:172
void PrintF(const char *format,...)
Definition: v8utils.cc:40
void SetNewSpacePageFlags(NewSpacePage *chunk)
static void RecordWriteForEvacuationFromCode(HeapObject *obj, Object **slot, Isolate *isolate)
#define ASSERT(condition)
Definition: checks.h:270
void RecordWriteIntoCodeSlow(HeapObject *obj, RelocInfo *rinfo, Object *value)
void Step(intptr_t allocated, CompletionAction action)
void RecordCodeTargetPatch(Code *host, Address pc, HeapObject *value)
static void RecordWriteFromCode(HeapObject *obj, Object *value, Isolate *isolate)
void MarkingComplete(CompletionAction action)
void RecordWriteOfCodeEntrySlow(JSFunction *host, Object **slot, Code *value)
const Register pc
static const intptr_t kInitialAllocationMarkingFactor
static bool IsImpossible(MarkBit mark_bit)
Definition: mark-compact.h:64
void SetOldSpacePageFlags(MemoryChunk *chunk)
void WhiteToGreyAndPush(HeapObject *obj, MarkBit mark_bit)
static const intptr_t kAllocationMarkingFactorSpeedupInterval
static const intptr_t kAllocationMarkingFactorSpeedup
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kThisPropertyAssignmentsOffset flag
Definition: objects-inl.h:3682
void RecordWriteSlow(HeapObject *obj, Object **slot, Object *value)
bool MarkBlackOrKeepGrey(MarkBit mark_bit)
static const intptr_t kAllocatedThreshold
void OldSpaceStep(intptr_t allocated)
static const intptr_t kMaxAllocationMarkingFactor
void BlackToGreyAndUnshift(HeapObject *obj, MarkBit mark_bit)