Line data Source code
1 : // Copyright 2016 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 "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
6 :
7 : #include "src/isolate.h"
8 : #include "src/utils.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 :
13 : namespace {
14 :
15 374 : double MonotonicallyIncreasingTimeInMs() {
16 374 : return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
17 374 : static_cast<double>(base::Time::kMillisecondsPerSecond);
18 : }
19 :
20 : const double kEstimatedRuntimeWithoutData = 1.0;
21 :
22 : } // namespace
23 :
24 187 : CompilerDispatcherTracer::Scope::Scope(CompilerDispatcherTracer* tracer,
25 : ScopeID scope_id, size_t num)
26 187 : : tracer_(tracer), scope_id_(scope_id), num_(num) {
27 187 : start_time_ = MonotonicallyIncreasingTimeInMs();
28 187 : }
29 :
30 187 : CompilerDispatcherTracer::Scope::~Scope() {
31 187 : double elapsed = MonotonicallyIncreasingTimeInMs() - start_time_;
32 187 : switch (scope_id_) {
33 : case ScopeID::kPrepareToParse:
34 28 : tracer_->RecordPrepareToParse(elapsed);
35 28 : break;
36 : case ScopeID::kParse:
37 28 : tracer_->RecordParse(elapsed, num_);
38 28 : break;
39 : case ScopeID::kFinalizeParsing:
40 27 : tracer_->RecordFinalizeParsing(elapsed);
41 27 : break;
42 : case ScopeID::kAnalyze:
43 26 : tracer_->RecordAnalyze(elapsed);
44 26 : break;
45 : case ScopeID::kPrepareToCompile:
46 29 : tracer_->RecordPrepareToCompile(elapsed);
47 29 : break;
48 : case ScopeID::kCompile:
49 25 : tracer_->RecordCompile(elapsed, num_);
50 25 : break;
51 : case ScopeID::kFinalizeCompiling:
52 24 : tracer_->RecordFinalizeCompiling(elapsed);
53 24 : break;
54 : }
55 187 : }
56 :
57 : // static
58 0 : const char* CompilerDispatcherTracer::Scope::Name(ScopeID scope_id) {
59 0 : switch (scope_id) {
60 : case ScopeID::kPrepareToParse:
61 : return "V8.BackgroundCompile_PrepareToParse";
62 : case ScopeID::kParse:
63 0 : return "V8.BackgroundCompile_Parse";
64 : case ScopeID::kFinalizeParsing:
65 0 : return "V8.BackgroundCompile_FinalizeParsing";
66 : case ScopeID::kAnalyze:
67 0 : return "V8.BackgroundCompile_Analyze";
68 : case ScopeID::kPrepareToCompile:
69 0 : return "V8.BackgroundCompile_PrepareToCompile";
70 : case ScopeID::kCompile:
71 0 : return "V8.BackgroundCompile_Compile";
72 : case ScopeID::kFinalizeCompiling:
73 0 : return "V8.BackgroundCompile_FinalizeCompiling";
74 : }
75 0 : UNREACHABLE();
76 : return nullptr;
77 : }
78 :
79 121639 : CompilerDispatcherTracer::CompilerDispatcherTracer(Isolate* isolate)
80 121642 : : runtime_call_stats_(nullptr) {
81 : // isolate might be nullptr during unittests.
82 60821 : if (isolate) {
83 60818 : runtime_call_stats_ = isolate->counters()->runtime_call_stats();
84 : }
85 60821 : }
86 :
87 59324 : CompilerDispatcherTracer::~CompilerDispatcherTracer() {}
88 :
89 31 : void CompilerDispatcherTracer::RecordPrepareToParse(double duration_ms) {
90 31 : base::LockGuard<base::Mutex> lock(&mutex_);
91 : prepare_parse_events_.Push(duration_ms);
92 31 : }
93 :
94 31 : void CompilerDispatcherTracer::RecordParse(double duration_ms,
95 : size_t source_length) {
96 31 : base::LockGuard<base::Mutex> lock(&mutex_);
97 31 : parse_events_.Push(std::make_pair(source_length, duration_ms));
98 31 : }
99 :
100 27 : void CompilerDispatcherTracer::RecordFinalizeParsing(double duration_ms) {
101 27 : base::LockGuard<base::Mutex> lock(&mutex_);
102 : finalize_parsing_events_.Push(duration_ms);
103 27 : }
104 :
105 26 : void CompilerDispatcherTracer::RecordAnalyze(double duration_ms) {
106 26 : base::LockGuard<base::Mutex> lock(&mutex_);
107 : analyze_events_.Push(duration_ms);
108 26 : }
109 :
110 29 : void CompilerDispatcherTracer::RecordPrepareToCompile(double duration_ms) {
111 29 : base::LockGuard<base::Mutex> lock(&mutex_);
112 : prepare_compile_events_.Push(duration_ms);
113 29 : }
114 :
115 31 : void CompilerDispatcherTracer::RecordCompile(double duration_ms,
116 : size_t ast_size_in_bytes) {
117 31 : base::LockGuard<base::Mutex> lock(&mutex_);
118 31 : compile_events_.Push(std::make_pair(ast_size_in_bytes, duration_ms));
119 31 : }
120 :
121 24 : void CompilerDispatcherTracer::RecordFinalizeCompiling(double duration_ms) {
122 24 : base::LockGuard<base::Mutex> lock(&mutex_);
123 : finalize_compiling_events_.Push(duration_ms);
124 24 : }
125 :
126 15 : double CompilerDispatcherTracer::EstimatePrepareToParseInMs() const {
127 15 : base::LockGuard<base::Mutex> lock(&mutex_);
128 30 : return Average(prepare_parse_events_);
129 : }
130 :
131 17 : double CompilerDispatcherTracer::EstimateParseInMs(size_t source_length) const {
132 17 : base::LockGuard<base::Mutex> lock(&mutex_);
133 34 : return Estimate(parse_events_, source_length);
134 : }
135 :
136 13 : double CompilerDispatcherTracer::EstimateFinalizeParsingInMs() const {
137 13 : base::LockGuard<base::Mutex> lock(&mutex_);
138 26 : return Average(finalize_parsing_events_);
139 : }
140 :
141 12 : double CompilerDispatcherTracer::EstimateAnalyzeInMs() const {
142 12 : base::LockGuard<base::Mutex> lock(&mutex_);
143 24 : return Average(analyze_events_);
144 : }
145 :
146 15 : double CompilerDispatcherTracer::EstimatePrepareToCompileInMs() const {
147 15 : base::LockGuard<base::Mutex> lock(&mutex_);
148 30 : return Average(prepare_compile_events_);
149 : }
150 :
151 16 : double CompilerDispatcherTracer::EstimateCompileInMs(
152 : size_t ast_size_in_bytes) const {
153 16 : base::LockGuard<base::Mutex> lock(&mutex_);
154 32 : return Estimate(compile_events_, ast_size_in_bytes);
155 : }
156 :
157 11 : double CompilerDispatcherTracer::EstimateFinalizeCompilingInMs() const {
158 11 : base::LockGuard<base::Mutex> lock(&mutex_);
159 22 : return Average(finalize_compiling_events_);
160 : }
161 :
162 0 : void CompilerDispatcherTracer::DumpStatistics() const {
163 : PrintF(
164 : "CompilerDispatcherTracer: "
165 : "prepare_parsing=%.2lfms parsing=%.2lfms/kb finalize_parsing=%.2lfms "
166 : "analyze=%.2lfms prepare_compiling=%.2lfms compiling=%.2lfms/kb "
167 : "finalize_compiling=%.2lfms\n",
168 : EstimatePrepareToParseInMs(), EstimateParseInMs(1 * KB),
169 : EstimateFinalizeParsingInMs(), EstimateAnalyzeInMs(),
170 : EstimatePrepareToCompileInMs(), EstimateCompileInMs(1 * KB),
171 0 : EstimateFinalizeCompilingInMs());
172 0 : }
173 :
174 66 : double CompilerDispatcherTracer::Average(
175 66 : const base::RingBuffer<double>& buffer) {
176 66 : if (buffer.Count() == 0) return 0.0;
177 13 : double sum = buffer.Sum([](double a, double b) { return a + b; }, 0.0);
178 11 : return sum / buffer.Count();
179 : }
180 :
181 33 : double CompilerDispatcherTracer::Estimate(
182 33 : const base::RingBuffer<std::pair<size_t, double>>& buffer, size_t num) {
183 33 : if (buffer.Count() == 0) return kEstimatedRuntimeWithoutData;
184 : std::pair<size_t, double> sum = buffer.Sum(
185 : [](std::pair<size_t, double> a, std::pair<size_t, double> b) {
186 16 : return std::make_pair(a.first + b.first, a.second + b.second);
187 : },
188 12 : std::make_pair(0, 0.0));
189 12 : return num * (sum.second / sum.first);
190 : }
191 :
192 : } // namespace internal
193 : } // namespace v8
|