2014-10-23 09:14:35 +00:00
|
|
|
// Copyright 2014 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2014-10-23 11:19:44 +00:00
|
|
|
#include <ostream> // NOLINT(readability/streams)
|
2014-10-23 09:14:35 +00:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "src/base/platform/platform.h"
|
|
|
|
#include "src/compilation-statistics.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
|
|
|
void CompilationStatistics::RecordPhaseStats(const char* phase_kind_name,
|
|
|
|
const char* phase_name,
|
|
|
|
const BasicStats& stats) {
|
|
|
|
std::string phase_name_str(phase_name);
|
|
|
|
auto it = phase_map_.find(phase_name_str);
|
|
|
|
if (it == phase_map_.end()) {
|
|
|
|
PhaseStats phase_stats(phase_map_.size(), phase_kind_name);
|
|
|
|
it = phase_map_.insert(std::make_pair(phase_name_str, phase_stats)).first;
|
|
|
|
}
|
|
|
|
it->second.Accumulate(stats);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CompilationStatistics::RecordPhaseKindStats(const char* phase_kind_name,
|
|
|
|
const BasicStats& stats) {
|
|
|
|
std::string phase_kind_name_str(phase_kind_name);
|
|
|
|
auto it = phase_kind_map_.find(phase_kind_name_str);
|
|
|
|
if (it == phase_kind_map_.end()) {
|
|
|
|
PhaseKindStats phase_kind_stats(phase_kind_map_.size());
|
|
|
|
it = phase_kind_map_.insert(std::make_pair(phase_kind_name_str,
|
|
|
|
phase_kind_stats)).first;
|
|
|
|
}
|
|
|
|
it->second.Accumulate(stats);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CompilationStatistics::RecordTotalStats(size_t source_size,
|
|
|
|
const BasicStats& stats) {
|
|
|
|
source_size += source_size;
|
|
|
|
total_stats_.Accumulate(stats);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) {
|
|
|
|
delta_ += stats.delta_;
|
|
|
|
total_allocated_bytes_ += stats.total_allocated_bytes_;
|
2014-10-27 08:58:55 +00:00
|
|
|
if (stats.absolute_max_allocated_bytes_ > absolute_max_allocated_bytes_) {
|
|
|
|
absolute_max_allocated_bytes_ = stats.absolute_max_allocated_bytes_;
|
2014-10-23 09:14:35 +00:00
|
|
|
max_allocated_bytes_ = stats.max_allocated_bytes_;
|
|
|
|
function_name_ = stats.function_name_;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-13 09:35:37 +00:00
|
|
|
static void WriteLine(std::ostream& os, bool machine_format, const char* name,
|
2014-10-23 09:14:35 +00:00
|
|
|
const CompilationStatistics::BasicStats& stats,
|
|
|
|
const CompilationStatistics::BasicStats& total_stats) {
|
|
|
|
const size_t kBufferSize = 128;
|
|
|
|
char buffer[kBufferSize];
|
|
|
|
|
|
|
|
double ms = stats.delta_.InMillisecondsF();
|
|
|
|
double percent = stats.delta_.PercentOf(total_stats.delta_);
|
|
|
|
double size_percent =
|
|
|
|
static_cast<double>(stats.total_allocated_bytes_ * 100) /
|
|
|
|
static_cast<double>(total_stats.total_allocated_bytes_);
|
2016-06-13 09:35:37 +00:00
|
|
|
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
|
|
|
|
" (%5.1f%%) %10" PRIuS " %10" PRIuS,
|
|
|
|
name, ms, percent, stats.total_allocated_bytes_,
|
|
|
|
size_percent, stats.max_allocated_bytes_,
|
|
|
|
stats.absolute_max_allocated_bytes_);
|
|
|
|
|
|
|
|
os << buffer;
|
|
|
|
if (stats.function_name_.size() > 0) {
|
|
|
|
os << " " << stats.function_name_.c_str();
|
|
|
|
}
|
|
|
|
os << std::endl;
|
2014-10-23 09:14:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void WriteFullLine(std::ostream& os) {
|
2014-10-27 08:58:55 +00:00
|
|
|
os << "--------------------------------------------------------"
|
|
|
|
"--------------------------------------------------------\n";
|
2014-10-23 09:14:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void WriteHeader(std::ostream& os) {
|
|
|
|
WriteFullLine(os);
|
2015-09-14 09:25:18 +00:00
|
|
|
os << " Turbonfan phase Time (ms) "
|
|
|
|
<< " Space (bytes) Function\n"
|
|
|
|
<< " "
|
|
|
|
<< " Total Max. Abs. max.\n";
|
2014-10-23 09:14:35 +00:00
|
|
|
WriteFullLine(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void WritePhaseKindBreak(std::ostream& os) {
|
2014-10-27 08:58:55 +00:00
|
|
|
os << " ---------------------------"
|
|
|
|
"--------------------------------------------------------\n";
|
2014-10-23 09:14:35 +00:00
|
|
|
}
|
|
|
|
|
2016-06-13 09:35:37 +00:00
|
|
|
std::ostream& operator<<(std::ostream& os, const AsPrintableStatistics& ps) {
|
2014-10-23 09:14:35 +00:00
|
|
|
// phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of
|
|
|
|
// pointers into them.
|
2016-06-13 09:35:37 +00:00
|
|
|
const CompilationStatistics& s = ps.s;
|
2014-10-23 09:14:35 +00:00
|
|
|
|
|
|
|
typedef std::vector<CompilationStatistics::PhaseKindMap::const_iterator>
|
|
|
|
SortedPhaseKinds;
|
|
|
|
SortedPhaseKinds sorted_phase_kinds(s.phase_kind_map_.size());
|
|
|
|
for (auto it = s.phase_kind_map_.begin(); it != s.phase_kind_map_.end();
|
|
|
|
++it) {
|
|
|
|
sorted_phase_kinds[it->second.insert_order_] = it;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef std::vector<CompilationStatistics::PhaseMap::const_iterator>
|
|
|
|
SortedPhases;
|
|
|
|
SortedPhases sorted_phases(s.phase_map_.size());
|
|
|
|
for (auto it = s.phase_map_.begin(); it != s.phase_map_.end(); ++it) {
|
|
|
|
sorted_phases[it->second.insert_order_] = it;
|
|
|
|
}
|
|
|
|
|
2016-06-13 09:35:37 +00:00
|
|
|
if (!ps.machine_output) WriteHeader(os);
|
2014-10-23 09:14:35 +00:00
|
|
|
for (auto phase_kind_it : sorted_phase_kinds) {
|
|
|
|
const auto& phase_kind_name = phase_kind_it->first;
|
2016-06-13 09:35:37 +00:00
|
|
|
if (!ps.machine_output) {
|
|
|
|
for (auto phase_it : sorted_phases) {
|
|
|
|
const auto& phase_stats = phase_it->second;
|
|
|
|
if (phase_stats.phase_kind_name_ != phase_kind_name) continue;
|
|
|
|
const auto& phase_name = phase_it->first;
|
|
|
|
WriteLine(os, ps.machine_output, phase_name.c_str(), phase_stats,
|
|
|
|
s.total_stats_);
|
|
|
|
}
|
|
|
|
WritePhaseKindBreak(os);
|
2014-10-23 09:14:35 +00:00
|
|
|
}
|
|
|
|
const auto& phase_kind_stats = phase_kind_it->second;
|
2016-06-13 09:35:37 +00:00
|
|
|
WriteLine(os, ps.machine_output, phase_kind_name.c_str(), phase_kind_stats,
|
|
|
|
s.total_stats_);
|
2014-10-23 09:14:35 +00:00
|
|
|
os << std::endl;
|
|
|
|
}
|
2016-06-13 09:35:37 +00:00
|
|
|
|
|
|
|
if (!ps.machine_output) WriteFullLine(os);
|
|
|
|
WriteLine(os, ps.machine_output, "totals", s.total_stats_, s.total_stats_);
|
2014-10-23 09:14:35 +00:00
|
|
|
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|