| 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 25 matching lines...) Expand all Loading... |
| 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 // Callback function for non-live blocks in the old generation. | 39 // Callback function for non-live blocks in the old generation. |
| 40 typedef void (*DeallocateFunction)(Address start, int size_in_bytes); | 40 typedef void (*DeallocateFunction)(Address start, int size_in_bytes); |
| 41 | 41 |
| 42 | 42 |
| 43 // Forward declarations. | 43 // Forward declarations. |
| 44 class RootMarkingVisitor; | 44 class RootMarkingVisitor; |
| 45 class MarkingVisitor; | 45 class MarkingVisitor; |
| 46 class MarkCompactCollectorPrivateData; |
| 46 | 47 |
| 48 class MarkCompactCollectorData { |
| 49 public: |
| 50 MarkCompactCollectorPrivateData& private_data_; |
| 51 private: |
| 52 #ifdef DEBUG |
| 53 enum CollectorState { |
| 54 IDLE, |
| 55 PREPARE_GC, |
| 56 MARK_LIVE_OBJECTS, |
| 57 SWEEP_SPACES, |
| 58 ENCODE_FORWARDING_ADDRESSES, |
| 59 UPDATE_POINTERS, |
| 60 RELOCATE_OBJECTS, |
| 61 REBUILD_RSETS |
| 62 }; |
| 63 |
| 64 // The current stage of the collector. |
| 65 CollectorState state_; |
| 66 |
| 67 // ----------------------------------------------------------------------- |
| 68 // Counters used for debugging the marking phase of mark-compact or |
| 69 // mark-sweep collection. |
| 70 |
| 71 // Number of live objects in Heap::to_space_. |
| 72 int live_young_objects_; |
| 73 |
| 74 // Number of live objects in Heap::old_pointer_space_. |
| 75 int live_old_pointer_objects_; |
| 76 |
| 77 // Number of live objects in Heap::old_data_space_. |
| 78 int live_old_data_objects_; |
| 79 |
| 80 // Number of live objects in Heap::code_space_. |
| 81 int live_code_objects_; |
| 82 |
| 83 // Number of live objects in Heap::map_space_. |
| 84 int live_map_objects_; |
| 85 |
| 86 // Number of live objects in Heap::cell_space_. |
| 87 int live_cell_objects_; |
| 88 |
| 89 // Number of live objects in Heap::lo_space_. |
| 90 int live_lo_objects_; |
| 91 |
| 92 // Number of live bytes in this collection. |
| 93 int live_bytes_; |
| 94 |
| 95 #endif |
| 96 |
| 97 // Global flag that forces a compaction. |
| 98 bool force_compaction_; |
| 99 |
| 100 // Global flag indicating whether spaces were compacted on the last GC. |
| 101 bool compacting_collection_; |
| 102 |
| 103 // Global flag indicating whether spaces will be compacted on the next GC. |
| 104 bool compact_on_next_gc_; |
| 105 |
| 106 // The number of objects left marked at the end of the last completed full |
| 107 // GC (expected to be zero). |
| 108 int previous_marked_count_; |
| 109 |
| 110 // A pointer to the current stack-allocated GC tracer object during a full |
| 111 // collection (NULL before and after). |
| 112 GCTracer* tracer_; |
| 113 |
| 114 friend class MarkCompactCollector; |
| 115 friend class V8Context; |
| 116 |
| 117 MarkCompactCollectorData(); |
| 118 ~MarkCompactCollectorData(); |
| 119 |
| 120 DISALLOW_COPY_AND_ASSIGN(MarkCompactCollectorData); |
| 121 }; |
| 47 | 122 |
| 48 // ------------------------------------------------------------------------- | 123 // ------------------------------------------------------------------------- |
| 49 // Mark-Compact collector | 124 // Mark-Compact collector |
| 50 // | 125 // |
| 51 // All methods are static. | 126 // All methods are static. |
| 52 | 127 |
| 53 class MarkCompactCollector: public AllStatic { | 128 class MarkCompactCollector: public AllStatic { |
| 54 public: | 129 public: |
| 55 // Type of functions to compute forwarding addresses of objects in | 130 // Type of functions to compute forwarding addresses of objects in |
| 56 // compacted spaces. Given an object and its size, return a (non-failure) | 131 // compacted spaces. Given an object and its size, return a (non-failure) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 71 int object_size, | 146 int object_size, |
| 72 Object* new_object, | 147 Object* new_object, |
| 73 int* offset); | 148 int* offset); |
| 74 | 149 |
| 75 // Type of functions to process non-live objects. | 150 // Type of functions to process non-live objects. |
| 76 typedef void (*ProcessNonLiveFunction)(HeapObject* object); | 151 typedef void (*ProcessNonLiveFunction)(HeapObject* object); |
| 77 | 152 |
| 78 // Set the global force_compaction flag, it must be called before Prepare | 153 // Set the global force_compaction flag, it must be called before Prepare |
| 79 // to take effect. | 154 // to take effect. |
| 80 static void SetForceCompaction(bool value) { | 155 static void SetForceCompaction(bool value) { |
| 81 force_compaction_ = value; | 156 v8_context()->mark_compact_collector_data_.force_compaction_ = value; |
| 82 } | 157 } |
| 83 | 158 |
| 84 // Prepares for GC by resetting relocation info in old and map spaces and | 159 // Prepares for GC by resetting relocation info in old and map spaces and |
| 85 // choosing spaces to compact. | 160 // choosing spaces to compact. |
| 86 static void Prepare(GCTracer* tracer); | 161 static void Prepare(GCTracer* tracer); |
| 87 | 162 |
| 88 // Performs a global garbage collection. | 163 // Performs a global garbage collection. |
| 89 static void CollectGarbage(); | 164 static void CollectGarbage(); |
| 90 | 165 |
| 91 // True if the last full GC performed heap compaction. | 166 // True if the last full GC performed heap compaction. |
| 92 static bool HasCompacted() { return compacting_collection_; } | 167 static bool HasCompacted() { |
| 168 return v8_context()->mark_compact_collector_data_.compacting_collection_; |
| 169 } |
| 93 | 170 |
| 94 // True after the Prepare phase if the compaction is taking place. | 171 // True after the Prepare phase if the compaction is taking place. |
| 95 static bool IsCompacting() { return compacting_collection_; } | 172 static bool IsCompacting() { |
| 173 return v8_context()->mark_compact_collector_data_.compacting_collection_; |
| 174 } |
| 96 | 175 |
| 97 // The count of the number of objects left marked at the end of the last | 176 // The count of the number of objects left marked at the end of the last |
| 98 // completed full GC (expected to be zero). | 177 // completed full GC (expected to be zero). |
| 99 static int previous_marked_count() { return previous_marked_count_; } | 178 static int previous_marked_count() { |
| 179 return v8_context()->mark_compact_collector_data_.previous_marked_count_; |
| 180 } |
| 100 | 181 |
| 101 // During a full GC, there is a stack-allocated GCTracer that is used for | 182 // During a full GC, there is a stack-allocated GCTracer that is used for |
| 102 // bookkeeping information. Return a pointer to that tracer. | 183 // bookkeeping information. Return a pointer to that tracer. |
| 103 static GCTracer* tracer() { return tracer_; } | 184 static GCTracer* tracer() { |
| 185 return v8_context()->mark_compact_collector_data_.tracer_; |
| 186 } |
| 104 | 187 |
| 105 #ifdef DEBUG | 188 #ifdef DEBUG |
| 106 // Checks whether performing mark-compact collection. | 189 // Checks whether performing mark-compact collection. |
| 107 static bool in_use() { return state_ > PREPARE_GC; } | 190 static bool in_use() { |
| 191 return v8_context()->mark_compact_collector_data_.state_ > |
| 192 MarkCompactCollectorData::PREPARE_GC; |
| 193 } |
| 108 #endif | 194 #endif |
| 109 | 195 |
| 110 private: | 196 private: |
| 111 #ifdef DEBUG | |
| 112 enum CollectorState { | |
| 113 IDLE, | |
| 114 PREPARE_GC, | |
| 115 MARK_LIVE_OBJECTS, | |
| 116 SWEEP_SPACES, | |
| 117 ENCODE_FORWARDING_ADDRESSES, | |
| 118 UPDATE_POINTERS, | |
| 119 RELOCATE_OBJECTS, | |
| 120 REBUILD_RSETS | |
| 121 }; | |
| 122 | |
| 123 // The current stage of the collector. | |
| 124 static CollectorState state_; | |
| 125 #endif | |
| 126 | |
| 127 // Global flag that forces a compaction. | |
| 128 static bool force_compaction_; | |
| 129 | |
| 130 // Global flag indicating whether spaces were compacted on the last GC. | |
| 131 static bool compacting_collection_; | |
| 132 | |
| 133 // Global flag indicating whether spaces will be compacted on the next GC. | |
| 134 static bool compact_on_next_gc_; | |
| 135 | |
| 136 // The number of objects left marked at the end of the last completed full | |
| 137 // GC (expected to be zero). | |
| 138 static int previous_marked_count_; | |
| 139 | |
| 140 // A pointer to the current stack-allocated GC tracer object during a full | |
| 141 // collection (NULL before and after). | |
| 142 static GCTracer* tracer_; | |
| 143 | 197 |
| 144 // Finishes GC, performs heap verification if enabled. | 198 // Finishes GC, performs heap verification if enabled. |
| 145 static void Finish(); | 199 static void Finish(); |
| 146 | 200 |
| 147 // ----------------------------------------------------------------------- | 201 // ----------------------------------------------------------------------- |
| 148 // Phase 1: Marking live objects. | 202 // Phase 1: Marking live objects. |
| 149 // | 203 // |
| 150 // Before: The heap has been prepared for garbage collection by | 204 // Before: The heap has been prepared for garbage collection by |
| 151 // MarkCompactCollector::Prepare() and is otherwise in its | 205 // MarkCompactCollector::Prepare() and is otherwise in its |
| 152 // normal state. | 206 // normal state. |
| 153 // | 207 // |
| 154 // After: Live objects are marked and non-live objects are unmarked. | 208 // After: Live objects are marked and non-live objects are unmarked. |
| 155 | 209 |
| 156 | 210 |
| 157 friend class RootMarkingVisitor; | 211 friend class RootMarkingVisitor; |
| 158 friend class MarkingVisitor; | 212 friend class MarkingVisitor; |
| 159 | 213 |
| 160 // Marking operations for objects reachable from roots. | 214 // Marking operations for objects reachable from roots. |
| 161 static void MarkLiveObjects(); | 215 static void MarkLiveObjects(); |
| 162 | 216 |
| 163 static void MarkUnmarkedObject(HeapObject* obj); | 217 static void MarkUnmarkedObject(HeapObject* obj); |
| 164 | 218 |
| 165 static inline void MarkObject(HeapObject* obj) { | 219 static inline void MarkObject(HeapObject* obj) { |
| 166 if (!obj->IsMarked()) MarkUnmarkedObject(obj); | 220 if (!obj->IsMarked()) MarkUnmarkedObject(obj); |
| 167 } | 221 } |
| 168 | 222 |
| 169 static inline void SetMark(HeapObject* obj) { | 223 static inline void SetMark(HeapObject* obj) { |
| 170 tracer_->increment_marked_count(); | 224 v8_context()->mark_compact_collector_data_. |
| 225 tracer_->increment_marked_count(); |
| 171 #ifdef DEBUG | 226 #ifdef DEBUG |
| 172 UpdateLiveObjectCount(obj); | 227 UpdateLiveObjectCount(obj); |
| 173 #endif | 228 #endif |
| 174 obj->SetMark(); | 229 obj->SetMark(); |
| 175 } | 230 } |
| 176 | 231 |
| 177 // Creates back pointers for all map transitions, stores them in | 232 // Creates back pointers for all map transitions, stores them in |
| 178 // the prototype field. The original prototype pointers are restored | 233 // the prototype field. The original prototype pointers are restored |
| 179 // in ClearNonLiveTransitions(). All JSObject maps | 234 // in ClearNonLiveTransitions(). All JSObject maps |
| 180 // connected by map transitions have the same prototype object, which | 235 // connected by map transitions have the same prototype object, which |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 // Before: The heap is in a normal state except that remembered sets | 440 // Before: The heap is in a normal state except that remembered sets |
| 386 // in the paged spaces are not correct. | 441 // in the paged spaces are not correct. |
| 387 // | 442 // |
| 388 // After: The heap is in a normal state. | 443 // After: The heap is in a normal state. |
| 389 | 444 |
| 390 // Rebuild remembered set in old and map spaces. | 445 // Rebuild remembered set in old and map spaces. |
| 391 static void RebuildRSets(); | 446 static void RebuildRSets(); |
| 392 | 447 |
| 393 #ifdef DEBUG | 448 #ifdef DEBUG |
| 394 // ----------------------------------------------------------------------- | 449 // ----------------------------------------------------------------------- |
| 395 // Debugging variables, functions and classes | 450 // Debugging functions and classes |
| 396 // Counters used for debugging the marking phase of mark-compact or | |
| 397 // mark-sweep collection. | |
| 398 | |
| 399 // Number of live objects in Heap::to_space_. | |
| 400 static int live_young_objects_; | |
| 401 | |
| 402 // Number of live objects in Heap::old_pointer_space_. | |
| 403 static int live_old_pointer_objects_; | |
| 404 | |
| 405 // Number of live objects in Heap::old_data_space_. | |
| 406 static int live_old_data_objects_; | |
| 407 | |
| 408 // Number of live objects in Heap::code_space_. | |
| 409 static int live_code_objects_; | |
| 410 | |
| 411 // Number of live objects in Heap::map_space_. | |
| 412 static int live_map_objects_; | |
| 413 | |
| 414 // Number of live objects in Heap::cell_space_. | |
| 415 static int live_cell_objects_; | |
| 416 | |
| 417 // Number of live objects in Heap::lo_space_. | |
| 418 static int live_lo_objects_; | |
| 419 | |
| 420 // Number of live bytes in this collection. | |
| 421 static int live_bytes_; | |
| 422 | |
| 423 friend class MarkObjectVisitor; | 451 friend class MarkObjectVisitor; |
| 424 static void VisitObject(HeapObject* obj); | 452 static void VisitObject(HeapObject* obj); |
| 425 | 453 |
| 426 friend class UnmarkObjectVisitor; | 454 friend class UnmarkObjectVisitor; |
| 427 static void UnmarkObject(HeapObject* obj); | 455 static void UnmarkObject(HeapObject* obj); |
| 428 #endif | 456 #endif |
| 429 }; | 457 }; |
| 430 | 458 |
| 431 | 459 |
| 432 } } // namespace v8::internal | 460 } } // namespace v8::internal |
| 433 | 461 |
| 434 #endif // V8_MARK_COMPACT_H_ | 462 #endif // V8_MARK_COMPACT_H_ |
| OLD | NEW |