Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index 51d114a7ab047da667134fae6de4907d2f8d34f1..f153634c9c9d5719592eeee2429bad584f7bedcb 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -326,7 +326,6 @@ void MarkCompactCollector::ClearInvalidRememberedSetSlots() { |
#endif |
} |
- |
void MarkCompactCollector::CollectGarbage() { |
// Make sure that Prepare() has been called. The individual steps below will |
// update the state as they proceed. |
@@ -1302,10 +1301,6 @@ void MarkCompactMarkingVisitor::Initialize() { |
StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); |
table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode); |
- |
- if (FLAG_track_gc_object_stats) { |
- MarkCompactObjectStatsVisitor::Initialize(&table_); |
- } |
} |
@@ -2282,6 +2277,39 @@ void MarkCompactCollector::RegisterExternallyReferencedObject(Object** object) { |
MarkObject(heap_object, mark_bit); |
} |
+class MarkCompactCollector::ObjectStatsVisitor |
+ : public MarkCompactCollector::HeapObjectVisitor { |
+ public: |
+ ObjectStatsVisitor(ObjectStats* live_stats, ObjectStats* dead_stats) |
+ : live_stats_(live_stats), dead_stats_(dead_stats) {} |
+ |
+ bool Visit(HeapObject* obj) override { |
+ if (Marking::IsBlack(Marking::MarkBitFrom(obj))) { |
+ if (live_stats_ != nullptr) |
+ ObjectStatsCollector::CollectStatistics(live_stats_, obj); |
+ } else { |
+ if (dead_stats_ != nullptr) |
+ ObjectStatsCollector::CollectStatistics(dead_stats_, obj); |
+ } |
+ return true; |
+ } |
+ |
+ private: |
+ ObjectStats* live_stats_; |
+ ObjectStats* dead_stats_; |
+}; |
+ |
+void MarkCompactCollector::VisitAllObjects(HeapObjectVisitor* visitor) { |
+ 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.
|
+ HeapObject* obj = nullptr; |
+ while (space_it.has_next()) { |
+ ObjectIterator* it = space_it.next(); |
+ while ((obj = it->Next()) != nullptr) { |
+ visitor->Visit(obj); |
+ } |
+ } |
+} |
+ |
void MarkCompactCollector::MarkLiveObjects() { |
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK); |
double start_time = 0.0; |
@@ -2301,10 +2329,6 @@ void MarkCompactCollector::MarkLiveObjects() { |
} else { |
// Abort any pending incremental activities e.g. incremental sweeping. |
incremental_marking->Stop(); |
- if (FLAG_track_gc_object_stats) { |
- // Clear object stats collected during incremental marking. |
- heap()->object_stats_->ClearObjectStats(); |
- } |
if (marking_deque_.in_use()) { |
marking_deque_.Uninitialize(true); |
} |
@@ -2387,7 +2411,16 @@ void MarkCompactCollector::MarkLiveObjects() { |
} |
if (FLAG_track_gc_object_stats) { |
if (FLAG_trace_gc_object_stats) { |
- heap()->object_stats_->TraceObjectStats(); |
+ // Reuse the live stats that are already recorded with |
+ // --track_gc_object_stats. |
+ ObjectStats dead_stats(heap()); |
+ ObjectStatsVisitor visitor(heap()->object_stats_, &dead_stats); |
+ VisitAllObjects(&visitor); |
+ heap()->object_stats_->PrintJSON("live"); |
+ dead_stats.PrintJSON("dead"); |
+ } else { |
+ ObjectStatsVisitor visitor(heap()->object_stats_, nullptr); |
+ VisitAllObjects(&visitor); |
} |
heap()->object_stats_->CheckpointObjectStats(); |
} |