| 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 |