Commit 14732265 authored by mvstanton's avatar mvstanton Committed by Commit bot

Machine-readable TurboFan compiler statistics

We'd like to track performance metrics in an automated way. This CL introduces
--turbo-stats-nvp which exposes --turbo-stats information in {"name"=value} pair
format.

BUG=

Review-Url: https://codereview.chromium.org/2053383002
Cr-Commit-Position: refs/heads/master@{#36919}
parent 3400ee9f
...@@ -54,8 +54,7 @@ void CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) { ...@@ -54,8 +54,7 @@ void CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) {
} }
} }
static void WriteLine(std::ostream& os, bool machine_format, const char* name,
static void WriteLine(std::ostream& os, const char* name,
const CompilationStatistics::BasicStats& stats, const CompilationStatistics::BasicStats& stats,
const CompilationStatistics::BasicStats& total_stats) { const CompilationStatistics::BasicStats& total_stats) {
const size_t kBufferSize = 128; const size_t kBufferSize = 128;
...@@ -66,6 +65,12 @@ static void WriteLine(std::ostream& os, const char* name, ...@@ -66,6 +65,12 @@ static void WriteLine(std::ostream& os, const char* name,
double size_percent = double size_percent =
static_cast<double>(stats.total_allocated_bytes_ * 100) / static_cast<double>(stats.total_allocated_bytes_ * 100) /
static_cast<double>(total_stats.total_allocated_bytes_); static_cast<double>(total_stats.total_allocated_bytes_);
if (machine_format) {
base::OS::SNPrintF(buffer, kBufferSize,
"\"%s_time\"=%.3f\n\"%s_space\"=%" PRIuS, name, ms, name,
stats.total_allocated_bytes_);
os << buffer;
} else {
base::OS::SNPrintF(buffer, kBufferSize, "%28s %10.3f (%5.1f%%) %10" PRIuS base::OS::SNPrintF(buffer, kBufferSize, "%28s %10.3f (%5.1f%%) %10" PRIuS
" (%5.1f%%) %10" PRIuS " %10" PRIuS, " (%5.1f%%) %10" PRIuS " %10" PRIuS,
name, ms, percent, stats.total_allocated_bytes_, name, ms, percent, stats.total_allocated_bytes_,
...@@ -77,6 +82,7 @@ static void WriteLine(std::ostream& os, const char* name, ...@@ -77,6 +82,7 @@ static void WriteLine(std::ostream& os, const char* name,
os << " " << stats.function_name_.c_str(); os << " " << stats.function_name_.c_str();
} }
os << std::endl; os << std::endl;
}
} }
...@@ -101,10 +107,10 @@ static void WritePhaseKindBreak(std::ostream& os) { ...@@ -101,10 +107,10 @@ static void WritePhaseKindBreak(std::ostream& os) {
"--------------------------------------------------------\n"; "--------------------------------------------------------\n";
} }
std::ostream& operator<<(std::ostream& os, const AsPrintableStatistics& ps) {
std::ostream& operator<<(std::ostream& os, const CompilationStatistics& s) {
// phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of // phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of
// pointers into them. // pointers into them.
const CompilationStatistics& s = ps.s;
typedef std::vector<CompilationStatistics::PhaseKindMap::const_iterator> typedef std::vector<CompilationStatistics::PhaseKindMap::const_iterator>
SortedPhaseKinds; SortedPhaseKinds;
...@@ -121,22 +127,27 @@ std::ostream& operator<<(std::ostream& os, const CompilationStatistics& s) { ...@@ -121,22 +127,27 @@ std::ostream& operator<<(std::ostream& os, const CompilationStatistics& s) {
sorted_phases[it->second.insert_order_] = it; sorted_phases[it->second.insert_order_] = it;
} }
WriteHeader(os); if (!ps.machine_output) WriteHeader(os);
for (auto phase_kind_it : sorted_phase_kinds) { for (auto phase_kind_it : sorted_phase_kinds) {
const auto& phase_kind_name = phase_kind_it->first; const auto& phase_kind_name = phase_kind_it->first;
if (!ps.machine_output) {
for (auto phase_it : sorted_phases) { for (auto phase_it : sorted_phases) {
const auto& phase_stats = phase_it->second; const auto& phase_stats = phase_it->second;
if (phase_stats.phase_kind_name_ != phase_kind_name) continue; if (phase_stats.phase_kind_name_ != phase_kind_name) continue;
const auto& phase_name = phase_it->first; const auto& phase_name = phase_it->first;
WriteLine(os, phase_name.c_str(), phase_stats, s.total_stats_); WriteLine(os, ps.machine_output, phase_name.c_str(), phase_stats,
s.total_stats_);
} }
WritePhaseKindBreak(os); WritePhaseKindBreak(os);
}
const auto& phase_kind_stats = phase_kind_it->second; const auto& phase_kind_stats = phase_kind_it->second;
WriteLine(os, phase_kind_name.c_str(), phase_kind_stats, s.total_stats_); WriteLine(os, ps.machine_output, phase_kind_name.c_str(), phase_kind_stats,
s.total_stats_);
os << std::endl; os << std::endl;
} }
WriteFullLine(os);
WriteLine(os, "totals", s.total_stats_, s.total_stats_); if (!ps.machine_output) WriteFullLine(os);
WriteLine(os, ps.machine_output, "totals", s.total_stats_, s.total_stats_);
return os; return os;
} }
......
...@@ -15,6 +15,12 @@ namespace v8 { ...@@ -15,6 +15,12 @@ namespace v8 {
namespace internal { namespace internal {
class CompilationInfo; class CompilationInfo;
class CompilationStatistics;
struct AsPrintableStatistics {
const CompilationStatistics& s;
const bool machine_output;
};
class CompilationStatistics final : public Malloced { class CompilationStatistics final : public Malloced {
public: public:
...@@ -65,7 +71,7 @@ class CompilationStatistics final : public Malloced { ...@@ -65,7 +71,7 @@ class CompilationStatistics final : public Malloced {
}; };
friend std::ostream& operator<<(std::ostream& os, friend std::ostream& operator<<(std::ostream& os,
const CompilationStatistics& s); const AsPrintableStatistics& s);
typedef OrderedStats PhaseKindStats; typedef OrderedStats PhaseKindStats;
typedef std::map<std::string, PhaseKindStats> PhaseKindMap; typedef std::map<std::string, PhaseKindStats> PhaseKindMap;
...@@ -78,7 +84,7 @@ class CompilationStatistics final : public Malloced { ...@@ -78,7 +84,7 @@ class CompilationStatistics final : public Malloced {
DISALLOW_COPY_AND_ASSIGN(CompilationStatistics); DISALLOW_COPY_AND_ASSIGN(CompilationStatistics);
}; };
std::ostream& operator<<(std::ostream& os, const CompilationStatistics& s); std::ostream& operator<<(std::ostream& os, const AsPrintableStatistics& s);
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -521,7 +521,7 @@ PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info, ...@@ -521,7 +521,7 @@ PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info,
ZonePool* zone_pool) { ZonePool* zone_pool) {
PipelineStatistics* pipeline_statistics = nullptr; PipelineStatistics* pipeline_statistics = nullptr;
if (FLAG_turbo_stats) { if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
pipeline_statistics = new PipelineStatistics(info, zone_pool); pipeline_statistics = new PipelineStatistics(info, zone_pool);
pipeline_statistics->BeginPhaseKind("initializing"); pipeline_statistics->BeginPhaseKind("initializing");
} }
...@@ -1503,7 +1503,7 @@ Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, ...@@ -1503,7 +1503,7 @@ Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate,
ZonePool zone_pool(isolate->allocator()); ZonePool zone_pool(isolate->allocator());
PipelineData data(&zone_pool, &info, graph, schedule); PipelineData data(&zone_pool, &info, graph, schedule);
base::SmartPointer<PipelineStatistics> pipeline_statistics; base::SmartPointer<PipelineStatistics> pipeline_statistics;
if (FLAG_turbo_stats) { if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool)); pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool));
pipeline_statistics->BeginPhaseKind("stub codegen"); pipeline_statistics->BeginPhaseKind("stub codegen");
} }
...@@ -1557,7 +1557,7 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, ...@@ -1557,7 +1557,7 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
ZonePool zone_pool(info->isolate()->allocator()); ZonePool zone_pool(info->isolate()->allocator());
PipelineData data(&zone_pool, info, graph, schedule); PipelineData data(&zone_pool, info, graph, schedule);
base::SmartPointer<PipelineStatistics> pipeline_statistics; base::SmartPointer<PipelineStatistics> pipeline_statistics;
if (FLAG_turbo_stats) { if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool)); pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool));
pipeline_statistics->BeginPhaseKind("test codegen"); pipeline_statistics->BeginPhaseKind("test codegen");
} }
......
...@@ -449,6 +449,8 @@ DEFINE_BOOL(turbo_asm_deoptimization, false, ...@@ -449,6 +449,8 @@ DEFINE_BOOL(turbo_asm_deoptimization, false,
"enable deoptimization in TurboFan for asm.js code") "enable deoptimization in TurboFan for asm.js code")
DEFINE_BOOL(turbo_verify, DEBUG_BOOL, "verify TurboFan graphs at each phase") DEFINE_BOOL(turbo_verify, DEBUG_BOOL, "verify TurboFan graphs at each phase")
DEFINE_BOOL(turbo_stats, false, "print TurboFan statistics") DEFINE_BOOL(turbo_stats, false, "print TurboFan statistics")
DEFINE_BOOL(turbo_stats_nvp, false,
"print TurboFan statistics in machine-readable format")
DEFINE_BOOL(turbo_splitting, true, "split nodes during scheduling in TurboFan") DEFINE_BOOL(turbo_splitting, true, "split nodes during scheduling in TurboFan")
DEFINE_BOOL(turbo_type_feedback, false, DEFINE_BOOL(turbo_type_feedback, false,
"use typed feedback for representation inference in Turbofan") "use typed feedback for representation inference in Turbofan")
......
...@@ -2450,8 +2450,17 @@ void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) { ...@@ -2450,8 +2450,17 @@ void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
void Isolate::DumpAndResetCompilationStats() { void Isolate::DumpAndResetCompilationStats() {
if (turbo_statistics() != nullptr) { if (turbo_statistics() != nullptr) {
DCHECK(FLAG_turbo_stats || FLAG_turbo_stats_nvp);
OFStream os(stdout); OFStream os(stdout);
os << *turbo_statistics() << std::endl; if (FLAG_turbo_stats) {
AsPrintableStatistics ps = {*turbo_statistics(), false};
os << ps << std::endl;
}
if (FLAG_turbo_stats_nvp) {
AsPrintableStatistics ps = {*turbo_statistics(), true};
os << ps << std::endl;
}
} }
if (hstatistics() != nullptr) hstatistics()->Print(); if (hstatistics() != nullptr) hstatistics()->Print();
delete turbo_statistics_; delete turbo_statistics_;
......
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