Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Side by Side Diff: third_party/WebKit/Source/core/frame/PerformanceMonitor.cpp

Issue 2713553010: Migrate performance monitor to inspector instrumentation. (Closed)
Patch Set: Introduce progress monitor Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/PerformanceMonitor.h" 5 #include "core/frame/PerformanceMonitor.h"
6 6
7 #include "bindings/core/v8/ScheduledAction.h" 7 #include "bindings/core/v8/ScheduledAction.h"
8 #include "bindings/core/v8/ScriptEventListener.h" 8 #include "bindings/core/v8/ScriptEventListener.h"
9 #include "bindings/core/v8/SourceLocation.h" 9 #include "bindings/core/v8/SourceLocation.h"
10 #include "core/InstrumentingAgents.h"
10 #include "core/dom/Document.h" 11 #include "core/dom/Document.h"
11 #include "core/dom/ExecutionContext.h" 12 #include "core/dom/ExecutionContext.h"
12 #include "core/events/EventListener.h" 13 #include "core/events/EventListener.h"
13 #include "core/frame/Frame.h" 14 #include "core/frame/Frame.h"
14 #include "core/frame/LocalFrame.h" 15 #include "core/frame/LocalFrame.h"
15 #include "core/html/parser/HTMLDocumentParser.h" 16 #include "core/html/parser/HTMLDocumentParser.h"
16 #include "public/platform/Platform.h" 17 #include "public/platform/Platform.h"
17 #include "wtf/CurrentTime.h" 18 #include "wtf/CurrentTime.h"
18 19
19 namespace blink { 20 namespace blink {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 return; 55 return;
55 --m_performanceMonitor->m_handlerDepth; 56 --m_performanceMonitor->m_handlerDepth;
56 if (!m_performanceMonitor->m_handlerDepth) { 57 if (!m_performanceMonitor->m_handlerDepth) {
57 m_performanceMonitor->m_handlerType = PerformanceMonitor::kAfterLast; 58 m_performanceMonitor->m_handlerType = PerformanceMonitor::kAfterLast;
58 m_performanceMonitor->m_handlerName = nullptr; 59 m_performanceMonitor->m_handlerName = nullptr;
59 m_performanceMonitor->m_handlerAtomicName = AtomicString(); 60 m_performanceMonitor->m_handlerAtomicName = AtomicString();
60 } 61 }
61 } 62 }
62 63
63 // static 64 // static
64 void PerformanceMonitor::willExecuteScript(ExecutionContext* context) {
65 PerformanceMonitor* performanceMonitor = PerformanceMonitor::monitor(context);
66 if (performanceMonitor)
67 performanceMonitor->alwaysWillExecuteScript(context);
68 }
69
70 // static
71 void PerformanceMonitor::didExecuteScript(ExecutionContext* context) {
72 PerformanceMonitor* performanceMonitor = PerformanceMonitor::monitor(context);
73 if (performanceMonitor)
74 performanceMonitor->alwaysDidExecuteScript();
75 }
76
77 // static
78 void PerformanceMonitor::willCallFunction(ExecutionContext* context) {
79 PerformanceMonitor* performanceMonitor = PerformanceMonitor::monitor(context);
80 if (performanceMonitor)
81 performanceMonitor->alwaysWillCallFunction(context);
82 }
83
84 // static
85 void PerformanceMonitor::didCallFunction(ExecutionContext* context,
86 v8::Local<v8::Function> function) {
87 PerformanceMonitor* performanceMonitor = PerformanceMonitor::monitor(context);
88 if (performanceMonitor)
89 performanceMonitor->alwaysDidCallFunction(context, function);
90 }
91
92 // static
93 void PerformanceMonitor::willUpdateLayout(Document* document) {
94 PerformanceMonitor* performanceMonitor =
95 PerformanceMonitor::instrumentingMonitor(document);
96 if (performanceMonitor)
97 performanceMonitor->willUpdateLayout();
98 }
99
100 // static
101 void PerformanceMonitor::didUpdateLayout(Document* document) {
102 PerformanceMonitor* performanceMonitor =
103 PerformanceMonitor::instrumentingMonitor(document);
104 if (performanceMonitor)
105 performanceMonitor->didUpdateLayout();
106 }
107
108 // static
109 void PerformanceMonitor::willRecalculateStyle(Document* document) {
110 PerformanceMonitor* performanceMonitor =
111 PerformanceMonitor::instrumentingMonitor(document);
112 if (performanceMonitor)
113 performanceMonitor->willRecalculateStyle();
114 }
115
116 // static
117 void PerformanceMonitor::didRecalculateStyle(Document* document) {
118 PerformanceMonitor* performanceMonitor =
119 PerformanceMonitor::instrumentingMonitor(document);
120 if (performanceMonitor)
121 performanceMonitor->didRecalculateStyle();
122 }
123
124 // static
125 void PerformanceMonitor::documentWriteFetchScript(Document* document) {
126 PerformanceMonitor* performanceMonitor =
127 PerformanceMonitor::instrumentingMonitor(document);
128 if (!performanceMonitor)
129 return;
130 String text = "Parser was blocked due to document.write(<script>)";
131 performanceMonitor->innerReportGenericViolation(document, kBlockedParser,
132 text, 0, nullptr);
133 }
134
135 // static
136 double PerformanceMonitor::threshold(ExecutionContext* context, 65 double PerformanceMonitor::threshold(ExecutionContext* context,
137 Violation violation) { 66 Violation violation) {
138 PerformanceMonitor* monitor = 67 PerformanceMonitor* monitor =
139 PerformanceMonitor::instrumentingMonitor(context); 68 PerformanceMonitor::instrumentingMonitor(context);
140 return monitor ? monitor->m_thresholds[violation] : 0; 69 return monitor ? monitor->m_thresholds[violation] : 0;
141 } 70 }
142 71
143 // static 72 // static
144 void PerformanceMonitor::reportGenericViolation( 73 void PerformanceMonitor::reportGenericViolation(
145 ExecutionContext* context, 74 ExecutionContext* context,
(...skipping 24 matching lines...) Expand all
170 PerformanceMonitor* PerformanceMonitor::instrumentingMonitor( 99 PerformanceMonitor* PerformanceMonitor::instrumentingMonitor(
171 const ExecutionContext* context) { 100 const ExecutionContext* context) {
172 PerformanceMonitor* monitor = PerformanceMonitor::monitor(context); 101 PerformanceMonitor* monitor = PerformanceMonitor::monitor(context);
173 return monitor && monitor->m_enabled ? monitor : nullptr; 102 return monitor && monitor->m_enabled ? monitor : nullptr;
174 } 103 }
175 104
176 PerformanceMonitor::PerformanceMonitor(LocalFrame* localRoot) 105 PerformanceMonitor::PerformanceMonitor(LocalFrame* localRoot)
177 : m_localRoot(localRoot) { 106 : m_localRoot(localRoot) {
178 std::fill(std::begin(m_thresholds), std::end(m_thresholds), 0); 107 std::fill(std::begin(m_thresholds), std::end(m_thresholds), 0);
179 Platform::current()->currentThread()->addTaskTimeObserver(this); 108 Platform::current()->currentThread()->addTaskTimeObserver(this);
109 m_localRoot->instrumentingAgents()->addPerformanceMonitor(this);
180 } 110 }
181 111
182 PerformanceMonitor::~PerformanceMonitor() { 112 PerformanceMonitor::~PerformanceMonitor() {
183 shutdown(); 113 DCHECK(!m_localRoot);
184 } 114 }
185 115
186 void PerformanceMonitor::subscribe(Violation violation, 116 void PerformanceMonitor::subscribe(Violation violation,
187 double threshold, 117 double threshold,
188 Client* client) { 118 Client* client) {
189 DCHECK(violation < kAfterLast); 119 DCHECK(violation < kAfterLast);
190 ClientThresholds* clientThresholds = m_subscriptions.at(violation); 120 ClientThresholds* clientThresholds = m_subscriptions.at(violation);
191 if (!clientThresholds) { 121 if (!clientThresholds) {
192 clientThresholds = new ClientThresholds(); 122 clientThresholds = new ClientThresholds();
193 m_subscriptions.set(violation, clientThresholds); 123 m_subscriptions.set(violation, clientThresholds);
194 } 124 }
195 clientThresholds->set(client, threshold); 125 clientThresholds->set(client, threshold);
196 updateInstrumentation(); 126 updateInstrumentation();
197 } 127 }
198 128
199 void PerformanceMonitor::unsubscribeAll(Client* client) { 129 void PerformanceMonitor::unsubscribeAll(Client* client) {
200 for (const auto& it : m_subscriptions) 130 for (const auto& it : m_subscriptions)
201 it.value->erase(client); 131 it.value->erase(client);
202 updateInstrumentation(); 132 updateInstrumentation();
203 } 133 }
204 134
205 void PerformanceMonitor::shutdown() { 135 void PerformanceMonitor::shutdown() {
136 if (!m_localRoot)
137 return;
206 m_subscriptions.clear(); 138 m_subscriptions.clear();
207 updateInstrumentation(); 139 updateInstrumentation();
208 Platform::current()->currentThread()->removeTaskTimeObserver(this); 140 Platform::current()->currentThread()->removeTaskTimeObserver(this);
141 m_localRoot->instrumentingAgents()->removePerformanceMonitor(this);
142 m_localRoot = nullptr;
209 } 143 }
210 144
211 void PerformanceMonitor::updateInstrumentation() { 145 void PerformanceMonitor::updateInstrumentation() {
212 std::fill(std::begin(m_thresholds), std::end(m_thresholds), 0); 146 std::fill(std::begin(m_thresholds), std::end(m_thresholds), 0);
213 147
214 for (const auto& it : m_subscriptions) { 148 for (const auto& it : m_subscriptions) {
215 Violation violation = static_cast<Violation>(it.key); 149 Violation violation = static_cast<Violation>(it.key);
216 ClientThresholds* clientThresholds = it.value; 150 ClientThresholds* clientThresholds = it.value;
217 for (const auto& clientThreshold : *clientThresholds) { 151 for (const auto& clientThreshold : *clientThresholds) {
218 if (!m_thresholds[violation] || 152 if (!m_thresholds[violation] ||
219 m_thresholds[violation] > clientThreshold.value) 153 m_thresholds[violation] > clientThreshold.value)
220 m_thresholds[violation] = clientThreshold.value; 154 m_thresholds[violation] = clientThreshold.value;
221 } 155 }
222 } 156 }
223 157
224 m_enabled = std::count(std::begin(m_thresholds), std::end(m_thresholds), 0) < 158 m_enabled = std::count(std::begin(m_thresholds), std::end(m_thresholds), 0) <
225 static_cast<int>(kAfterLast); 159 static_cast<int>(kAfterLast);
226 } 160 }
227 161
228 void PerformanceMonitor::alwaysWillExecuteScript(ExecutionContext* context) { 162 void PerformanceMonitor::willExecuteScript(ExecutionContext* context) {
229 // Heuristic for minimal frame context attribution: note the frame context 163 // Heuristic for minimal frame context attribution: note the frame context
230 // for each script execution. When a long task is encountered, 164 // for each script execution. When a long task is encountered,
231 // if there is only one frame context involved, then report it. 165 // if there is only one frame context involved, then report it.
232 // Otherwise don't report frame context. 166 // Otherwise don't report frame context.
233 // NOTE: This heuristic is imperfect and will be improved in V2 API. 167 // NOTE: This heuristic is imperfect and will be improved in V2 API.
234 // In V2, timing of script execution along with style & layout updates will be 168 // In V2, timing of script execution along with style & layout updates will be
235 // accounted for detailed and more accurate attribution. 169 // accounted for detailed and more accurate attribution.
236 ++m_scriptDepth; 170 ++m_scriptDepth;
237 if (!m_taskExecutionContext) 171 if (!m_taskExecutionContext)
238 m_taskExecutionContext = context; 172 m_taskExecutionContext = context;
239 else if (m_taskExecutionContext != context) 173 else if (m_taskExecutionContext != context)
240 m_taskHasMultipleContexts = true; 174 m_taskHasMultipleContexts = true;
241 } 175 }
242 176
243 void PerformanceMonitor::alwaysDidExecuteScript() { 177 void PerformanceMonitor::didExecuteScript() {
244 --m_scriptDepth; 178 --m_scriptDepth;
245 } 179 }
246 180
247 void PerformanceMonitor::alwaysWillCallFunction(ExecutionContext* context) { 181 void PerformanceMonitor::willCallFunction(ExecutionContext* context) {
248 alwaysWillExecuteScript(context); 182 willExecuteScript(context);
249 if (!m_enabled) 183 if (!m_enabled)
250 return; 184 return;
251 if (m_scriptDepth == 1 && m_thresholds[m_handlerType]) 185 if (m_scriptDepth == 1 && m_thresholds[m_handlerType])
252 m_scriptStartTime = WTF::monotonicallyIncreasingTime(); 186 m_scriptStartTime = WTF::monotonicallyIncreasingTime();
253 } 187 }
254 188
255 void PerformanceMonitor::alwaysDidCallFunction( 189 void PerformanceMonitor::didCallFunction(ExecutionContext* context,
256 ExecutionContext* context, 190 v8::Local<v8::Function> function) {
257 v8::Local<v8::Function> function) { 191 didExecuteScript();
258 alwaysDidExecuteScript();
259 if (!m_enabled) 192 if (!m_enabled)
260 return; 193 return;
261 if (m_scriptDepth) 194 if (m_scriptDepth)
262 return; 195 return;
263 if (m_handlerType == kAfterLast) 196 if (m_handlerType == kAfterLast)
264 return; 197 return;
265 double threshold = m_thresholds[m_handlerType]; 198 double threshold = m_thresholds[m_handlerType];
266 if (!threshold) 199 if (!threshold)
267 return; 200 return;
268 201
269 double time = WTF::monotonicallyIncreasingTime() - m_scriptStartTime; 202 double time = WTF::monotonicallyIncreasingTime() - m_scriptStartTime;
270 if (time < threshold) 203 if (time < threshold)
271 return; 204 return;
272 String name = m_handlerName ? m_handlerName : m_handlerAtomicName; 205 String name = m_handlerName ? m_handlerName : m_handlerAtomicName;
273 String text = String::format("'%s' handler took %ldms", name.utf8().data(), 206 String text = String::format("'%s' handler took %ldms", name.utf8().data(),
274 lround(time * 1000)); 207 lround(time * 1000));
275 innerReportGenericViolation(context, m_handlerType, text, time, 208 innerReportGenericViolation(context, m_handlerType, text, time,
276 SourceLocation::fromFunction(function)); 209 SourceLocation::fromFunction(function));
277 } 210 }
278 211
279 void PerformanceMonitor::willUpdateLayout() { 212 void PerformanceMonitor::willUpdateLayout() {
213 if (!m_enabled)
214 return;
280 if (m_thresholds[kLongLayout] && m_scriptDepth && !m_layoutDepth) 215 if (m_thresholds[kLongLayout] && m_scriptDepth && !m_layoutDepth)
281 m_layoutStartTime = WTF::monotonicallyIncreasingTime(); 216 m_layoutStartTime = WTF::monotonicallyIncreasingTime();
282 ++m_layoutDepth; 217 ++m_layoutDepth;
283 } 218 }
284 219
285 void PerformanceMonitor::didUpdateLayout() { 220 void PerformanceMonitor::didUpdateLayout() {
221 if (!m_enabled)
222 return;
286 --m_layoutDepth; 223 --m_layoutDepth;
287 if (m_thresholds[kLongLayout] && m_scriptDepth && !m_layoutDepth) { 224 if (m_thresholds[kLongLayout] && m_scriptDepth && !m_layoutDepth) {
288 m_perTaskStyleAndLayoutTime += 225 m_perTaskStyleAndLayoutTime +=
289 WTF::monotonicallyIncreasingTime() - m_layoutStartTime; 226 WTF::monotonicallyIncreasingTime() - m_layoutStartTime;
290 } 227 }
291 } 228 }
292 229
293 void PerformanceMonitor::willRecalculateStyle() { 230 void PerformanceMonitor::willRecalculateStyle(Document*) {
231 if (!m_enabled)
232 return;
233
294 if (m_thresholds[kLongLayout] && m_scriptDepth) 234 if (m_thresholds[kLongLayout] && m_scriptDepth)
295 m_styleStartTime = WTF::monotonicallyIncreasingTime(); 235 m_styleStartTime = WTF::monotonicallyIncreasingTime();
296 } 236 }
297 237
298 void PerformanceMonitor::didRecalculateStyle() { 238 void PerformanceMonitor::didRecalculateStyle() {
239 if (!m_enabled)
240 return;
299 if (m_thresholds[kLongLayout] && m_scriptDepth) { 241 if (m_thresholds[kLongLayout] && m_scriptDepth) {
300 m_perTaskStyleAndLayoutTime += 242 m_perTaskStyleAndLayoutTime +=
301 WTF::monotonicallyIncreasingTime() - m_styleStartTime; 243 WTF::monotonicallyIncreasingTime() - m_styleStartTime;
302 } 244 }
303 } 245 }
304 246
247 void PerformanceMonitor::documentWriteFetchScript(Document* document) {
248 if (!m_enabled)
249 return;
250 String text = "Parser was blocked due to document.write(<script>)";
251 innerReportGenericViolation(document, kBlockedParser, text, 0, nullptr);
252 }
253
305 void PerformanceMonitor::willProcessTask(scheduler::TaskQueue*, 254 void PerformanceMonitor::willProcessTask(scheduler::TaskQueue*,
306 double startTime) { 255 double startTime) {
307 // Reset m_taskExecutionContext. We don't clear this in didProcessTask 256 // Reset m_taskExecutionContext. We don't clear this in didProcessTask
308 // as it is needed in ReportTaskTime which occurs after didProcessTask. 257 // as it is needed in ReportTaskTime which occurs after didProcessTask.
309 m_taskExecutionContext = nullptr; 258 m_taskExecutionContext = nullptr;
310 m_taskHasMultipleContexts = false; 259 m_taskHasMultipleContexts = false;
311 260
312 if (!m_enabled) 261 if (!m_enabled)
313 return; 262 return;
314 m_scriptDepth = 0; 263 m_scriptDepth = 0;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 } 319 }
371 } 320 }
372 321
373 DEFINE_TRACE(PerformanceMonitor) { 322 DEFINE_TRACE(PerformanceMonitor) {
374 visitor->trace(m_localRoot); 323 visitor->trace(m_localRoot);
375 visitor->trace(m_taskExecutionContext); 324 visitor->trace(m_taskExecutionContext);
376 visitor->trace(m_subscriptions); 325 visitor->trace(m_subscriptions);
377 } 326 }
378 327
379 } // namespace blink 328 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698