| OLD | NEW |
| 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 static const char preciseCoverageStarted[] = "preciseCoverageStarted"; |
| 26 static const char preciseCoverageBinary[] = "preciseCoverageBinary"; |
| 26 } | 27 } |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>> | 31 std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>> |
| 31 buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) { | 32 buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) { |
| 32 unsigned lineCount = node->GetHitLineCount(); | 33 unsigned lineCount = node->GetHitLineCount(); |
| 33 if (!lineCount) return nullptr; | 34 if (!lineCount) return nullptr; |
| 34 auto array = protocol::Array<protocol::Profiler::PositionTickInfo>::create(); | 35 auto array = protocol::Array<protocol::Profiler::PositionTickInfo>::create(); |
| 35 std::vector<v8::CpuProfileNode::LineTick> entries(lineCount); | 36 std::vector<v8::CpuProfileNode::LineTick> entries(lineCount); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 if (!m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false)) | 233 if (!m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false)) |
| 233 return; | 234 return; |
| 234 m_enabled = true; | 235 m_enabled = true; |
| 235 DCHECK(!m_profiler); | 236 DCHECK(!m_profiler); |
| 236 if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling, | 237 if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling, |
| 237 false)) { | 238 false)) { |
| 238 start(); | 239 start(); |
| 239 } | 240 } |
| 240 if (m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted, | 241 if (m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted, |
| 241 false)) { | 242 false)) { |
| 242 startPreciseCoverage(); | 243 bool binary = m_state->booleanProperty( |
| 244 ProfilerAgentState::preciseCoverageBinary, false); |
| 245 startPreciseCoverage(Maybe<bool>(binary)); |
| 243 } | 246 } |
| 244 } | 247 } |
| 245 | 248 |
| 246 Response V8ProfilerAgentImpl::start() { | 249 Response V8ProfilerAgentImpl::start() { |
| 247 if (m_recordingCPUProfile) return Response::OK(); | 250 if (m_recordingCPUProfile) return Response::OK(); |
| 248 if (!m_enabled) return Response::Error("Profiler is not enabled"); | 251 if (!m_enabled) return Response::Error("Profiler is not enabled"); |
| 249 m_recordingCPUProfile = true; | 252 m_recordingCPUProfile = true; |
| 250 m_frontendInitiatedProfileId = nextProfileId(); | 253 m_frontendInitiatedProfileId = nextProfileId(); |
| 251 startProfiling(m_frontendInitiatedProfileId); | 254 startProfiling(m_frontendInitiatedProfileId); |
| 252 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true); | 255 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 263 stopProfiling(m_frontendInitiatedProfileId, !!profile); | 266 stopProfiling(m_frontendInitiatedProfileId, !!profile); |
| 264 if (profile) { | 267 if (profile) { |
| 265 *profile = std::move(cpuProfile); | 268 *profile = std::move(cpuProfile); |
| 266 if (!profile->get()) return Response::Error("Profile is not found"); | 269 if (!profile->get()) return Response::Error("Profile is not found"); |
| 267 } | 270 } |
| 268 m_frontendInitiatedProfileId = String16(); | 271 m_frontendInitiatedProfileId = String16(); |
| 269 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false); | 272 m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false); |
| 270 return Response::OK(); | 273 return Response::OK(); |
| 271 } | 274 } |
| 272 | 275 |
| 273 Response V8ProfilerAgentImpl::startPreciseCoverage() { | 276 Response V8ProfilerAgentImpl::startPreciseCoverage(Maybe<bool> binary) { |
| 274 if (!m_enabled) return Response::Error("Profiler is not enabled"); | 277 if (!m_enabled) return Response::Error("Profiler is not enabled"); |
| 278 bool isBinary = binary.fromMaybe(false); |
| 275 m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, true); | 279 m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, true); |
| 276 v8::debug::Coverage::SelectMode(m_isolate, | 280 m_state->setBoolean(ProfilerAgentState::preciseCoverageBinary, isBinary); |
| 277 v8::debug::Coverage::kPreciseCount); | 281 v8::debug::Coverage::SelectMode( |
| 282 m_isolate, isBinary ? v8::debug::Coverage::kPreciseBinary |
| 283 : v8::debug::Coverage::kPreciseCount); |
| 278 return Response::OK(); | 284 return Response::OK(); |
| 279 } | 285 } |
| 280 | 286 |
| 281 Response V8ProfilerAgentImpl::stopPreciseCoverage() { | 287 Response V8ProfilerAgentImpl::stopPreciseCoverage() { |
| 282 if (!m_enabled) return Response::Error("Profiler is not enabled"); | 288 if (!m_enabled) return Response::Error("Profiler is not enabled"); |
| 283 m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, false); | 289 m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, false); |
| 290 m_state->setBoolean(ProfilerAgentState::preciseCoverageBinary, false); |
| 284 v8::debug::Coverage::SelectMode(m_isolate, v8::debug::Coverage::kBestEffort); | 291 v8::debug::Coverage::SelectMode(m_isolate, v8::debug::Coverage::kBestEffort); |
| 285 return Response::OK(); | 292 return Response::OK(); |
| 286 } | 293 } |
| 287 | 294 |
| 288 namespace { | 295 namespace { |
| 289 Response takeCoverage( | 296 Response coverageToProtocol( |
| 290 v8::Isolate* isolate, bool reset_count, | 297 v8::Isolate* isolate, const v8::debug::Coverage& coverage, |
| 291 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>* | 298 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>* |
| 292 out_result) { | 299 out_result) { |
| 293 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>> result = | 300 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>> result = |
| 294 protocol::Array<protocol::Profiler::ScriptCoverage>::create(); | 301 protocol::Array<protocol::Profiler::ScriptCoverage>::create(); |
| 295 v8::HandleScope handle_scope(isolate); | |
| 296 v8::debug::Coverage coverage = | |
| 297 v8::debug::Coverage::Collect(isolate, reset_count); | |
| 298 for (size_t i = 0; i < coverage.ScriptCount(); i++) { | 302 for (size_t i = 0; i < coverage.ScriptCount(); i++) { |
| 299 v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); | 303 v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); |
| 300 v8::Local<v8::debug::Script> script = script_data.GetScript(); | 304 v8::Local<v8::debug::Script> script = script_data.GetScript(); |
| 301 std::unique_ptr<protocol::Array<protocol::Profiler::FunctionCoverage>> | 305 std::unique_ptr<protocol::Array<protocol::Profiler::FunctionCoverage>> |
| 302 functions = | 306 functions = |
| 303 protocol::Array<protocol::Profiler::FunctionCoverage>::create(); | 307 protocol::Array<protocol::Profiler::FunctionCoverage>::create(); |
| 304 for (size_t j = 0; j < script_data.FunctionCount(); j++) { | 308 for (size_t j = 0; j < script_data.FunctionCount(); j++) { |
| 305 v8::debug::Coverage::FunctionData function_data = | 309 v8::debug::Coverage::FunctionData function_data = |
| 306 script_data.GetFunctionData(j); | 310 script_data.GetFunctionData(j); |
| 307 std::unique_ptr<protocol::Array<protocol::Profiler::CoverageRange>> | 311 std::unique_ptr<protocol::Array<protocol::Profiler::CoverageRange>> |
| (...skipping 28 matching lines...) Expand all Loading... |
| 336 } | 340 } |
| 337 } // anonymous namespace | 341 } // anonymous namespace |
| 338 | 342 |
| 339 Response V8ProfilerAgentImpl::takePreciseCoverage( | 343 Response V8ProfilerAgentImpl::takePreciseCoverage( |
| 340 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>* | 344 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>* |
| 341 out_result) { | 345 out_result) { |
| 342 if (!m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted, | 346 if (!m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted, |
| 343 false)) { | 347 false)) { |
| 344 return Response::Error("Precise coverage has not been started."); | 348 return Response::Error("Precise coverage has not been started."); |
| 345 } | 349 } |
| 346 return takeCoverage(m_isolate, true, out_result); | 350 v8::HandleScope handle_scope(m_isolate); |
| 351 v8::debug::Coverage coverage = v8::debug::Coverage::CollectPrecise(m_isolate); |
| 352 return coverageToProtocol(m_isolate, coverage, out_result); |
| 347 } | 353 } |
| 348 | 354 |
| 349 Response V8ProfilerAgentImpl::getBestEffortCoverage( | 355 Response V8ProfilerAgentImpl::getBestEffortCoverage( |
| 350 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>* | 356 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>* |
| 351 out_result) { | 357 out_result) { |
| 352 return takeCoverage(m_isolate, false, out_result); | 358 v8::HandleScope handle_scope(m_isolate); |
| 359 v8::debug::Coverage coverage = |
| 360 v8::debug::Coverage::CollectBestEffort(m_isolate); |
| 361 return coverageToProtocol(m_isolate, coverage, out_result); |
| 353 } | 362 } |
| 354 | 363 |
| 355 String16 V8ProfilerAgentImpl::nextProfileId() { | 364 String16 V8ProfilerAgentImpl::nextProfileId() { |
| 356 return String16::fromInteger( | 365 return String16::fromInteger( |
| 357 v8::base::NoBarrier_AtomicIncrement(&s_lastProfileId, 1)); | 366 v8::base::NoBarrier_AtomicIncrement(&s_lastProfileId, 1)); |
| 358 } | 367 } |
| 359 | 368 |
| 360 void V8ProfilerAgentImpl::startProfiling(const String16& title) { | 369 void V8ProfilerAgentImpl::startProfiling(const String16& title) { |
| 361 v8::HandleScope handleScope(m_isolate); | 370 v8::HandleScope handleScope(m_isolate); |
| 362 if (!m_startedProfilesCount) { | 371 if (!m_startedProfilesCount) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 return m_profiler; | 404 return m_profiler; |
| 396 } | 405 } |
| 397 | 406 |
| 398 bool V8ProfilerAgentImpl::idleFinished() { | 407 bool V8ProfilerAgentImpl::idleFinished() { |
| 399 m_idle = false; | 408 m_idle = false; |
| 400 if (m_profiler) m_profiler->SetIdle(m_idle); | 409 if (m_profiler) m_profiler->SetIdle(m_idle); |
| 401 return m_profiler; | 410 return m_profiler; |
| 402 } | 411 } |
| 403 | 412 |
| 404 } // namespace v8_inspector | 413 } // namespace v8_inspector |
| OLD | NEW |