13#include "src/inspector/protocol/Protocol.h"
22namespace ProfilerAgentState {
30 "preciseCoverageAllowTriggeredUpdates";
38 if (!inspector)
return name;
39 std::unique_ptr<StringBuffer> url =
44std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>>
46 unsigned lineCount = node->GetHitLineCount();
47 if (!lineCount)
return nullptr;
49 std::make_unique<protocol::Array<protocol::Profiler::PositionTickInfo>>();
50 std::vector<v8::CpuProfileNode::LineTick>
entries(lineCount);
51 if (node->GetLineTicks(&
entries[0], lineCount)) {
52 for (
unsigned i = 0;
i < lineCount;
i++) {
53 std::unique_ptr<protocol::Profiler::PositionTickInfo> line =
54 protocol::Profiler::PositionTickInfo::create()
58 array->emplace_back(std::move(line));
64std::unique_ptr<protocol::Profiler::ProfileNode> buildInspectorObjectFor(
69 protocol::Runtime::CallFrame::create()
72 .setUrl(resourceNameToUrl(inspector, node->GetScriptResourceName()))
73 .setLineNumber(node->GetLineNumber() - 1)
74 .setColumnNumber(node->GetColumnNumber() - 1)
76 auto result = protocol::Profiler::ProfileNode::create()
77 .setCallFrame(std::move(callFrame))
78 .setHitCount(node->GetHitCount())
79 .setId(node->GetNodeId())
82 const int childrenCount = node->GetChildrenCount();
84 auto children = std::make_unique<protocol::Array<int>>();
85 for (
int i = 0;
i < childrenCount;
i++)
86 children->emplace_back(node->GetChild(
i)->GetNodeId());
90 const char* deoptReason = node->GetBailoutReason();
91 if (deoptReason && deoptReason[0] && strcmp(deoptReason,
"no reason"))
92 result->setDeoptReason(deoptReason);
94 auto positionTicks = buildInspectorObjectForPositionTicks(node);
95 if (positionTicks)
result->setPositionTicks(std::move(positionTicks));
100std::unique_ptr<protocol::Array<int>> buildInspectorObjectForSamples(
102 auto array = std::make_unique<protocol::Array<int>>();
105 array->emplace_back(v8profile->
GetSample(
i)->GetNodeId());
109std::unique_ptr<protocol::Array<int>> buildInspectorObjectForTimestamps(
111 auto array = std::make_unique<protocol::Array<int>>();
116 array->emplace_back(
static_cast<int>(ts - lastTime));
122void flattenNodesTree(V8InspectorImpl* inspector,
124 protocol::Array<protocol::Profiler::ProfileNode>* list) {
125 list->emplace_back(buildInspectorObjectFor(inspector, node));
126 const int childrenCount = node->GetChildrenCount();
127 for (
int i = 0;
i < childrenCount;
i++)
128 flattenNodesTree(inspector, node->GetChild(
i), list);
131std::unique_ptr<protocol::Profiler::Profile> createCPUProfile(
134 std::make_unique<protocol::Array<protocol::Profiler::ProfileNode>>();
135 flattenNodesTree(inspector, v8profile->
GetTopDownRoot(), nodes.get());
136 return protocol::Profiler::Profile::create()
137 .setNodes(std::move(nodes))
138 .setStartTime(
static_cast<double>(v8profile->
GetStartTime()))
139 .setEndTime(
static_cast<double>(v8profile->
GetEndTime()))
140 .setSamples(buildInspectorObjectForSamples(v8profile))
141 .setTimeDeltas(buildInspectorObjectForTimestamps(v8profile))
145std::unique_ptr<protocol::Debugger::Location> currentDebugLocation(
146 V8InspectorImpl* inspector) {
149 CHECK(!stackTrace->isEmpty());
150 return protocol::Debugger::Location::create()
152 .setLineNumber(stackTrace->topLineNumber())
153 .setColumnNumber(stackTrace->topColumnNumber())
157volatile int s_lastProfileId = 0;
171 protocol::DictionaryValue* state)
203 resolvedTitle = title;
209 if (
id.isEmpty())
return;
211 std::unique_ptr<protocol::Profiler::Profile> profile =
213 if (!profile)
return;
225 return Response::Success();
240 return Response::Success();
245 return Response::ServerError(
246 "Cannot change sampling interval when profiling.");
249 return Response::Success();
263 bool callCount =
m_state->booleanProperty(
265 bool detailed =
m_state->booleanProperty(
267 bool updatesAllowed =
m_state->booleanProperty(
271 std::optional<bool>(detailed),
272 std::optional<bool>(updatesAllowed), ×tamp);
279 if (!
m_enabled)
return Response::ServerError(
"Profiler is not enabled");
284 return Response::Success();
288 std::unique_ptr<protocol::Profiler::Profile>* profile) {
290 return Response::ServerError(
"No recording profiles found");
293 std::unique_ptr<protocol::Profiler::Profile> cpuProfile =
296 *profile = std::move(cpuProfile);
297 if (!*profile)
return Response::ServerError(
"Profile is not found");
301 return Response::Success();
305 std::optional<bool> callCount, std::optional<bool> detailed,
306 std::optional<bool> allowTriggeredUpdates,
double* out_timestamp) {
307 if (!
m_enabled)
return Response::ServerError(
"Profiler is not enabled");
309 bool callCountValue = callCount.value_or(
false);
310 bool detailedValue = detailed.value_or(
false);
311 bool allowTriggeredUpdatesValue = allowTriggeredUpdates.value_or(
false);
318 allowTriggeredUpdatesValue);
325 Mode mode = callCountValue
326 ? (detailedValue ? Mode::kBlockCount : Mode::kPreciseCount)
327 : (detailedValue ? Mode::kBlockBinary : Mode::kPreciseBinary);
329 return Response::Success();
333 if (!
m_enabled)
return Response::ServerError(
"Profiler is not enabled");
339 return Response::Success();
343std::unique_ptr<protocol::Profiler::CoverageRange> createCoverageRange(
345 return protocol::Profiler::CoverageRange::create()
346 .setStartOffset(
start)
352Response coverageToProtocol(
354 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
357 std::make_unique<protocol::Array<protocol::Profiler::ScriptCoverage>>();
359 for (
size_t i = 0;
i < coverage.ScriptCount();
i++) {
362 auto functions = std::make_unique<
363 protocol::Array<protocol::Profiler::FunctionCoverage>>();
367 auto ranges = std::make_unique<
368 protocol::Array<protocol::Profiler::CoverageRange>>();
371 ranges->emplace_back(createCoverageRange(function_data.
StartOffset(),
373 function_data.
Count()));
376 for (
size_t k = 0; k < function_data.
BlockCount(); k++) {
379 ranges->emplace_back(createCoverageRange(block_data.
StartOffset(),
381 block_data.
Count()));
384 functions->emplace_back(
385 protocol::Profiler::FunctionCoverage::create()
389 .setRanges(std::move(ranges))
395 if (script->SourceURL().ToLocal(&name) && name->Length()) {
397 }
else if (script->Name().ToLocal(&name) && name->Length()) {
398 url = resourceNameToUrl(inspector, name);
400 result->emplace_back(protocol::Profiler::ScriptCoverage::create()
403 .setFunctions(std::move(functions))
406 *out_result = std::move(
result);
407 return Response::Success();
412 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
414 double* out_timestamp) {
417 return Response::ServerError(
"Precise coverage has not been started.");
437 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>
441 m_frontend.preciseCoverageDeltaUpdate(now, occasion, std::move(out_result));
445 std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
472 const String16& title,
bool serialize) {
476 std::unique_ptr<protocol::Profiler::Profile>
result;
const CpuProfileNode * GetTopDownRoot() const
int GetSamplesCount() const
int64_t GetEndTime() const
const CpuProfileNode * GetSample(int index) const
int64_t GetSampleTimestamp(int index) const
int64_t GetStartTime() const
CpuProfilingStatus StartProfiling(Local< String > title, CpuProfilingOptions options, std::unique_ptr< DiscardedSamplesDelegate > delegate=nullptr)
static CpuProfiler * New(Isolate *isolate, CpuProfilingNamingMode=kDebugNaming, CpuProfilingLoggingMode=kLazyLogging)
CpuProfile * StopProfiling(Local< String > title)
void SetSamplingInterval(int us)
double InSecondsF() const
constexpr TimeDelta since_origin() const
bool HasBlockCoverage() const
BlockData GetBlockData(size_t i) const
MaybeLocal< String > Name() const
size_t BlockCount() const
FunctionData GetFunctionData(size_t i) const
size_t FunctionCount() const
Local< debug::Script > GetScript() const
static void SelectMode(Isolate *isolate, CoverageMode mode)
static Coverage CollectPrecise(Isolate *isolate)
static Coverage CollectBestEffort(Isolate *isolate)
static String16 fromInteger(int)
virtual std::unique_ptr< StringBuffer > resourceNameToUrl(const StringView &resourceName)
v8::Isolate * isolate() const
V8InspectorClient * client()
V8InspectorImpl * inspector() const
ProfileDescriptor(const String16 &id, const String16 &title)
Response takePreciseCoverage(std::unique_ptr< protocol::Array< protocol::Profiler::ScriptCoverage > > *out_result, double *out_timestamp) override
Response stopPreciseCoverage() override
void startProfiling(const String16 &title)
Response startPreciseCoverage(std::optional< bool > binary, std::optional< bool > detailed, std::optional< bool > allow_triggered_updates, double *out_timestamp) override
~V8ProfilerAgentImpl() override
protocol::Profiler::Frontend m_frontend
Response getBestEffortCoverage(std::unique_ptr< protocol::Array< protocol::Profiler::ScriptCoverage > > *out_result) override
void consoleProfile(const String16 &title)
Response start() override
String16 m_frontendInitiatedProfileId
V8InspectorSessionImpl * m_session
V8ProfilerAgentImpl(V8InspectorSessionImpl *, protocol::FrontendChannel *, protocol::DictionaryValue *state)
int m_startedProfilesCount
bool m_recordingCPUProfile
Response setSamplingInterval(int) override
std::vector< ProfileDescriptor > m_startedProfiles
Response disable() override
protocol::DictionaryValue * m_state
Response enable() override
std::unique_ptr< protocol::Profiler::Profile > stopProfiling(const String16 &title, bool serialize)
void triggerPreciseCoverageDeltaUpdate(const String16 &occasion)
Response stop(std::unique_ptr< protocol::Profiler::Profile > *) override
void consoleProfileEnd(const String16 &title)
v8::CpuProfiler * m_profiler
static std::unique_ptr< V8StackTraceImpl > capture(V8Debugger *, int maxStackSize)
std::vector< std::unique_ptr< InstanceTypeTree > > children
ZoneVector< RpoNumber > & result
ZoneVector< Entry > entries
Atomic32 Relaxed_AtomicIncrement(volatile Atomic32 *ptr, Atomic32 increment)
static const char preciseCoverageAllowTriggeredUpdates[]
static const char userInitiatedProfiling[]
static const char preciseCoverageCallCount[]
static const char preciseCoverageStarted[]
static const char samplingInterval[]
static const char preciseCoverageDetailed[]
static const char profilerEnabled[]
String16 toProtocolString(v8::Isolate *isolate, v8::Local< v8::String > value)
StringView toStringView(const String16 &string)
v8::Local< v8::String > toV8String(v8::Isolate *isolate, const String16 &string)
String16 toString16(const StringView &string)
#define DCHECK(condition)
V8InspectorSessionImpl * m_session
protocol::HeapProfiler::Frontend * m_frontend