The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / mark-compact.h @ 40c0f755

History | View | Annotate | Download (15.9 KB)

1
// Copyright 2006-2008 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_MARK_COMPACT_H_
29
#define V8_MARK_COMPACT_H_
30

    
31
namespace v8 { namespace internal {
32

    
33
// Callback function, returns whether an object is alive. The heap size
34
// of the object is returned in size. It optionally updates the offset
35
// to the first live object in the page (only used for old and map objects).
36
typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset);
37

    
38
// Callback function for non-live blocks in the old generation.
39
typedef void (*DeallocateFunction)(Address start, int size_in_bytes);
40

    
41

    
42
// Forward declarations.
43
class RootMarkingVisitor;
44
class MarkingVisitor;
45

    
46

    
47
// -------------------------------------------------------------------------
48
// Mark-Compact collector
49
//
50
// All methods are static.
51

    
52
class MarkCompactCollector: public AllStatic {
53
 public:
54
  // Type of functions to compute forwarding addresses of objects in
55
  // compacted spaces.  Given an object and its size, return a (non-failure)
56
  // Object* that will be the object after forwarding.  There is a separate
57
  // allocation function for each (compactable) space based on the location
58
  // of the object before compaction.
59
  typedef Object* (*AllocationFunction)(HeapObject* object, int object_size);
60

    
61
  // Type of functions to encode the forwarding address for an object.
62
  // Given the object, its size, and the new (non-failure) object it will be
63
  // forwarded to, encode the forwarding address.  For paged spaces, the
64
  // 'offset' input/output parameter contains the offset of the forwarded
65
  // object from the forwarding address of the previous live object in the
66
  // page as input, and is updated to contain the offset to be used for the
67
  // next live object in the same page.  For spaces using a different
68
  // encoding (ie, contiguous spaces), the offset parameter is ignored.
69
  typedef void (*EncodingFunction)(HeapObject* old_object,
70
                                   int object_size,
71
                                   Object* new_object,
72
                                   int* offset);
73

    
74
  // Type of functions to process non-live objects.
75
  typedef void (*ProcessNonLiveFunction)(HeapObject* object);
76

    
77
  // Prepares for GC by resetting relocation info in old and map spaces and
78
  // choosing spaces to compact.
79
  static void Prepare(GCTracer* tracer);
80

    
81
  // Performs a global garbage collection.
82
  static void CollectGarbage();
83

    
84
  // True if the last full GC performed heap compaction.
85
  static bool HasCompacted() { return compacting_collection_; }
86

    
87
  // True after the Prepare phase if the compaction is taking place.
88
  static bool IsCompacting() { return compacting_collection_; }
89

    
90
  // The count of the number of objects left marked at the end of the last
91
  // completed full GC (expected to be zero).
92
  static int previous_marked_count() { return previous_marked_count_; }
93

    
94
  // During a full GC, there is a stack-allocated GCTracer that is used for
95
  // bookkeeping information.  Return a pointer to that tracer.
96
  static GCTracer* tracer() { return tracer_; }
97

    
98
#ifdef DEBUG
99
  // Checks whether performing mark-compact collection.
100
  static bool in_use() { return state_ > PREPARE_GC; }
101
#endif
102

    
103
 private:
104
#ifdef DEBUG
105
  enum CollectorState {
106
    IDLE,
107
    PREPARE_GC,
108
    MARK_LIVE_OBJECTS,
109
    SWEEP_SPACES,
110
    ENCODE_FORWARDING_ADDRESSES,
111
    UPDATE_POINTERS,
112
    RELOCATE_OBJECTS,
113
    REBUILD_RSETS
114
  };
115

    
116
  // The current stage of the collector.
117
  static CollectorState state_;
118
#endif
119
  // Global flag indicating whether spaces were compacted on the last GC.
120
  static bool compacting_collection_;
121

    
122
  // The number of objects left marked at the end of the last completed full
123
  // GC (expected to be zero).
124
  static int previous_marked_count_;
125

    
126
  // A pointer to the current stack-allocated GC tracer object during a full
127
  // collection (NULL before and after).
128
  static GCTracer* tracer_;
129

    
130
  // Finishes GC, performs heap verification if enabled.
131
  static void Finish();
132

    
133
  // -----------------------------------------------------------------------
134
  // Phase 1: Marking live objects.
135
  //
136
  //  Before: The heap has been prepared for garbage collection by
137
  //          MarkCompactCollector::Prepare() and is otherwise in its
138
  //          normal state.
139
  //
140
  //   After: Live objects are marked and non-live objects are unmarked.
141

    
142

    
143
  friend class RootMarkingVisitor;
144
  friend class MarkingVisitor;
145

    
146
  // Marking operations for objects reachable from roots.
147
  static void MarkLiveObjects();
148

    
149
  static void MarkUnmarkedObject(HeapObject* obj);
150

    
151
  static inline void MarkObject(HeapObject* obj) {
152
    if (!obj->IsMarked()) MarkUnmarkedObject(obj);
153
  }
154

    
155
  static inline void SetMark(HeapObject* obj) {
156
    tracer_->increment_marked_count();
157
#ifdef DEBUG
158
    UpdateLiveObjectCount(obj);
159
#endif
160
    obj->SetMark();
161
  }
162

    
163
  // Creates back pointers for all map transitions, stores them in
164
  // the prototype field.  The original prototype pointers are restored
165
  // in ClearNonLiveTransitions().  All JSObject maps
166
  // connected by map transitions have the same prototype object, which
167
  // is why we can use this field temporarily for back pointers.
168
  static void CreateBackPointers();
169

    
170
  // Mark a Map and its DescriptorArray together, skipping transitions.
171
  static void MarkMapContents(Map* map);
172
  static void MarkDescriptorArray(DescriptorArray* descriptors);
173

    
174
  // Mark the heap roots and all objects reachable from them.
175
  static void ProcessRoots(RootMarkingVisitor* visitor);
176

    
177
  // Mark objects in object groups that have at least one object in the
178
  // group marked.
179
  static void MarkObjectGroups();
180

    
181
  // Mark all objects in an object group with at least one marked
182
  // object, then all objects reachable from marked objects in object
183
  // groups, and repeat.
184
  static void ProcessObjectGroups(MarkingVisitor* visitor);
185

    
186
  // Mark objects reachable (transitively) from objects in the marking stack
187
  // or overflowed in the heap.
188
  static void ProcessMarkingStack(MarkingVisitor* visitor);
189

    
190
  // Mark objects reachable (transitively) from objects in the marking
191
  // stack.  This function empties the marking stack, but may leave
192
  // overflowed objects in the heap, in which case the marking stack's
193
  // overflow flag will be set.
194
  static void EmptyMarkingStack(MarkingVisitor* visitor);
195

    
196
  // Refill the marking stack with overflowed objects from the heap.  This
197
  // function either leaves the marking stack full or clears the overflow
198
  // flag on the marking stack.
199
  static void RefillMarkingStack();
200

    
201
  // Callback function for telling whether the object *p must be marked.
202
  static bool MustBeMarked(Object** p);
203

    
204
#ifdef DEBUG
205
  static void UpdateLiveObjectCount(HeapObject* obj);
206
#endif
207

    
208
  // We sweep the large object space in the same way whether we are
209
  // compacting or not, because the large object space is never compacted.
210
  static void SweepLargeObjectSpace();
211

    
212
  // Test whether a (possibly marked) object is a Map.
213
  static inline bool SafeIsMap(HeapObject* object);
214

    
215
  // Map transitions from a live map to a dead map must be killed.
216
  // We replace them with a null descriptor, with the same key.
217
  static void ClearNonLiveTransitions();
218

    
219
  // -----------------------------------------------------------------------
220
  // Phase 2: Sweeping to clear mark bits and free non-live objects for
221
  // a non-compacting collection, or else computing and encoding
222
  // forwarding addresses for a compacting collection.
223
  //
224
  //  Before: Live objects are marked and non-live objects are unmarked.
225
  //
226
  //   After: (Non-compacting collection.)  Live objects are unmarked,
227
  //          non-live regions have been added to their space's free
228
  //          list.
229
  //
230
  //   After: (Compacting collection.)  The forwarding address of live
231
  //          objects in the paged spaces is encoded in their map word
232
  //          along with their (non-forwarded) map pointer.
233
  //
234
  //          The forwarding address of live objects in the new space is
235
  //          written to their map word's offset in the inactive
236
  //          semispace.
237
  //
238
  //          Bookkeeping data is written to the remembered-set are of
239
  //          eached paged-space page that contains live objects after
240
  //          compaction:
241
  //
242
  //          The 3rd word of the page (first word of the remembered
243
  //          set) contains the relocation top address, the address of
244
  //          the first word after the end of the last live object in
245
  //          the page after compaction.
246
  //
247
  //          The 4th word contains the zero-based index of the page in
248
  //          its space.  This word is only used for map space pages, in
249
  //          order to encode the map addresses in 21 bits to free 11
250
  //          bits per map word for the forwarding address.
251
  //
252
  //          The 5th word contains the (nonencoded) forwarding address
253
  //          of the first live object in the page.
254
  //
255
  //          In both the new space and the paged spaces, a linked list
256
  //          of live regions is constructructed (linked through
257
  //          pointers in the non-live region immediately following each
258
  //          live region) to speed further passes of the collector.
259

    
260
  // Encodes forwarding addresses of objects in compactable parts of the
261
  // heap.
262
  static void EncodeForwardingAddresses();
263

    
264
  // Encodes the forwarding addresses of objects in new space.
265
  static void EncodeForwardingAddressesInNewSpace();
266

    
267
  // Function template to encode the forwarding addresses of objects in
268
  // paged spaces, parameterized by allocation and non-live processing
269
  // functions.
270
  template<AllocationFunction Alloc, ProcessNonLiveFunction ProcessNonLive>
271
  static void EncodeForwardingAddressesInPagedSpace(PagedSpace* space);
272

    
273
  // Iterates live objects in a space, passes live objects
274
  // to a callback function which returns the heap size of the object.
275
  // Returns the number of live objects iterated.
276
  static int IterateLiveObjects(NewSpace* space, HeapObjectCallback size_f);
277
  static int IterateLiveObjects(PagedSpace* space, HeapObjectCallback size_f);
278

    
279
  // Iterates the live objects between a range of addresses, returning the
280
  // number of live objects.
281
  static int IterateLiveObjectsInRange(Address start, Address end,
282
                                       HeapObjectCallback size_func);
283

    
284
  // Callback functions for deallocating non-live blocks in the old
285
  // generation.
286
  static void DeallocateOldPointerBlock(Address start, int size_in_bytes);
287
  static void DeallocateOldDataBlock(Address start, int size_in_bytes);
288
  static void DeallocateCodeBlock(Address start, int size_in_bytes);
289
  static void DeallocateMapBlock(Address start, int size_in_bytes);
290

    
291
  // If we are not compacting the heap, we simply sweep the spaces except
292
  // for the large object space, clearing mark bits and adding unmarked
293
  // regions to each space's free list.
294
  static void SweepSpaces();
295

    
296
  // -----------------------------------------------------------------------
297
  // Phase 3: Updating pointers in live objects.
298
  //
299
  //  Before: Same as after phase 2 (compacting collection).
300
  //
301
  //   After: All pointers in live objects, including encoded map
302
  //          pointers, are updated to point to their target's new
303
  //          location.  The remembered set area of each paged-space
304
  //          page containing live objects still contains bookkeeping
305
  //          information.
306

    
307
  friend class UpdatingVisitor;  // helper for updating visited objects
308

    
309
  // Updates pointers in all spaces.
310
  static void UpdatePointers();
311

    
312
  // Updates pointers in an object in new space.
313
  // Returns the heap size of the object.
314
  static int UpdatePointersInNewObject(HeapObject* obj);
315

    
316
  // Updates pointers in an object in old spaces.
317
  // Returns the heap size of the object.
318
  static int UpdatePointersInOldObject(HeapObject* obj);
319

    
320
  // Calculates the forwarding address of an object in an old space.
321
  static Address GetForwardingAddressInOldSpace(HeapObject* obj);
322

    
323
  // -----------------------------------------------------------------------
324
  // Phase 4: Relocating objects.
325
  //
326
  //  Before: Pointers to live objects are updated to point to their
327
  //          target's new location.  The remembered set area of each
328
  //          paged-space page containing live objects still contains
329
  //          bookkeeping information.
330
  //
331
  //   After: Objects have been moved to their new addresses. The
332
  //          remembered set area of each paged-space page containing
333
  //          live objects still contains bookkeeping information.
334

    
335
  // Relocates objects in all spaces.
336
  static void RelocateObjects();
337

    
338
  // Converts a code object's inline target to addresses, convention from
339
  // address to target happens in the marking phase.
340
  static int ConvertCodeICTargetToAddress(HeapObject* obj);
341

    
342
  // Relocate a map object.
343
  static int RelocateMapObject(HeapObject* obj);
344

    
345
  // Relocates an old object.
346
  static int RelocateOldPointerObject(HeapObject* obj);
347
  static int RelocateOldDataObject(HeapObject* obj);
348

    
349
  // Helper function.
350
  static inline int RelocateOldNonCodeObject(HeapObject* obj, OldSpace* space);
351

    
352
  // Relocates an object in the code space.
353
  static int RelocateCodeObject(HeapObject* obj);
354

    
355
  // Copy a new object.
356
  static int RelocateNewObject(HeapObject* obj);
357

    
358
  // -----------------------------------------------------------------------
359
  // Phase 5: Rebuilding remembered sets.
360
  //
361
  //  Before: The heap is in a normal state except that remembered sets
362
  //          in the paged spaces are not correct.
363
  //
364
  //   After: The heap is in a normal state.
365

    
366
  // Rebuild remembered set in old and map spaces.
367
  static void RebuildRSets();
368

    
369
#ifdef DEBUG
370
  // -----------------------------------------------------------------------
371
  // Debugging variables, functions and classes
372
  // Counters used for debugging the marking phase of mark-compact or
373
  // mark-sweep collection.
374

    
375
  // Number of live objects in Heap::to_space_.
376
  static int live_young_objects_;
377

    
378
  // Number of live objects in Heap::old_pointer_space_.
379
  static int live_old_pointer_objects_;
380

    
381
  // Number of live objects in Heap::old_data_space_.
382
  static int live_old_data_objects_;
383

    
384
  // Number of live objects in Heap::code_space_.
385
  static int live_code_objects_;
386

    
387
  // Number of live objects in Heap::map_space_.
388
  static int live_map_objects_;
389

    
390
  // Number of live objects in Heap::lo_space_.
391
  static int live_lo_objects_;
392

    
393
  // Number of live bytes in this collection.
394
  static int live_bytes_;
395

    
396
  friend class MarkObjectVisitor;
397
  static void VisitObject(HeapObject* obj);
398

    
399
  friend class UnmarkObjectVisitor;
400
  static void UnmarkObject(HeapObject* obj);
401
#endif
402
};
403

    
404

    
405
} }  // namespace v8::internal
406

    
407
#endif  // V8_MARK_COMPACT_H_