Factor out a Histogram class from HistogramTimer, and use it to measure external fragmentation

BUG=none
TEST=none

Review URL: https://chromiumcodereview.appspot.com/10695056
Patch from Jochen Eisinger <jochen@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12081 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent acc4edea
// Copyright 2007-2008 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -64,9 +64,20 @@ void StatsCounterTimer::Stop() { ...@@ -64,9 +64,20 @@ void StatsCounterTimer::Stop() {
counter_.Increment(milliseconds); counter_.Increment(milliseconds);
} }
void Histogram::AddSample(int sample) {
if (Enabled()) {
Isolate::Current()->stats_table()->AddHistogramSample(histogram_, sample);
}
}
void* Histogram::CreateHistogram() const {
return Isolate::Current()->stats_table()->
CreateHistogram(name_, min_, max_, num_buckets_);
}
// Start the timer. // Start the timer.
void HistogramTimer::Start() { void HistogramTimer::Start() {
if (GetHistogram() != NULL) { if (histogram_.Enabled()) {
stop_time_ = 0; stop_time_ = 0;
start_time_ = OS::Ticks(); start_time_ = OS::Ticks();
} }
...@@ -74,20 +85,13 @@ void HistogramTimer::Start() { ...@@ -74,20 +85,13 @@ void HistogramTimer::Start() {
// Stop the timer and record the results. // Stop the timer and record the results.
void HistogramTimer::Stop() { void HistogramTimer::Stop() {
if (histogram_ != NULL) { if (histogram_.Enabled()) {
stop_time_ = OS::Ticks(); stop_time_ = OS::Ticks();
// Compute the delta between start and stop, in milliseconds. // Compute the delta between start and stop, in milliseconds.
int milliseconds = static_cast<int>(stop_time_ - start_time_) / 1000; int milliseconds = static_cast<int>(stop_time_ - start_time_) / 1000;
Isolate::Current()->stats_table()-> histogram_.AddSample(milliseconds);
AddHistogramSample(histogram_, milliseconds);
} }
} }
void* HistogramTimer::CreateHistogram() const {
return Isolate::Current()->stats_table()->
CreateHistogram(name_, 0, 10000, 50);
}
} } // namespace v8::internal } } // namespace v8::internal
// Copyright 2007-2008 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -169,8 +169,7 @@ struct StatsCounter { ...@@ -169,8 +169,7 @@ struct StatsCounter {
protected: protected:
// Returns the cached address of this counter location. // Returns the cached address of this counter location.
int* GetPtr() { int* GetPtr() {
if (lookup_done_) if (lookup_done_) return ptr_;
return ptr_;
lookup_done_ = true; lookup_done_ = true;
ptr_ = FindLocationInStatsTable(); ptr_ = FindLocationInStatsTable();
return ptr_; return ptr_;
...@@ -199,25 +198,25 @@ struct StatsCounterTimer { ...@@ -199,25 +198,25 @@ struct StatsCounterTimer {
} }
}; };
// A HistogramTimer allows distributions of results to be created // A Histogram represents a dynamically created histogram in the StatsTable.
// HistogramTimer t = { L"foo", NULL, false, 0, 0 }; //
struct HistogramTimer { // This class is designed to be POD initialized. It will be registered with
// the histogram system on first use. For example:
// Histogram h = { "myhist", 0, 10000, 50, NULL, false };
struct Histogram {
const char* name_; const char* name_;
int min_;
int max_;
int num_buckets_;
void* histogram_; void* histogram_;
bool lookup_done_; bool lookup_done_;
int64_t start_time_; // Add a single sample to this histogram.
int64_t stop_time_; void AddSample(int sample);
// Start the timer.
void Start();
// Stop the timer and record the results.
void Stop();
// Returns true if the timer is running. // Returns true if this histogram is enabled.
bool Running() { bool Enabled() {
return (histogram_ != NULL) && (start_time_ != 0) && (stop_time_ == 0); return GetHistogram() != NULL;
} }
protected: protected:
...@@ -234,6 +233,26 @@ struct HistogramTimer { ...@@ -234,6 +233,26 @@ struct HistogramTimer {
void* CreateHistogram() const; void* CreateHistogram() const;
}; };
// A HistogramTimer allows distributions of results to be created
// HistogramTimer t = { {L"foo", 0, 10000, 50, NULL, false}, 0, 0 };
struct HistogramTimer {
Histogram histogram_;
int64_t start_time_;
int64_t stop_time_;
// Start the timer.
void Start();
// Stop the timer and record the results.
void Stop();
// Returns true if the timer is running.
bool Running() {
return histogram_.Enabled() && (start_time_ != 0) && (stop_time_ == 0);
}
};
// Helper class for scoping a HistogramTimer. // Helper class for scoping a HistogramTimer.
class HistogramTimerScope BASE_EMBEDDED { class HistogramTimerScope BASE_EMBEDDED {
public: public:
......
...@@ -445,54 +445,26 @@ void Heap::GarbageCollectionEpilogue() { ...@@ -445,54 +445,26 @@ void Heap::GarbageCollectionEpilogue() {
isolate_->counters()->number_of_symbols()->Set( isolate_->counters()->number_of_symbols()->Set(
symbol_table()->NumberOfElements()); symbol_table()->NumberOfElements());
isolate_->counters()->new_space_bytes_available()->Set( #define UPDATE_COUNTERS_FOR_SPACE(space) \
static_cast<int>(new_space()->Available())); isolate_->counters()->space##_bytes_available()->Set( \
isolate_->counters()->new_space_bytes_committed()->Set( static_cast<int>(space()->Available())); \
static_cast<int>(new_space()->CommittedMemory())); isolate_->counters()->space##_bytes_committed()->Set( \
isolate_->counters()->new_space_bytes_used()->Set( static_cast<int>(space()->CommittedMemory())); \
static_cast<int>(new_space()->SizeOfObjects())); isolate_->counters()->space##_bytes_used()->Set( \
static_cast<int>(space()->SizeOfObjects())); \
isolate_->counters()->old_pointer_space_bytes_available()->Set( if (space()->CommittedMemory() > 0) { \
static_cast<int>(old_pointer_space()->Available())); isolate_->counters()->external_fragmentation_##space()->AddSample( \
isolate_->counters()->old_pointer_space_bytes_committed()->Set( static_cast<int>( \
static_cast<int>(old_pointer_space()->CommittedMemory())); (space()->SizeOfObjects() * 100) / space()->CommittedMemory())); \
isolate_->counters()->old_pointer_space_bytes_used()->Set( }
static_cast<int>(old_pointer_space()->SizeOfObjects())); UPDATE_COUNTERS_FOR_SPACE(new_space)
UPDATE_COUNTERS_FOR_SPACE(old_pointer_space)
isolate_->counters()->old_data_space_bytes_available()->Set( UPDATE_COUNTERS_FOR_SPACE(old_data_space)
static_cast<int>(old_data_space()->Available())); UPDATE_COUNTERS_FOR_SPACE(code_space)
isolate_->counters()->old_data_space_bytes_committed()->Set( UPDATE_COUNTERS_FOR_SPACE(map_space)
static_cast<int>(old_data_space()->CommittedMemory())); UPDATE_COUNTERS_FOR_SPACE(cell_space)
isolate_->counters()->old_data_space_bytes_used()->Set( UPDATE_COUNTERS_FOR_SPACE(lo_space)
static_cast<int>(old_data_space()->SizeOfObjects())); #undef UPDATE_COUNTERS_FOR_SPACE
isolate_->counters()->code_space_bytes_available()->Set(
static_cast<int>(code_space()->Available()));
isolate_->counters()->code_space_bytes_committed()->Set(
static_cast<int>(code_space()->CommittedMemory()));
isolate_->counters()->code_space_bytes_used()->Set(
static_cast<int>(code_space()->SizeOfObjects()));
isolate_->counters()->map_space_bytes_available()->Set(
static_cast<int>(map_space()->Available()));
isolate_->counters()->map_space_bytes_committed()->Set(
static_cast<int>(map_space()->CommittedMemory()));
isolate_->counters()->map_space_bytes_used()->Set(
static_cast<int>(map_space()->SizeOfObjects()));
isolate_->counters()->cell_space_bytes_available()->Set(
static_cast<int>(cell_space()->Available()));
isolate_->counters()->cell_space_bytes_committed()->Set(
static_cast<int>(cell_space()->CommittedMemory()));
isolate_->counters()->cell_space_bytes_used()->Set(
static_cast<int>(cell_space()->SizeOfObjects()));
isolate_->counters()->lo_space_bytes_available()->Set(
static_cast<int>(lo_space()->Available()));
isolate_->counters()->lo_space_bytes_committed()->Set(
static_cast<int>(lo_space()->CommittedMemory()));
isolate_->counters()->lo_space_bytes_used()->Set(
static_cast<int>(lo_space()->SizeOfObjects()));
#if defined(DEBUG) #if defined(DEBUG)
ReportStatisticsAfterGC(); ReportStatisticsAfterGC();
......
// Copyright 2007-2008 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -34,11 +34,17 @@ namespace internal { ...@@ -34,11 +34,17 @@ namespace internal {
Counters::Counters() { Counters::Counters() {
#define HT(name, caption) \ #define HT(name, caption) \
HistogramTimer name = { #caption, NULL, false, 0, 0 }; \ HistogramTimer name = { {#caption, 0, 10000, 50, NULL, false}, 0, 0 }; \
name##_ = name; name##_ = name;
HISTOGRAM_TIMER_LIST(HT) HISTOGRAM_TIMER_LIST(HT)
#undef HT #undef HT
#define HP(name, caption) \
Histogram name = { #caption, 0, 101, 100, NULL, false }; \
name##_ = name;
HISTOGRAM_PERCENTAGE_LIST(HP)
#undef HP
#define SC(name, caption) \ #define SC(name, caption) \
StatsCounter name = { "c:" #caption, NULL, false };\ StatsCounter name = { "c:" #caption, NULL, false };\
name##_ = name; name##_ = name;
......
// Copyright 2011 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -50,6 +50,23 @@ namespace internal { ...@@ -50,6 +50,23 @@ namespace internal {
HT(compile_lazy, V8.CompileLazy) HT(compile_lazy, V8.CompileLazy)
#define HISTOGRAM_PERCENTAGE_LIST(HP) \
HP(external_fragmentation_new_space, \
V8.MemoryExternalFragmentationNewSpace) \
HP(external_fragmentation_old_pointer_space, \
V8.MemoryExternalFragmentationOldPointerSpace) \
HP(external_fragmentation_old_data_space, \
V8.MemoryExternalFragmentationOldDataSpace) \
HP(external_fragmentation_code_space, \
V8.MemoryExternalFragmentationCodeSpace) \
HP(external_fragmentation_map_space, \
V8.MemoryExternalFragmentationMapSpace) \
HP(external_fragmentation_cell_space, \
V8.MemoryExternalFragmentationCellSpace) \
HP(external_fragmentation_lo_space, \
V8.MemoryExternalFragmentationLoSpace)
// WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC // WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC
// Intellisense to crash. It was broken into two macros (each of length 40 // Intellisense to crash. It was broken into two macros (each of length 40
// lines) rather than one macro (of length about 80 lines) to work around // lines) rather than one macro (of length about 80 lines) to work around
...@@ -280,6 +297,11 @@ class Counters { ...@@ -280,6 +297,11 @@ class Counters {
HISTOGRAM_TIMER_LIST(HT) HISTOGRAM_TIMER_LIST(HT)
#undef HT #undef HT
#define HP(name, caption) \
Histogram* name() { return &name##_; }
HISTOGRAM_PERCENTAGE_LIST(HP)
#undef HP
#define SC(name, caption) \ #define SC(name, caption) \
StatsCounter* name() { return &name##_; } StatsCounter* name() { return &name##_; }
STATS_COUNTER_LIST_1(SC) STATS_COUNTER_LIST_1(SC)
...@@ -290,6 +312,9 @@ class Counters { ...@@ -290,6 +312,9 @@ class Counters {
#define RATE_ID(name, caption) k_##name, #define RATE_ID(name, caption) k_##name,
HISTOGRAM_TIMER_LIST(RATE_ID) HISTOGRAM_TIMER_LIST(RATE_ID)
#undef RATE_ID #undef RATE_ID
#define PERCENTAGE_ID(name, caption) k_##name,
HISTOGRAM_PERCENTAGE_LIST(PERCENTAGE_ID)
#undef PERCENTAGE_ID
#define COUNTER_ID(name, caption) k_##name, #define COUNTER_ID(name, caption) k_##name,
STATS_COUNTER_LIST_1(COUNTER_ID) STATS_COUNTER_LIST_1(COUNTER_ID)
STATS_COUNTER_LIST_2(COUNTER_ID) STATS_COUNTER_LIST_2(COUNTER_ID)
...@@ -310,6 +335,11 @@ class Counters { ...@@ -310,6 +335,11 @@ class Counters {
HISTOGRAM_TIMER_LIST(HT) HISTOGRAM_TIMER_LIST(HT)
#undef HT #undef HT
#define HP(name, caption) \
Histogram name##_;
HISTOGRAM_PERCENTAGE_LIST(HP)
#undef HP
#define SC(name, caption) \ #define SC(name, caption) \
StatsCounter name##_; StatsCounter name##_;
STATS_COUNTER_LIST_1(SC) STATS_COUNTER_LIST_1(SC)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment