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

Side by Side Diff: src/inspector/v8-profiler-agent-impl.cc

Issue 2715833003: [inspector] move coverage related methods to profiler (Closed)
Patch Set: rebased Created 3 years, 10 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
« no previous file with comments | « src/inspector/v8-profiler-agent-impl.h ('k') | src/inspector/v8-runtime-agent-impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project 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 "src/inspector/v8-profiler-agent-impl.h" 5 #include "src/inspector/v8-profiler-agent-impl.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "src/base/atomicops.h" 9 #include "src/base/atomicops.h"
10 #include "src/inspector/protocol/Protocol.h" 10 #include "src/inspector/protocol/Protocol.h"
11 #include "src/inspector/string-util.h" 11 #include "src/inspector/string-util.h"
12 #include "src/inspector/v8-debugger.h" 12 #include "src/inspector/v8-debugger.h"
13 #include "src/inspector/v8-inspector-impl.h" 13 #include "src/inspector/v8-inspector-impl.h"
14 #include "src/inspector/v8-inspector-session-impl.h" 14 #include "src/inspector/v8-inspector-session-impl.h"
15 #include "src/inspector/v8-stack-trace-impl.h" 15 #include "src/inspector/v8-stack-trace-impl.h"
16 16
17 #include "include/v8-profiler.h" 17 #include "include/v8-profiler.h"
18 18
19 namespace v8_inspector { 19 namespace v8_inspector {
20 20
21 namespace ProfilerAgentState { 21 namespace ProfilerAgentState {
22 static const char samplingInterval[] = "samplingInterval"; 22 static const char samplingInterval[] = "samplingInterval";
23 static const char userInitiatedProfiling[] = "userInitiatedProfiling"; 23 static const char userInitiatedProfiling[] = "userInitiatedProfiling";
24 static const char profilerEnabled[] = "profilerEnabled"; 24 static const char profilerEnabled[] = "profilerEnabled";
25 static const char preciseCoverageStarted[] = "preciseCoverageStarted";
25 } 26 }
26 27
27 namespace { 28 namespace {
28 29
29 std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>> 30 std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>>
30 buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) { 31 buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) {
31 unsigned lineCount = node->GetHitLineCount(); 32 unsigned lineCount = node->GetHitLineCount();
32 if (!lineCount) return nullptr; 33 if (!lineCount) return nullptr;
33 auto array = protocol::Array<protocol::Profiler::PositionTickInfo>::create(); 34 auto array = protocol::Array<protocol::Profiler::PositionTickInfo>::create();
34 std::vector<v8::CpuProfileNode::LineTick> entries(lineCount); 35 std::vector<v8::CpuProfileNode::LineTick> entries(lineCount);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 : m_id(id), m_title(title) {} 146 : m_id(id), m_title(title) {}
146 String16 m_id; 147 String16 m_id;
147 String16 m_title; 148 String16 m_title;
148 }; 149 };
149 150
150 V8ProfilerAgentImpl::V8ProfilerAgentImpl( 151 V8ProfilerAgentImpl::V8ProfilerAgentImpl(
151 V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, 152 V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel,
152 protocol::DictionaryValue* state) 153 protocol::DictionaryValue* state)
153 : m_session(session), 154 : m_session(session),
154 m_isolate(m_session->inspector()->isolate()), 155 m_isolate(m_session->inspector()->isolate()),
155 m_profiler(nullptr),
156 m_state(state), 156 m_state(state),
157 m_frontend(frontendChannel), 157 m_frontend(frontendChannel) {}
158 m_enabled(false),
159 m_recordingCPUProfile(false) {}
160 158
161 V8ProfilerAgentImpl::~V8ProfilerAgentImpl() { 159 V8ProfilerAgentImpl::~V8ProfilerAgentImpl() {
162 if (m_profiler) m_profiler->Dispose(); 160 if (m_profiler) m_profiler->Dispose();
163 } 161 }
164 162
165 void V8ProfilerAgentImpl::consoleProfile(const String16& title) { 163 void V8ProfilerAgentImpl::consoleProfile(const String16& title) {
166 if (!m_enabled) return; 164 if (!m_enabled) return;
167 String16 id = nextProfileId(); 165 String16 id = nextProfileId();
168 m_startedProfiles.push_back(ProfileDescriptor(id, title)); 166 m_startedProfiles.push_back(ProfileDescriptor(id, title));
169 startProfiling(id); 167 startProfiling(id);
(...skipping 27 matching lines...) Expand all
197 if (!profile) return; 195 if (!profile) return;
198 std::unique_ptr<protocol::Debugger::Location> location = 196 std::unique_ptr<protocol::Debugger::Location> location =
199 currentDebugLocation(m_session->inspector()); 197 currentDebugLocation(m_session->inspector());
200 m_frontend.consoleProfileFinished(id, std::move(location), std::move(profile), 198 m_frontend.consoleProfileFinished(id, std::move(location), std::move(profile),
201 resolvedTitle); 199 resolvedTitle);
202 } 200 }
203 201
204 Response V8ProfilerAgentImpl::enable() { 202 Response V8ProfilerAgentImpl::enable() {
205 if (m_enabled) return Response::OK(); 203 if (m_enabled) return Response::OK();
206 m_enabled = true; 204 m_enabled = true;
207 DCHECK(!m_profiler);
208 m_profiler = v8::CpuProfiler::New(m_isolate);
209 m_state->setBoolean(ProfilerAgentState::profilerEnabled, true); 205 m_state->setBoolean(ProfilerAgentState::profilerEnabled, true);
210 return Response::OK(); 206 return Response::OK();
211 } 207 }
212 208
213 Response V8ProfilerAgentImpl::disable() { 209 Response V8ProfilerAgentImpl::disable() {
214 if (!m_enabled) return Response::OK(); 210 if (!m_enabled) return Response::OK();
215 for (size_t i = m_startedProfiles.size(); i > 0; --i) 211 for (size_t i = m_startedProfiles.size(); i > 0; --i)
216 stopProfiling(m_startedProfiles[i - 1].m_id, false); 212 stopProfiling(m_startedProfiles[i - 1].m_id, false);
217 m_startedProfiles.clear(); 213 m_startedProfiles.clear();
218 stop(nullptr); 214 stop(nullptr);
219 m_profiler->Dispose(); 215 stopPreciseCoverage();
220 m_profiler = nullptr; 216 DCHECK(!m_profiler);
221 m_enabled = false; 217 m_enabled = false;
222 m_state->setBoolean(ProfilerAgentState::profilerEnabled, false); 218 m_state->setBoolean(ProfilerAgentState::profilerEnabled, false);
223 return Response::OK(); 219 return Response::OK();
224 } 220 }
225 221
226 Response V8ProfilerAgentImpl::setSamplingInterval(int interval) { 222 Response V8ProfilerAgentImpl::setSamplingInterval(int interval) {
227 if (m_recordingCPUProfile) 223 if (m_profiler) {
228 return Response::Error("Cannot change sampling interval when profiling."); 224 return Response::Error("Cannot change sampling interval when profiling.");
225 }
229 m_state->setInteger(ProfilerAgentState::samplingInterval, interval); 226 m_state->setInteger(ProfilerAgentState::samplingInterval, interval);
230 m_profiler->SetSamplingInterval(interval);
231 return Response::OK(); 227 return Response::OK();
232 } 228 }
233 229
234 void V8ProfilerAgentImpl::restore() { 230 void V8ProfilerAgentImpl::restore() {
235 DCHECK(!m_enabled); 231 DCHECK(!m_enabled);
236 if (!m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false)) 232 if (!m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false))
237 return; 233 return;
238 m_enabled = true; 234 m_enabled = true;
239 DCHECK(!m_profiler); 235 DCHECK(!m_profiler);
240 m_profiler = v8::CpuProfiler::New(m_isolate);
241 int interval = 0;
242 m_state->getInteger(ProfilerAgentState::samplingInterval, &interval);
243 if (interval) m_profiler->SetSamplingInterval(interval);
244 if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling, 236 if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling,
245 false)) { 237 false)) {
246 start(); 238 start();
247 } 239 }
240 if (m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
241 false)) {
242 startPreciseCoverage();
243 }
248 } 244 }
249 245
250 Response V8ProfilerAgentImpl::start() { 246 Response V8ProfilerAgentImpl::start() {
251 if (m_recordingCPUProfile) return Response::OK(); 247 if (m_recordingCPUProfile) return Response::OK();
252 if (!m_enabled) return Response::Error("Profiler is not enabled"); 248 if (!m_enabled) return Response::Error("Profiler is not enabled");
253 m_recordingCPUProfile = true; 249 m_recordingCPUProfile = true;
254 m_frontendInitiatedProfileId = nextProfileId(); 250 m_frontendInitiatedProfileId = nextProfileId();
255 startProfiling(m_frontendInitiatedProfileId); 251 startProfiling(m_frontendInitiatedProfileId);
256 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true); 252 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true);
257 return Response::OK(); 253 return Response::OK();
258 } 254 }
259 255
260 Response V8ProfilerAgentImpl::stop( 256 Response V8ProfilerAgentImpl::stop(
261 std::unique_ptr<protocol::Profiler::Profile>* profile) { 257 std::unique_ptr<protocol::Profiler::Profile>* profile) {
262 if (!m_recordingCPUProfile) 258 if (!m_recordingCPUProfile) {
263 return Response::Error("No recording profiles found"); 259 return Response::Error("No recording profiles found");
260 }
264 m_recordingCPUProfile = false; 261 m_recordingCPUProfile = false;
265 std::unique_ptr<protocol::Profiler::Profile> cpuProfile = 262 std::unique_ptr<protocol::Profiler::Profile> cpuProfile =
266 stopProfiling(m_frontendInitiatedProfileId, !!profile); 263 stopProfiling(m_frontendInitiatedProfileId, !!profile);
267 if (profile) { 264 if (profile) {
268 *profile = std::move(cpuProfile); 265 *profile = std::move(cpuProfile);
269 if (!profile->get()) return Response::Error("Profile is not found"); 266 if (!profile->get()) return Response::Error("Profile is not found");
270 } 267 }
271 m_frontendInitiatedProfileId = String16(); 268 m_frontendInitiatedProfileId = String16();
272 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false); 269 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false);
273 return Response::OK(); 270 return Response::OK();
274 } 271 }
275 272
273 Response V8ProfilerAgentImpl::startPreciseCoverage() {
274 if (!m_enabled) return Response::Error("Profiler is not enabled");
275 m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, true);
276 v8::debug::Coverage::TogglePrecise(m_isolate, true);
277 return Response::OK();
278 }
279
280 Response V8ProfilerAgentImpl::stopPreciseCoverage() {
281 if (!m_enabled) return Response::Error("Profiler is not enabled");
282 m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, false);
283 v8::debug::Coverage::TogglePrecise(m_isolate, false);
284 return Response::OK();
285 }
286
287 namespace {
288 Response takeCoverage(
289 v8::Isolate* isolate, bool reset_count,
290 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
291 out_result) {
292 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>> result =
293 protocol::Array<protocol::Profiler::ScriptCoverage>::create();
294 v8::HandleScope handle_scope(isolate);
295 v8::debug::Coverage coverage =
296 v8::debug::Coverage::Collect(isolate, reset_count);
297 for (size_t i = 0; i < coverage.ScriptCount(); i++) {
298 v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i);
299 v8::Local<v8::debug::Script> script = script_data.GetScript();
300 std::unique_ptr<protocol::Array<protocol::Profiler::FunctionCoverage>>
301 functions =
302 protocol::Array<protocol::Profiler::FunctionCoverage>::create();
303 for (size_t j = 0; j < script_data.FunctionCount(); j++) {
304 v8::debug::Coverage::FunctionData function_data =
305 script_data.GetFunctionData(j);
306 std::unique_ptr<protocol::Array<protocol::Profiler::CoverageRange>>
307 ranges = protocol::Array<protocol::Profiler::CoverageRange>::create();
308 // At this point we only have per-function coverage data, so there is
309 // only one range per function.
310 ranges->addItem(
311 protocol::Profiler::CoverageRange::create()
312 .setStartLineNumber(function_data.Start().GetLineNumber())
313 .setStartColumnNumber(function_data.Start().GetColumnNumber())
314 .setEndLineNumber(function_data.End().GetLineNumber())
315 .setEndColumnNumber(function_data.End().GetColumnNumber())
316 .setCount(function_data.Count())
317 .build());
318 functions->addItem(
319 protocol::Profiler::FunctionCoverage::create()
320 .setFunctionName(toProtocolString(
321 function_data.Name().FromMaybe(v8::Local<v8::String>())))
322 .setRanges(std::move(ranges))
323 .build());
324 }
325 String16 url;
326 v8::Local<v8::String> name;
327 if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) {
328 url = toProtocolString(name);
329 }
330 result->addItem(protocol::Profiler::ScriptCoverage::create()
331 .setScriptId(String16::fromInteger(script->Id()))
332 .setUrl(url)
333 .setFunctions(std::move(functions))
334 .build());
335 }
336 *out_result = std::move(result);
337 return Response::OK();
338 }
339 } // anonymous namespace
340
341 Response V8ProfilerAgentImpl::takePreciseCoverage(
342 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
343 out_result) {
344 if (!m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
345 false)) {
346 return Response::Error("Precise coverage has not been started.");
347 }
348 return takeCoverage(m_isolate, true, out_result);
349 }
350
351 Response V8ProfilerAgentImpl::getBestEffortCoverage(
352 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
353 out_result) {
354 return takeCoverage(m_isolate, false, out_result);
355 }
356
276 String16 V8ProfilerAgentImpl::nextProfileId() { 357 String16 V8ProfilerAgentImpl::nextProfileId() {
277 return String16::fromInteger( 358 return String16::fromInteger(
278 v8::base::NoBarrier_AtomicIncrement(&s_lastProfileId, 1)); 359 v8::base::NoBarrier_AtomicIncrement(&s_lastProfileId, 1));
279 } 360 }
280 361
281 void V8ProfilerAgentImpl::startProfiling(const String16& title) { 362 void V8ProfilerAgentImpl::startProfiling(const String16& title) {
282 v8::HandleScope handleScope(m_isolate); 363 v8::HandleScope handleScope(m_isolate);
364 if (!m_startedProfilesCount) {
365 DCHECK(!m_profiler);
366 m_profiler = v8::CpuProfiler::New(m_isolate);
367 m_profiler->SetIdle(m_idle);
368 int interval =
369 m_state->integerProperty(ProfilerAgentState::samplingInterval, 0);
370 if (interval) m_profiler->SetSamplingInterval(interval);
371 }
372 ++m_startedProfilesCount;
283 m_profiler->StartProfiling(toV8String(m_isolate, title), true); 373 m_profiler->StartProfiling(toV8String(m_isolate, title), true);
284 } 374 }
285 375
286 std::unique_ptr<protocol::Profiler::Profile> V8ProfilerAgentImpl::stopProfiling( 376 std::unique_ptr<protocol::Profiler::Profile> V8ProfilerAgentImpl::stopProfiling(
287 const String16& title, bool serialize) { 377 const String16& title, bool serialize) {
288 v8::HandleScope handleScope(m_isolate); 378 v8::HandleScope handleScope(m_isolate);
289 v8::CpuProfile* profile = 379 v8::CpuProfile* profile =
290 m_profiler->StopProfiling(toV8String(m_isolate, title)); 380 m_profiler->StopProfiling(toV8String(m_isolate, title));
291 if (!profile) return nullptr;
292 std::unique_ptr<protocol::Profiler::Profile> result; 381 std::unique_ptr<protocol::Profiler::Profile> result;
293 if (serialize) result = createCPUProfile(m_isolate, profile); 382 if (profile) {
294 profile->Delete(); 383 if (serialize) result = createCPUProfile(m_isolate, profile);
384 profile->Delete();
385 }
386 --m_startedProfilesCount;
387 if (!m_startedProfilesCount) {
388 m_profiler->Dispose();
389 m_profiler = nullptr;
390 }
295 return result; 391 return result;
296 } 392 }
297 393
298 bool V8ProfilerAgentImpl::isRecording() const {
299 return m_recordingCPUProfile || !m_startedProfiles.empty();
300 }
301
302 bool V8ProfilerAgentImpl::idleStarted() { 394 bool V8ProfilerAgentImpl::idleStarted() {
303 if (m_profiler) m_profiler->SetIdle(true); 395 m_idle = true;
396 if (m_profiler) m_profiler->SetIdle(m_idle);
304 return m_profiler; 397 return m_profiler;
305 } 398 }
306 399
307 bool V8ProfilerAgentImpl::idleFinished() { 400 bool V8ProfilerAgentImpl::idleFinished() {
308 if (m_profiler) m_profiler->SetIdle(false); 401 m_idle = false;
402 if (m_profiler) m_profiler->SetIdle(m_idle);
309 return m_profiler; 403 return m_profiler;
310 } 404 }
311 405
312 } // namespace v8_inspector 406 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-profiler-agent-impl.h ('k') | src/inspector/v8-runtime-agent-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698