OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 21 matching lines...) Expand all Loading... |
32 namespace internal { | 32 namespace internal { |
33 | 33 |
34 // Callback function, returns whether an object is alive. The heap size | 34 // Callback function, returns whether an object is alive. The heap size |
35 // of the object is returned in size. It optionally updates the offset | 35 // of the object is returned in size. It optionally updates the offset |
36 // to the first live object in the page (only used for old and map objects). | 36 // to the first live object in the page (only used for old and map objects). |
37 typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset); | 37 typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset); |
38 | 38 |
39 // Forward declarations. | 39 // Forward declarations. |
40 class RootMarkingVisitor; | 40 class RootMarkingVisitor; |
41 class MarkingVisitor; | 41 class MarkingVisitor; |
| 42 class Marker; |
42 | 43 |
43 | 44 // ---------------------------------------------------------------------------- |
| 45 // Marking stack for tracing live objects. |
44 // ------------------------------------------------------------------------- | 46 // ------------------------------------------------------------------------- |
45 // Mark-Compact collector | 47 // Mark-Compact collector |
46 // | 48 // |
47 // All methods are static. | 49 // All methods are static. |
48 | 50 |
49 class MarkCompactCollector: public AllStatic { | 51 class MarkCompactCollector: public AllStatic { |
50 public: | 52 public: |
51 // Type of functions to compute forwarding addresses of objects in | 53 // Type of functions to compute forwarding addresses of objects in |
52 // compacted spaces. Given an object and its size, return a (non-failure) | 54 // compacted spaces. Given an object and its size, return a (non-failure) |
53 // Object* that will be the object after forwarding. There is a separate | 55 // Object* that will be the object after forwarding. There is a separate |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 static bool IsCompacting() { | 96 static bool IsCompacting() { |
95 #ifdef DEBUG | 97 #ifdef DEBUG |
96 // For the purposes of asserts we don't want this to keep returning true | 98 // For the purposes of asserts we don't want this to keep returning true |
97 // after the collection is completed. | 99 // after the collection is completed. |
98 return state_ != IDLE && compacting_collection_; | 100 return state_ != IDLE && compacting_collection_; |
99 #else | 101 #else |
100 return compacting_collection_; | 102 return compacting_collection_; |
101 #endif | 103 #endif |
102 } | 104 } |
103 | 105 |
104 // The count of the number of objects left marked at the end of the last | |
105 // completed full GC (expected to be zero). | |
106 static int previous_marked_count() { return previous_marked_count_; } | |
107 | |
108 // During a full GC, there is a stack-allocated GCTracer that is used for | 106 // During a full GC, there is a stack-allocated GCTracer that is used for |
109 // bookkeeping information. Return a pointer to that tracer. | 107 // bookkeeping information. Return a pointer to that tracer. |
110 static GCTracer* tracer() { return tracer_; } | 108 static GCTracer* tracer() { return tracer_; } |
111 | 109 |
112 #ifdef DEBUG | 110 #ifdef DEBUG |
113 // Checks whether performing mark-compact collection. | 111 // Checks whether performing mark-compact collection. |
114 static bool in_use() { return state_ > PREPARE_GC; } | 112 static bool in_use() { return state_ > PREPARE_GC; } |
115 static bool are_map_pointers_encoded() { return state_ == UPDATE_POINTERS; } | 113 static bool are_map_pointers_encoded() { return state_ == UPDATE_POINTERS; } |
116 #endif | 114 #endif |
117 | 115 |
(...skipping 23 matching lines...) Expand all Loading... |
141 | 139 |
142 // Global flag that forces a compaction. | 140 // Global flag that forces a compaction. |
143 static bool force_compaction_; | 141 static bool force_compaction_; |
144 | 142 |
145 // Global flag indicating whether spaces were compacted on the last GC. | 143 // Global flag indicating whether spaces were compacted on the last GC. |
146 static bool compacting_collection_; | 144 static bool compacting_collection_; |
147 | 145 |
148 // Global flag indicating whether spaces will be compacted on the next GC. | 146 // Global flag indicating whether spaces will be compacted on the next GC. |
149 static bool compact_on_next_gc_; | 147 static bool compact_on_next_gc_; |
150 | 148 |
151 // The number of objects left marked at the end of the last completed full | |
152 // GC (expected to be zero). | |
153 static int previous_marked_count_; | |
154 | |
155 // A pointer to the current stack-allocated GC tracer object during a full | 149 // A pointer to the current stack-allocated GC tracer object during a full |
156 // collection (NULL before and after). | 150 // collection (NULL before and after). |
157 static GCTracer* tracer_; | 151 static GCTracer* tracer_; |
158 | 152 |
159 // Finishes GC, performs heap verification if enabled. | 153 // Finishes GC, performs heap verification if enabled. |
160 static void Finish(); | 154 static void Finish(); |
161 | 155 |
162 // ----------------------------------------------------------------------- | 156 // ----------------------------------------------------------------------- |
163 // Phase 1: Marking live objects. | 157 // Phase 1: Marking live objects. |
164 // | 158 // |
165 // Before: The heap has been prepared for garbage collection by | 159 // Before: The heap has been prepared for garbage collection by |
166 // MarkCompactCollector::Prepare() and is otherwise in its | 160 // MarkCompactCollector::Prepare() and is otherwise in its |
167 // normal state. | 161 // normal state. |
168 // | 162 // |
169 // After: Live objects are marked and non-live objects are unmarked. | 163 // After: Live objects are marked and non-live objects are unmarked. |
170 | 164 |
171 | 165 |
172 friend class RootMarkingVisitor; | 166 friend class RootMarkingVisitor; |
173 friend class MarkingVisitor; | 167 friend class MarkingVisitor; |
174 friend class StaticMarkingVisitor; | 168 friend class StaticMarkingVisitor; |
175 friend class CodeMarkingVisitor; | 169 friend class CodeMarkingVisitor; |
176 friend class SharedFunctionInfoMarkingVisitor; | 170 friend class SharedFunctionInfoMarkingVisitor; |
| 171 friend class Marker; |
177 | 172 |
178 static void PrepareForCodeFlushing(); | 173 static void PrepareForCodeFlushing(); |
179 | 174 |
| 175 // Return total number of markers that will be used during |
| 176 // marking phase. |
| 177 static int NumberOfMarkers() { |
| 178 // If parallel marking is enabled and atomic operations is supported |
| 179 // on this platform use FLAG_number_of_markers otherwise use only |
| 180 // main marker. |
| 181 #if ATOMIC_SUPPORTED |
| 182 if (FLAG_parallel_marking) { |
| 183 return 1 + FLAG_number_of_markers; |
| 184 } |
| 185 #endif |
| 186 |
| 187 return 1; |
| 188 } |
| 189 |
| 190 |
180 // Marking operations for objects reachable from roots. | 191 // Marking operations for objects reachable from roots. |
181 static void MarkLiveObjects(); | 192 static void MarkLiveObjects(); |
182 | 193 |
183 static void MarkUnmarkedObject(HeapObject* obj); | |
184 | |
185 static inline void MarkObject(HeapObject* obj) { | |
186 if (!obj->IsMarked()) MarkUnmarkedObject(obj); | |
187 } | |
188 | |
189 static inline void SetMark(HeapObject* obj) { | |
190 tracer_->increment_marked_count(); | |
191 #ifdef DEBUG | |
192 UpdateLiveObjectCount(obj); | |
193 #endif | |
194 obj->SetMark(); | |
195 } | |
196 | |
197 // Creates back pointers for all map transitions, stores them in | 194 // Creates back pointers for all map transitions, stores them in |
198 // the prototype field. The original prototype pointers are restored | 195 // the prototype field. The original prototype pointers are restored |
199 // in ClearNonLiveTransitions(). All JSObject maps | 196 // in ClearNonLiveTransitions(). All JSObject maps |
200 // connected by map transitions have the same prototype object, which | 197 // connected by map transitions have the same prototype object, which |
201 // is why we can use this field temporarily for back pointers. | 198 // is why we can use this field temporarily for back pointers. |
202 static void CreateBackPointers(); | 199 static void CreateBackPointers(); |
203 | 200 |
204 // Mark a Map and its DescriptorArray together, skipping transitions. | 201 // Mark a Map and its DescriptorArray together, skipping transitions. |
205 static void MarkMapContents(Map* map); | 202 static void MarkMapContents(Map* map, Marker* marker); |
206 static void MarkDescriptorArray(DescriptorArray* descriptors); | 203 |
| 204 static void MarkDescriptorArray(DescriptorArray* descriptors, Marker* marker); |
207 | 205 |
208 // Mark the heap roots and all objects reachable from them. | 206 // Mark the heap roots and all objects reachable from them. |
209 static void MarkRoots(RootMarkingVisitor* visitor); | 207 static void MarkRoots(); |
210 | 208 |
211 // Mark the symbol table specially. References to symbols from the | 209 // Mark the symbol table specially. References to symbols from the |
212 // symbol table are weak. | 210 // symbol table are weak. |
213 static void MarkSymbolTable(); | 211 static void MarkSymbolTable(Marker* marker); |
214 | 212 |
215 // Mark objects in object groups that have at least one object in the | 213 // Mark objects in object groups that have at least one object in the |
216 // group marked. | 214 // group marked. |
217 static void MarkObjectGroups(); | 215 static void MarkObjectGroups(); |
218 | 216 |
219 // Mark all objects in an object group with at least one marked | 217 // Mark all objects in an object group with at least one marked |
220 // object, then all objects reachable from marked objects in object | 218 // object, then all objects reachable from marked objects in object |
221 // groups, and repeat. | 219 // groups, and repeat. |
222 static void ProcessObjectGroups(); | 220 static void ProcessObjectGroups(); |
223 | 221 |
224 // Mark objects reachable (transitively) from objects in the marking stack | |
225 // or overflowed in the heap. | |
226 static void ProcessMarkingStack(); | |
227 | |
228 // Mark objects reachable (transitively) from objects in the marking | |
229 // stack. This function empties the marking stack, but may leave | |
230 // overflowed objects in the heap, in which case the marking stack's | |
231 // overflow flag will be set. | |
232 static void EmptyMarkingStack(); | |
233 | |
234 // Refill the marking stack with overflowed objects from the heap. This | |
235 // function either leaves the marking stack full or clears the overflow | |
236 // flag on the marking stack. | |
237 static void RefillMarkingStack(); | |
238 | |
239 // Callback function for telling whether the object *p is an unmarked | 222 // Callback function for telling whether the object *p is an unmarked |
240 // heap object. | 223 // heap object. |
241 static bool IsUnmarkedHeapObject(Object** p); | 224 static bool IsUnmarkedHeapObject(Object** p); |
242 | 225 |
243 #ifdef DEBUG | 226 #ifdef DEBUG |
244 static void UpdateLiveObjectCount(HeapObject* obj); | 227 static void UpdateLiveObjectCount(HeapObject* obj); |
245 #endif | 228 #endif |
246 | 229 |
247 // We sweep the large object space in the same way whether we are | 230 // We sweep the large object space in the same way whether we are |
248 // compacting or not, because the large object space is never compacted. | 231 // compacting or not, because the large object space is never compacted. |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 | 403 |
421 friend class UnmarkObjectVisitor; | 404 friend class UnmarkObjectVisitor; |
422 static void UnmarkObject(HeapObject* obj); | 405 static void UnmarkObject(HeapObject* obj); |
423 #endif | 406 #endif |
424 }; | 407 }; |
425 | 408 |
426 | 409 |
427 } } // namespace v8::internal | 410 } } // namespace v8::internal |
428 | 411 |
429 #endif // V8_MARK_COMPACT_H_ | 412 #endif // V8_MARK_COMPACT_H_ |
OLD | NEW |