v8  3.14.5(node0.10.28)
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  static void Initialize();
57 
58  void TearDown();
59 
61  ASSERT(state_ == STOPPED || FLAG_incremental_marking);
62  return state_;
63  }
64 
65  bool should_hurry() { return should_hurry_; }
66  void set_should_hurry(bool val) { should_hurry_ = val; }
67 
68  inline bool IsStopped() { return state() == STOPPED; }
69 
70  INLINE(bool IsMarking()) { return state() >= MARKING; }
71 
72  inline bool IsMarkingIncomplete() { return state() == MARKING; }
73 
74  inline bool IsComplete() { return state() == COMPLETE; }
75 
76  bool WorthActivating();
77 
78  void Start();
79 
80  void Stop();
81 
82  void PrepareForScavenge();
83 
85 
86  void Hurry();
87 
88  void Finalize();
89 
90  void Abort();
91 
92  void MarkingComplete(CompletionAction action);
93 
94  // It's hard to know how much work the incremental marker should do to make
95  // progress in the face of the mutator creating new work for it. We start
96  // of at a moderate rate of work and gradually increase the speed of the
97  // incremental marker until it completes.
98  // Do some marking every time this much memory has been allocated or that many
99  // heavy (color-checking) write barriers have been invoked.
100  static const intptr_t kAllocatedThreshold = 65536;
101  static const intptr_t kWriteBarriersInvokedThreshold = 65536;
102  // Start off by marking this many times more memory than has been allocated.
103  static const intptr_t kInitialMarkingSpeed = 1;
104  // But if we are promoting a lot of data we need to mark faster to keep up
105  // with the data that is entering the old space through promotion.
106  static const intptr_t kFastMarking = 3;
107  // After this many steps we increase the marking/allocating factor.
108  static const intptr_t kMarkingSpeedAccellerationInterval = 1024;
109  // This is how much we increase the marking/allocating factor by.
110  static const intptr_t kMarkingSpeedAccelleration = 2;
111  static const intptr_t kMaxMarkingSpeed = 1000;
112 
113  void OldSpaceStep(intptr_t allocated) {
114  Step(allocated * kFastMarking / kInitialMarkingSpeed,
116  }
117 
118  void Step(intptr_t allocated, CompletionAction action);
119 
120  inline void RestartIfNotMarking() {
121  if (state_ == COMPLETE) {
122  state_ = MARKING;
123  if (FLAG_trace_incremental_marking) {
124  PrintF("[IncrementalMarking] Restarting (new grey objects)\n");
125  }
126  }
127  }
128 
129  static void RecordWriteFromCode(HeapObject* obj,
130  Object* value,
131  Isolate* isolate);
132 
134  Object** slot,
135  Isolate* isolate);
136 
137  // Record a slot for compaction. Returns false for objects that are
138  // guaranteed to be rescanned or not guaranteed to survive.
139  //
140  // No slots in white objects should be recorded, as some slots are typed and
141  // cannot be interpreted correctly if the underlying object does not survive
142  // the incremental cycle (stays white).
143  INLINE(bool BaseRecordWrite(HeapObject* obj, Object** slot, Object* value));
144  INLINE(void RecordWrite(HeapObject* obj, Object** slot, Object* value));
145  INLINE(void RecordWriteIntoCode(HeapObject* obj,
146  RelocInfo* rinfo,
147  Object* value));
148  INLINE(void RecordWriteOfCodeEntry(JSFunction* host,
149  Object** slot,
150  Code* value));
151 
152 
153  void RecordWriteSlow(HeapObject* obj, Object** slot, Object* value);
155  RelocInfo* rinfo,
156  Object* value);
157  void RecordWriteOfCodeEntrySlow(JSFunction* host, Object** slot, Code* value);
158  void RecordCodeTargetPatch(Code* host, Address pc, HeapObject* value);
160 
161  inline void RecordWrites(HeapObject* obj);
162 
163  inline void BlackToGreyAndUnshift(HeapObject* obj, MarkBit mark_bit);
164 
165  inline void WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit);
166 
167  // Does white->black or keeps gray or black color. Returns true if converting
168  // white to black.
169  inline bool MarkBlackOrKeepGrey(MarkBit mark_bit) {
170  ASSERT(!Marking::IsImpossible(mark_bit));
171  if (mark_bit.Get()) {
172  // Grey or black: Keep the color.
173  return false;
174  }
175  mark_bit.Set();
176  ASSERT(Marking::IsBlack(mark_bit));
177  return true;
178  }
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 (marking_speed_ < kFastMarking) {
217  if (FLAG_trace_gc) {
218  PrintPID("Increasing marking speed to %d "
219  "due to high promotion rate\n",
220  static_cast<int>(kFastMarking));
221  }
222  marking_speed_ = kFastMarking;
223  }
224  }
225  }
226 
228  no_marking_scope_depth_++;
229  }
230 
232  no_marking_scope_depth_--;
233  }
234 
235  void UncommitMarkingDeque();
236 
237  private:
238  int64_t SpaceLeftInOldSpace();
239 
240  void ResetStepCounters();
241 
242  enum CompactionFlag { ALLOW_COMPACTION, PREVENT_COMPACTION };
243 
244  void StartMarking(CompactionFlag flag);
245 
246  void ActivateIncrementalWriteBarrier(PagedSpace* space);
247  static void ActivateIncrementalWriteBarrier(NewSpace* space);
248  void ActivateIncrementalWriteBarrier();
249 
250  static void DeactivateIncrementalWriteBarrierForSpace(PagedSpace* space);
251  static void DeactivateIncrementalWriteBarrierForSpace(NewSpace* space);
252  void DeactivateIncrementalWriteBarrier();
253 
254  static void SetOldSpacePageFlags(MemoryChunk* chunk,
255  bool is_marking,
256  bool is_compacting);
257 
258  static void SetNewSpacePageFlags(NewSpacePage* chunk, bool is_marking);
259 
260  void EnsureMarkingDequeIsCommitted();
261 
262  Heap* heap_;
263 
264  State state_;
265  bool is_compacting_;
266 
267  VirtualMemory* marking_deque_memory_;
268  bool marking_deque_memory_committed_;
269  MarkingDeque marking_deque_;
270 
271  int steps_count_;
272  double steps_took_;
273  double longest_step_;
274  int64_t old_generation_space_available_at_start_of_incremental_;
275  int64_t old_generation_space_used_at_start_of_incremental_;
276  int steps_count_since_last_gc_;
277  double steps_took_since_last_gc_;
278  int64_t bytes_rescanned_;
279  bool should_hurry_;
280  int marking_speed_;
281  intptr_t bytes_scanned_;
282  intptr_t allocated_;
283  intptr_t write_barriers_invoked_since_last_step_;
284 
285  int no_marking_scope_depth_;
286 
287  DISALLOW_IMPLICIT_CONSTRUCTORS(IncrementalMarking);
288 };
289 
290 } } // namespace v8::internal
291 
292 #endif // V8_INCREMENTAL_MARKING_H_
static bool IsBlack(MarkBit mark_bit)
Definition: mark-compact.h:70
byte * Address
Definition: globals.h:157
void PrintF(const char *format,...)
Definition: v8utils.cc:40
static const intptr_t kWriteBarriersInvokedThreshold
void SetNewSpacePageFlags(NewSpacePage *chunk)
static void RecordWriteForEvacuationFromCode(HeapObject *obj, Object **slot, Isolate *isolate)
#define ASSERT(condition)
Definition: checks.h:270
static const intptr_t kMarkingSpeedAccelleration
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)
static const intptr_t kMarkingSpeedAccellerationInterval
static const intptr_t kMaxMarkingSpeed
void MarkingComplete(CompletionAction action)
void RecordWriteOfCodeEntrySlow(JSFunction *host, Object **slot, Code *value)
const Register pc
static bool IsImpossible(MarkBit mark_bit)
Definition: mark-compact.h:64
void SetOldSpacePageFlags(MemoryChunk *chunk)
void WhiteToGreyAndPush(HeapObject *obj, MarkBit mark_bit)
void PrintPID(const char *format,...)
Definition: v8utils.cc:56
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 kInitialMarkingSpeed
void BlackToGreyAndUnshift(HeapObject *obj, MarkBit mark_bit)
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kInstanceClassNameOffset flag
Definition: objects-inl.h:3923