v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
compilation-statistics.cc
Go to the documentation of this file.
1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <iomanip>
8#include <ostream>
9#include <vector>
10
12
13namespace v8 {
14namespace internal {
15
16void CompilationStatistics::RecordPhaseStats(const char* phase_kind_name,
17 const char* phase_name,
18 const BasicStats& stats) {
20
21 std::string phase_name_str(phase_name);
22 auto it = phase_map_.find(phase_name_str);
23 if (it == phase_map_.end()) {
24 PhaseStats phase_stats(phase_map_.size(), phase_kind_name);
25 it = phase_map_.insert(std::make_pair(phase_name_str, phase_stats)).first;
26 }
27 it->second.Accumulate(stats);
28}
29
30void CompilationStatistics::RecordPhaseKindStats(const char* phase_kind_name,
31 const BasicStats& stats) {
33
34 std::string phase_kind_name_str(phase_kind_name);
35 auto it = phase_kind_map_.find(phase_kind_name_str);
36 if (it == phase_kind_map_.end()) {
37 PhaseKindStats phase_kind_stats(phase_kind_map_.size());
39 .insert(std::make_pair(phase_kind_name_str, phase_kind_stats))
40 .first;
41 }
42 it->second.Accumulate(stats);
43}
44
50
52 delta_ += stats.delta_;
53 total_allocated_bytes_ += stats.total_allocated_bytes_;
54 if (stats.absolute_max_allocated_bytes_ > absolute_max_allocated_bytes_) {
55 absolute_max_allocated_bytes_ = stats.absolute_max_allocated_bytes_;
56 max_allocated_bytes_ = stats.max_allocated_bytes_;
57 function_name_ = stats.function_name_;
58 }
59 input_graph_size_ += stats.input_graph_size_;
60 output_graph_size_ += stats.output_graph_size_;
61}
62
64// clang-format off
65#define DICT(s) "{" << s << "}"
66#define QUOTE(s) "\"" << s << "\""
67#define MEMBER(s) QUOTE(s) << ":"
68
69 DCHECK_EQ(function_name_.find("\""), std::string::npos);
70
71 std::stringstream stream;
72 stream << DICT(
73 MEMBER("function_name") << QUOTE(function_name_) << ","
74 MEMBER("total_allocated_bytes") << total_allocated_bytes_ << ","
75 MEMBER("max_allocated_bytes") << max_allocated_bytes_ << ","
76 MEMBER("absolute_max_allocated_bytes") << absolute_max_allocated_bytes_);
77
78 return stream.str();
79
80#undef DICT
81#undef QUOTE
82#undef MEMBER
83 // clang-format on
84}
85
86static void WriteLine(std::ostream& os, bool machine_format, const char* name,
87 const char* compiler,
89 const CompilationStatistics::BasicStats& total_stats) {
90 const size_t kBufferSize = 128;
91 char buffer[kBufferSize];
92
93 double ms = stats.delta_.InMillisecondsF();
94 double percent = stats.delta_.PercentOf(total_stats.delta_);
95 double size_percent =
96 static_cast<double>(stats.total_allocated_bytes_ * 100) /
97 static_cast<double>(total_stats.total_allocated_bytes_);
98 double growth =
99 static_cast<double>(stats.output_graph_size_) / stats.input_graph_size_;
100 double mops_per_s = (stats.output_graph_size_ / 1000000.0) / (ms / 1000.0);
101
102 if (machine_format) {
103 base::OS::SNPrintF(buffer, kBufferSize,
104 "\"%s_%s_time\"=%.3f\n\"%s_%s_space\"=%zu", compiler,
105 name, ms, compiler, name, stats.total_allocated_bytes_);
106 os << buffer;
107 } else {
108 if (stats.output_graph_size_ != 0) {
109 base::OS::SNPrintF(
110 buffer, kBufferSize,
111 "%34s %10.3f (%4.1f%%) %10zu (%4.1f%%) %10zu %10zu %5.3f %6.2f",
112 name, ms, percent, stats.total_allocated_bytes_, size_percent,
113 stats.max_allocated_bytes_, stats.absolute_max_allocated_bytes_,
114 growth, mops_per_s);
115 } else {
116 base::OS::SNPrintF(
117 buffer, kBufferSize,
118 "%34s %10.3f (%4.1f%%) %10zu (%4.1f%%) %10zu %10zu ",
119 name, ms, percent, stats.total_allocated_bytes_, size_percent,
120 stats.max_allocated_bytes_, stats.absolute_max_allocated_bytes_);
121 }
122
123 os << buffer;
124 if (!stats.function_name_.empty()) {
125 os << " " << stats.function_name_.c_str();
126 }
127 os << '\n';
128 }
129}
130
131static void WriteFullLine(std::ostream& os) {
132 os << "-----------------------------------------------------------"
133 "-----------------------------------------------------------\n";
134}
135
136static void WriteHeader(std::ostream& os, const char* compiler) {
137 WriteFullLine(os);
138 os << std::setw(24) << compiler << " phase Time (ms) "
139 << " Space (bytes) Growth MOps/s Function\n"
140 << " "
141 << " Total Max. Abs. max.\n";
142 WriteFullLine(os);
143}
144
145static void WritePhaseKindBreak(std::ostream& os) {
146 os << " ------------------------"
147 "-----------------------------------------------------------\n";
148}
149
150std::ostream& operator<<(std::ostream& os, const AsPrintableStatistics& ps) {
151 // phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of
152 // pointers into them.
153 CompilationStatistics& s = ps.s;
154 base::MutexGuard guard(&s.access_mutex_);
155
156 using SortedPhaseKinds =
157 std::vector<CompilationStatistics::PhaseKindMap::const_iterator>;
158 SortedPhaseKinds sorted_phase_kinds(s.phase_kind_map_.size());
159 for (auto it = s.phase_kind_map_.begin(); it != s.phase_kind_map_.end();
160 ++it) {
161 sorted_phase_kinds[it->second.insert_order_] = it;
162 }
163
164 using SortedPhases =
165 std::vector<CompilationStatistics::PhaseMap::const_iterator>;
166 SortedPhases sorted_phases(s.phase_map_.size());
167 for (auto it = s.phase_map_.begin(); it != s.phase_map_.end(); ++it) {
168 sorted_phases[it->second.insert_order_] = it;
169 }
170
171 if (!ps.machine_output) WriteHeader(os, ps.compiler);
172 for (const auto& phase_kind_it : sorted_phase_kinds) {
173 const auto& phase_kind_name = phase_kind_it->first;
174 if (!ps.machine_output) {
175 for (const auto& phase_it : sorted_phases) {
176 const auto& phase_stats = phase_it->second;
177 if (phase_stats.phase_kind_name_ != phase_kind_name) continue;
178 const auto& phase_name = phase_it->first;
179 WriteLine(os, ps.machine_output, phase_name.c_str(), ps.compiler,
180 phase_stats, s.total_stats_);
181 }
183 }
184 const auto& phase_kind_stats = phase_kind_it->second;
185 WriteLine(os, ps.machine_output, phase_kind_name.c_str(), ps.compiler,
186 phase_kind_stats, s.total_stats_);
187 os << '\n';
188 }
189
190 if (!ps.machine_output) WriteFullLine(os);
191 WriteLine(os, ps.machine_output, "totals", ps.compiler, s.total_stats_,
192 s.total_stats_);
193
194 if (ps.machine_output) {
195 os << '\n';
196 os << "\"" << ps.compiler << "_totals_count\"=" << s.total_stats_.count_;
197 }
198 return os;
199}
200
201} // namespace internal
202} // namespace v8
int64_t delta_
Definition time.h:224
void RecordPhaseStats(const char *phase_kind_name, const char *phase_name, const BasicStats &stats)
void RecordPhaseKindStats(const char *phase_kind_name, const BasicStats &stats)
friend std::ostream & operator<<(std::ostream &os, const AsPrintableStatistics &s)
void RecordTotalStats(const BasicStats &stats)
#define MEMBER(s)
#define DICT(s)
#define QUOTE(s)
static void WritePhaseKindBreak(std::ostream &os)
static void WriteLine(std::ostream &os, bool machine_format, const char *name, const char *compiler, const CompilationStatistics::BasicStats &stats, const CompilationStatistics::BasicStats &total_stats)
static void WriteHeader(std::ostream &os, const char *compiler)
static void WriteFullLine(std::ostream &os)
#define DCHECK_EQ(v1, v2)
Definition logging.h:485