Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
| 6 | 6 |
| 7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 // cleared eagerly immediately after the transition. | 319 // cleared eagerly immediately after the transition. |
| 320 | 320 |
| 321 #ifdef VERIFY_HEAP | 321 #ifdef VERIFY_HEAP |
| 322 if (FLAG_verify_heap) { | 322 if (FLAG_verify_heap) { |
| 323 RememberedSet<OLD_TO_NEW>::VerifyValidSlots(heap()); | 323 RememberedSet<OLD_TO_NEW>::VerifyValidSlots(heap()); |
| 324 RememberedSet<OLD_TO_OLD>::VerifyValidSlots(heap()); | 324 RememberedSet<OLD_TO_OLD>::VerifyValidSlots(heap()); |
| 325 } | 325 } |
| 326 #endif | 326 #endif |
| 327 } | 327 } |
| 328 | 328 |
| 329 | |
| 330 void MarkCompactCollector::CollectGarbage() { | 329 void MarkCompactCollector::CollectGarbage() { |
| 331 // Make sure that Prepare() has been called. The individual steps below will | 330 // Make sure that Prepare() has been called. The individual steps below will |
| 332 // update the state as they proceed. | 331 // update the state as they proceed. |
| 333 DCHECK(state_ == PREPARE_GC); | 332 DCHECK(state_ == PREPARE_GC); |
| 334 | 333 |
| 335 MarkLiveObjects(); | 334 MarkLiveObjects(); |
| 336 | 335 |
| 337 DCHECK(heap_->incremental_marking()->IsStopped()); | 336 DCHECK(heap_->incremental_marking()->IsStopped()); |
| 338 | 337 |
| 339 ClearNonLiveReferences(); | 338 ClearNonLiveReferences(); |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1295 // Visit the fields of the RegExp, including the updated FixedArray. | 1294 // Visit the fields of the RegExp, including the updated FixedArray. |
| 1296 VisitJSRegExp(map, object); | 1295 VisitJSRegExp(map, object); |
| 1297 } | 1296 } |
| 1298 }; | 1297 }; |
| 1299 | 1298 |
| 1300 | 1299 |
| 1301 void MarkCompactMarkingVisitor::Initialize() { | 1300 void MarkCompactMarkingVisitor::Initialize() { |
| 1302 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); | 1301 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); |
| 1303 | 1302 |
| 1304 table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode); | 1303 table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode); |
| 1305 | |
| 1306 if (FLAG_track_gc_object_stats) { | |
| 1307 MarkCompactObjectStatsVisitor::Initialize(&table_); | |
| 1308 } | |
| 1309 } | 1304 } |
| 1310 | 1305 |
| 1311 | 1306 |
| 1312 class CodeMarkingVisitor : public ThreadVisitor { | 1307 class CodeMarkingVisitor : public ThreadVisitor { |
| 1313 public: | 1308 public: |
| 1314 explicit CodeMarkingVisitor(MarkCompactCollector* collector) | 1309 explicit CodeMarkingVisitor(MarkCompactCollector* collector) |
| 1315 : collector_(collector) {} | 1310 : collector_(collector) {} |
| 1316 | 1311 |
| 1317 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 1312 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
| 1318 collector_->PrepareThreadForCodeFlushing(isolate, top); | 1313 collector_->PrepareThreadForCodeFlushing(isolate, top); |
| (...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2275 } | 2270 } |
| 2276 | 2271 |
| 2277 void MarkCompactCollector::RegisterExternallyReferencedObject(Object** object) { | 2272 void MarkCompactCollector::RegisterExternallyReferencedObject(Object** object) { |
| 2278 DCHECK(in_use()); | 2273 DCHECK(in_use()); |
| 2279 HeapObject* heap_object = HeapObject::cast(*object); | 2274 HeapObject* heap_object = HeapObject::cast(*object); |
| 2280 DCHECK(heap_->Contains(heap_object)); | 2275 DCHECK(heap_->Contains(heap_object)); |
| 2281 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); | 2276 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); |
| 2282 MarkObject(heap_object, mark_bit); | 2277 MarkObject(heap_object, mark_bit); |
| 2283 } | 2278 } |
| 2284 | 2279 |
| 2280 class MarkCompactCollector::ObjectStatsVisitor | |
| 2281 : public MarkCompactCollector::HeapObjectVisitor { | |
| 2282 public: | |
| 2283 ObjectStatsVisitor(ObjectStats* live_stats, ObjectStats* dead_stats) | |
| 2284 : live_stats_(live_stats), dead_stats_(dead_stats) {} | |
| 2285 | |
| 2286 bool Visit(HeapObject* obj) override { | |
| 2287 if (Marking::IsBlack(Marking::MarkBitFrom(obj))) { | |
| 2288 if (live_stats_ != nullptr) | |
| 2289 ObjectStatsCollector::CollectStatistics(live_stats_, obj); | |
| 2290 } else { | |
| 2291 if (dead_stats_ != nullptr) | |
| 2292 ObjectStatsCollector::CollectStatistics(dead_stats_, obj); | |
| 2293 } | |
| 2294 return true; | |
| 2295 } | |
| 2296 | |
| 2297 private: | |
| 2298 ObjectStats* live_stats_; | |
| 2299 ObjectStats* dead_stats_; | |
| 2300 }; | |
| 2301 | |
| 2302 void MarkCompactCollector::VisitAllObjects(HeapObjectVisitor* visitor) { | |
| 2303 SpaceIterator space_it(heap()); | |
|
Michael Lippautz
2016/07/13 10:10:00
Hannes: Your HeapObjectIterator changes have been
Hannes Payer (out of office)
2016/07/13 11:39:11
Yeah, for snapshot reasons. Just use your custom i
Michael Lippautz
2016/07/13 12:20:17
Acknowledged.
| |
| 2304 HeapObject* obj = nullptr; | |
| 2305 while (space_it.has_next()) { | |
| 2306 ObjectIterator* it = space_it.next(); | |
| 2307 while ((obj = it->Next()) != nullptr) { | |
| 2308 visitor->Visit(obj); | |
| 2309 } | |
| 2310 } | |
| 2311 } | |
| 2312 | |
| 2285 void MarkCompactCollector::MarkLiveObjects() { | 2313 void MarkCompactCollector::MarkLiveObjects() { |
| 2286 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK); | 2314 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK); |
| 2287 double start_time = 0.0; | 2315 double start_time = 0.0; |
| 2288 if (FLAG_print_cumulative_gc_stat) { | 2316 if (FLAG_print_cumulative_gc_stat) { |
| 2289 start_time = heap_->MonotonicallyIncreasingTimeInMs(); | 2317 start_time = heap_->MonotonicallyIncreasingTimeInMs(); |
| 2290 } | 2318 } |
| 2291 // The recursive GC marker detects when it is nearing stack overflow, | 2319 // The recursive GC marker detects when it is nearing stack overflow, |
| 2292 // and switches to a different marking system. JS interrupts interfere | 2320 // and switches to a different marking system. JS interrupts interfere |
| 2293 // with the C stack limit check. | 2321 // with the C stack limit check. |
| 2294 PostponeInterruptsScope postpone(isolate()); | 2322 PostponeInterruptsScope postpone(isolate()); |
| 2295 | 2323 |
| 2296 { | 2324 { |
| 2297 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_FINISH_INCREMENTAL); | 2325 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_FINISH_INCREMENTAL); |
| 2298 IncrementalMarking* incremental_marking = heap_->incremental_marking(); | 2326 IncrementalMarking* incremental_marking = heap_->incremental_marking(); |
| 2299 if (was_marked_incrementally_) { | 2327 if (was_marked_incrementally_) { |
| 2300 incremental_marking->Finalize(); | 2328 incremental_marking->Finalize(); |
| 2301 } else { | 2329 } else { |
| 2302 // Abort any pending incremental activities e.g. incremental sweeping. | 2330 // Abort any pending incremental activities e.g. incremental sweeping. |
| 2303 incremental_marking->Stop(); | 2331 incremental_marking->Stop(); |
| 2304 if (FLAG_track_gc_object_stats) { | |
| 2305 // Clear object stats collected during incremental marking. | |
| 2306 heap()->object_stats_->ClearObjectStats(); | |
| 2307 } | |
| 2308 if (marking_deque_.in_use()) { | 2332 if (marking_deque_.in_use()) { |
| 2309 marking_deque_.Uninitialize(true); | 2333 marking_deque_.Uninitialize(true); |
| 2310 } | 2334 } |
| 2311 } | 2335 } |
| 2312 } | 2336 } |
| 2313 | 2337 |
| 2314 #ifdef DEBUG | 2338 #ifdef DEBUG |
| 2315 DCHECK(state_ == PREPARE_GC); | 2339 DCHECK(state_ == PREPARE_GC); |
| 2316 state_ = MARK_LIVE_OBJECTS; | 2340 state_ = MARK_LIVE_OBJECTS; |
| 2317 #endif | 2341 #endif |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2380 } | 2404 } |
| 2381 } | 2405 } |
| 2382 } | 2406 } |
| 2383 | 2407 |
| 2384 if (FLAG_print_cumulative_gc_stat) { | 2408 if (FLAG_print_cumulative_gc_stat) { |
| 2385 heap_->tracer()->AddMarkingTime(heap_->MonotonicallyIncreasingTimeInMs() - | 2409 heap_->tracer()->AddMarkingTime(heap_->MonotonicallyIncreasingTimeInMs() - |
| 2386 start_time); | 2410 start_time); |
| 2387 } | 2411 } |
| 2388 if (FLAG_track_gc_object_stats) { | 2412 if (FLAG_track_gc_object_stats) { |
| 2389 if (FLAG_trace_gc_object_stats) { | 2413 if (FLAG_trace_gc_object_stats) { |
| 2390 heap()->object_stats_->TraceObjectStats(); | 2414 // Reuse the live stats that are already recorded with |
| 2415 // --track_gc_object_stats. | |
| 2416 ObjectStats dead_stats(heap()); | |
| 2417 ObjectStatsVisitor visitor(heap()->object_stats_, &dead_stats); | |
| 2418 VisitAllObjects(&visitor); | |
| 2419 heap()->object_stats_->PrintJSON("live"); | |
| 2420 dead_stats.PrintJSON("dead"); | |
| 2421 } else { | |
| 2422 ObjectStatsVisitor visitor(heap()->object_stats_, nullptr); | |
| 2423 VisitAllObjects(&visitor); | |
| 2391 } | 2424 } |
| 2392 heap()->object_stats_->CheckpointObjectStats(); | 2425 heap()->object_stats_->CheckpointObjectStats(); |
| 2393 } | 2426 } |
| 2394 } | 2427 } |
| 2395 | 2428 |
| 2396 | 2429 |
| 2397 void MarkCompactCollector::ClearNonLiveReferences() { | 2430 void MarkCompactCollector::ClearNonLiveReferences() { |
| 2398 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR); | 2431 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR); |
| 2399 | 2432 |
| 2400 { | 2433 { |
| (...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4086 // The target is always in old space, we don't have to record the slot in | 4119 // The target is always in old space, we don't have to record the slot in |
| 4087 // the old-to-new remembered set. | 4120 // the old-to-new remembered set. |
| 4088 DCHECK(!heap()->InNewSpace(target)); | 4121 DCHECK(!heap()->InNewSpace(target)); |
| 4089 RecordRelocSlot(host, &rinfo, target); | 4122 RecordRelocSlot(host, &rinfo, target); |
| 4090 } | 4123 } |
| 4091 } | 4124 } |
| 4092 } | 4125 } |
| 4093 | 4126 |
| 4094 } // namespace internal | 4127 } // namespace internal |
| 4095 } // namespace v8 | 4128 } // namespace v8 |
| OLD | NEW |