Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Unified Diff: src/heap.cc

Issue 2132005: Improved GC statistics (cumulative and per collection). (Closed)
Patch Set: fixed Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap.h ('k') | src/mark-compact.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 0a276ca9959e1b6ffedfbfba3b23d4e75d35419e..d33d91ab4ad8f8e85fca4609b69fa56b5b9f7097 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -115,8 +115,11 @@ int Heap::external_allocation_limit_ = 0;
Heap::HeapState Heap::gc_state_ = NOT_IN_GC;
int Heap::mc_count_ = 0;
+int Heap::ms_count_ = 0;
int Heap::gc_count_ = 0;
+GCTracer* Heap::tracer_ = NULL;
+
int Heap::unflattened_strings_length_ = 0;
int Heap::always_allocate_scope_depth_ = 0;
@@ -130,6 +133,11 @@ int Heap::allocation_timeout_ = 0;
bool Heap::disallow_allocation_failure_ = false;
#endif // DEBUG
+int GCTracer::alive_after_last_gc_ = 0;
+double GCTracer::last_gc_end_timestamp_ = 0.0;
+int GCTracer::max_gc_pause_ = 0;
+int GCTracer::max_alive_after_gc_ = 0;
+int GCTracer::min_in_mutator_ = kMaxInt;
int Heap::Capacity() {
if (!HasBeenSetup()) return 0;
@@ -570,7 +578,7 @@ void Heap::PerformGarbageCollection(AllocationSpace space,
VerifySymbolTable();
if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) {
ASSERT(!allocation_allowed_);
- GCTracer::ExternalScope scope(tracer);
+ GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
global_gc_prologue_callback_();
}
@@ -596,14 +604,16 @@ void Heap::PerformGarbageCollection(AllocationSpace space,
old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2);
old_gen_exhausted_ = false;
} else {
+ tracer_ = tracer;
Scavenge();
+ tracer_ = NULL;
}
Counters::objs_since_last_young.Set(0);
if (collector == MARK_COMPACTOR) {
DisableAssertNoAllocation allow_allocation;
- GCTracer::ExternalScope scope(tracer);
+ GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
GlobalHandles::PostGarbageCollectionProcessing();
}
@@ -627,7 +637,7 @@ void Heap::PerformGarbageCollection(AllocationSpace space,
if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) {
ASSERT(!allocation_allowed_);
- GCTracer::ExternalScope scope(tracer);
+ GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
global_gc_epilogue_callback_();
}
VerifySymbolTable();
@@ -636,7 +646,11 @@ void Heap::PerformGarbageCollection(AllocationSpace space,
void Heap::MarkCompact(GCTracer* tracer) {
gc_state_ = MARK_COMPACT;
- mc_count_++;
+ if (MarkCompactCollector::IsCompacting()) {
+ mc_count_++;
+ } else {
+ ms_count_++;
+ }
tracer->set_full_gc_count(mc_count_);
LOG(ResourceEvent("markcompact", "begin"));
@@ -1179,6 +1193,7 @@ void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) {
node->set_size(object_size);
*p = target;
+ tracer()->increment_promoted_objects_size(object_size);
return;
}
} else {
@@ -1214,6 +1229,7 @@ void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) {
(*p)->Iterate(&v);
#endif
}
+ tracer()->increment_promoted_objects_size(object_size);
return;
}
}
@@ -3760,6 +3776,17 @@ void Heap::SetStackLimits() {
void Heap::TearDown() {
+ if (FLAG_print_cumulative_gc_stat) {
+ PrintF("\n\n");
+ PrintF("gc_count=%d ", gc_count_);
+ PrintF("mark_sweep_count=%d ", ms_count_);
+ PrintF("mark_compact_count=%d ", mc_count_);
+ PrintF("max_gc_pause=%d ", GCTracer::get_max_gc_pause());
+ PrintF("min_in_mutator=%d ", GCTracer::get_min_in_mutator());
+ PrintF("max_alive_after_gc=%d ", GCTracer::get_max_alive_after_gc());
+ PrintF("\n\n");
+ }
+
GlobalHandles::TearDown();
ExternalStringTable::TearDown();
@@ -4235,33 +4262,114 @@ void Heap::TracePathToGlobal() {
#endif
+static int CountTotalHolesSize() {
+ int holes_size = 0;
+ OldSpaces spaces;
+ for (OldSpace* space = spaces.next();
+ space != NULL;
+ space = spaces.next()) {
+ holes_size += space->Waste() + space->AvailableFree();
+ }
+ return holes_size;
+}
+
+
GCTracer::GCTracer()
: start_time_(0.0),
- start_size_(0.0),
- external_time_(0.0),
+ start_size_(0),
gc_count_(0),
full_gc_count_(0),
is_compacting_(false),
- marked_count_(0) {
+ marked_count_(0),
+ allocated_since_last_gc_(0),
+ spent_in_mutator_(0),
+ promoted_objects_size_(0) {
// These two fields reflect the state of the previous full collection.
// Set them before they are changed by the collector.
previous_has_compacted_ = MarkCompactCollector::HasCompacted();
previous_marked_count_ = MarkCompactCollector::previous_marked_count();
- if (!FLAG_trace_gc) return;
+ if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
start_time_ = OS::TimeCurrentMillis();
- start_size_ = SizeOfHeapObjects();
+ start_size_ = Heap::SizeOfObjects();
+
+ for (int i = 0; i < Scope::kNumberOfScopes; i++) {
+ scopes_[i] = 0;
+ }
+
+ in_free_list_or_wasted_before_gc_ = CountTotalHolesSize();
+
+ allocated_since_last_gc_ = Heap::SizeOfObjects() - alive_after_last_gc_;
+
+ if (last_gc_end_timestamp_ > 0) {
+ spent_in_mutator_ = Max(start_time_ - last_gc_end_timestamp_, 0.0);
+ }
}
GCTracer::~GCTracer() {
- if (!FLAG_trace_gc) return;
// Printf ONE line iff flag is set.
- int time = static_cast<int>(OS::TimeCurrentMillis() - start_time_);
- int external_time = static_cast<int>(external_time_);
- PrintF("%s %.1f -> %.1f MB, ",
- CollectorString(), start_size_, SizeOfHeapObjects());
- if (external_time > 0) PrintF("%d / ", external_time);
- PrintF("%d ms.\n", time);
+ if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
+
+ bool first_gc = (last_gc_end_timestamp_ == 0);
+
+ alive_after_last_gc_ = Heap::SizeOfObjects();
+ last_gc_end_timestamp_ = OS::TimeCurrentMillis();
+
+ int time = static_cast<int>(last_gc_end_timestamp_ - start_time_);
+
+ // Update cumulative GC statistics if required.
+ if (FLAG_print_cumulative_gc_stat) {
+ max_gc_pause_ = Max(max_gc_pause_, time);
+ max_alive_after_gc_ = Max(max_alive_after_gc_, alive_after_last_gc_);
+ if (!first_gc) {
+ min_in_mutator_ = Min(min_in_mutator_,
+ static_cast<int>(spent_in_mutator_));
+ }
+ }
+
+ if (!FLAG_trace_gc_nvp) {
+ int external_time = static_cast<int>(scopes_[Scope::EXTERNAL]);
+
+ PrintF("%s %.1f -> %.1f MB, ",
+ CollectorString(),
+ static_cast<double>(start_size_) / MB,
+ SizeOfHeapObjects());
+
+ if (external_time > 0) PrintF("%d / ", external_time);
+ PrintF("%d ms.\n", time);
+ } else {
+ PrintF("pause=%d ", time);
+ PrintF("mutator=%d ",
+ static_cast<int>(spent_in_mutator_));
+
+ PrintF("gc=");
+ switch (collector_) {
+ case SCAVENGER:
+ PrintF("s");
+ break;
+ case MARK_COMPACTOR:
+ PrintF(MarkCompactCollector::HasCompacted() ? "mc" : "ms");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ PrintF(" ");
+
+ PrintF("external=%d ", static_cast<int>(scopes_[Scope::EXTERNAL]));
+ PrintF("mark=%d ", static_cast<int>(scopes_[Scope::MC_MARK]));
+ PrintF("sweep=%d ", static_cast<int>(scopes_[Scope::MC_SWEEP]));
+ PrintF("compact=%d ", static_cast<int>(scopes_[Scope::MC_COMPACT]));
+
+ PrintF("total_size_before=%d ", start_size_);
+ PrintF("total_size_after=%d ", Heap::SizeOfObjects());
+ PrintF("holes_size_before=%d ", in_free_list_or_wasted_before_gc_);
+ PrintF("holes_size_after=%d ", CountTotalHolesSize());
+
+ PrintF("allocated=%d ", allocated_since_last_gc_);
+ PrintF("promoted=%d ", promoted_objects_size_);
+
+ PrintF("\n");
+ }
#if defined(ENABLE_LOGGING_AND_PROFILING)
Heap::PrintShortHeapStatistics();
« no previous file with comments | « src/heap.h ('k') | src/mark-compact.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698