Line data Source code
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 :
5 : #include <ostream> // NOLINT(readability/streams)
6 : #include <vector>
7 :
8 : #include "src/base/platform/platform.h"
9 : #include "src/compilation-statistics.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 0 : void CompilationStatistics::RecordPhaseStats(const char* phase_kind_name,
15 : const char* phase_name,
16 : const BasicStats& stats) {
17 0 : base::MutexGuard guard(&record_mutex_);
18 :
19 0 : std::string phase_name_str(phase_name);
20 : auto it = phase_map_.find(phase_name_str);
21 0 : if (it == phase_map_.end()) {
22 0 : PhaseStats phase_stats(phase_map_.size(), phase_kind_name);
23 0 : it = phase_map_.insert(std::make_pair(phase_name_str, phase_stats)).first;
24 : }
25 0 : it->second.Accumulate(stats);
26 0 : }
27 :
28 :
29 0 : void CompilationStatistics::RecordPhaseKindStats(const char* phase_kind_name,
30 : const BasicStats& stats) {
31 0 : base::MutexGuard guard(&record_mutex_);
32 :
33 0 : std::string phase_kind_name_str(phase_kind_name);
34 : auto it = phase_kind_map_.find(phase_kind_name_str);
35 0 : if (it == phase_kind_map_.end()) {
36 : PhaseKindStats phase_kind_stats(phase_kind_map_.size());
37 0 : it = phase_kind_map_.insert(std::make_pair(phase_kind_name_str,
38 : phase_kind_stats)).first;
39 : }
40 0 : it->second.Accumulate(stats);
41 0 : }
42 :
43 :
44 0 : void CompilationStatistics::RecordTotalStats(size_t source_size,
45 : const BasicStats& stats) {
46 0 : base::MutexGuard guard(&record_mutex_);
47 :
48 : source_size += source_size;
49 0 : total_stats_.Accumulate(stats);
50 0 : }
51 :
52 :
53 0 : void CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) {
54 : delta_ += stats.delta_;
55 0 : total_allocated_bytes_ += stats.total_allocated_bytes_;
56 0 : if (stats.absolute_max_allocated_bytes_ > absolute_max_allocated_bytes_) {
57 0 : absolute_max_allocated_bytes_ = stats.absolute_max_allocated_bytes_;
58 0 : max_allocated_bytes_ = stats.max_allocated_bytes_;
59 0 : function_name_ = stats.function_name_;
60 : }
61 0 : }
62 :
63 0 : static void WriteLine(std::ostream& os, bool machine_format, const char* name,
64 : const CompilationStatistics::BasicStats& stats,
65 : const CompilationStatistics::BasicStats& total_stats) {
66 : const size_t kBufferSize = 128;
67 : char buffer[kBufferSize];
68 :
69 0 : double ms = stats.delta_.InMillisecondsF();
70 : double percent = stats.delta_.PercentOf(total_stats.delta_);
71 : double size_percent =
72 0 : static_cast<double>(stats.total_allocated_bytes_ * 100) /
73 0 : static_cast<double>(total_stats.total_allocated_bytes_);
74 0 : if (machine_format) {
75 : base::OS::SNPrintF(buffer, kBufferSize,
76 : "\"%s_time\"=%.3f\n\"%s_space\"=%" PRIuS, name, ms, name,
77 0 : stats.total_allocated_bytes_);
78 0 : os << buffer;
79 : } else {
80 : base::OS::SNPrintF(
81 : buffer, kBufferSize,
82 : "%34s %10.3f (%5.1f%%) %10" PRIuS " (%5.1f%%) %10" PRIuS " %10" PRIuS,
83 : name, ms, percent, stats.total_allocated_bytes_, size_percent,
84 0 : stats.max_allocated_bytes_, stats.absolute_max_allocated_bytes_);
85 :
86 0 : os << buffer;
87 0 : if (stats.function_name_.size() > 0) {
88 0 : os << " " << stats.function_name_.c_str();
89 : }
90 : os << std::endl;
91 : }
92 0 : }
93 :
94 :
95 : static void WriteFullLine(std::ostream& os) {
96 : os << "-----------------------------------------------------------"
97 0 : "-----------------------------------------------------------\n";
98 : }
99 :
100 :
101 0 : static void WriteHeader(std::ostream& os) {
102 : WriteFullLine(os);
103 : os << " Turbofan phase Time (ms) "
104 : << " Space (bytes) Function\n"
105 : << " "
106 0 : << " Total Max. Abs. max.\n";
107 : WriteFullLine(os);
108 0 : }
109 :
110 :
111 : static void WritePhaseKindBreak(std::ostream& os) {
112 : os << " ------------------------"
113 0 : "-----------------------------------------------------------\n";
114 : }
115 :
116 0 : std::ostream& operator<<(std::ostream& os, const AsPrintableStatistics& ps) {
117 : // phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of
118 : // pointers into them.
119 0 : const CompilationStatistics& s = ps.s;
120 :
121 : typedef std::vector<CompilationStatistics::PhaseKindMap::const_iterator>
122 : SortedPhaseKinds;
123 0 : SortedPhaseKinds sorted_phase_kinds(s.phase_kind_map_.size());
124 0 : for (auto it = s.phase_kind_map_.begin(); it != s.phase_kind_map_.end();
125 : ++it) {
126 0 : sorted_phase_kinds[it->second.insert_order_] = it;
127 : }
128 :
129 : typedef std::vector<CompilationStatistics::PhaseMap::const_iterator>
130 : SortedPhases;
131 0 : SortedPhases sorted_phases(s.phase_map_.size());
132 0 : for (auto it = s.phase_map_.begin(); it != s.phase_map_.end(); ++it) {
133 0 : sorted_phases[it->second.insert_order_] = it;
134 : }
135 :
136 0 : if (!ps.machine_output) WriteHeader(os);
137 0 : for (const auto& phase_kind_it : sorted_phase_kinds) {
138 0 : const auto& phase_kind_name = phase_kind_it->first;
139 0 : if (!ps.machine_output) {
140 0 : for (const auto& phase_it : sorted_phases) {
141 : const auto& phase_stats = phase_it->second;
142 0 : if (phase_stats.phase_kind_name_ != phase_kind_name) continue;
143 : const auto& phase_name = phase_it->first;
144 0 : WriteLine(os, ps.machine_output, phase_name.c_str(), phase_stats,
145 0 : s.total_stats_);
146 : }
147 : WritePhaseKindBreak(os);
148 : }
149 : const auto& phase_kind_stats = phase_kind_it->second;
150 0 : WriteLine(os, ps.machine_output, phase_kind_name.c_str(), phase_kind_stats,
151 0 : s.total_stats_);
152 : os << std::endl;
153 : }
154 :
155 0 : if (!ps.machine_output) WriteFullLine(os);
156 0 : WriteLine(os, ps.machine_output, "totals", s.total_stats_, s.total_stats_);
157 :
158 0 : return os;
159 : }
160 :
161 : } // namespace internal
162 122036 : } // namespace v8
|