[inspector] move coverage related methods to profiler
R=dgozman@chromium.org, pfeldman@chromium.org BUG=v8:5808 Review-Url: https://codereview.chromium.org/2715833003 Cr-Commit-Position: refs/heads/master@{#43426}
This commit is contained in:
parent
6b7650f039
commit
64a563c97f
@ -204,38 +204,6 @@
|
||||
{ "name": "parent", "$ref": "StackTrace", "optional": true, "description": "Asynchronous JavaScript stack trace that preceded this stack, if available." },
|
||||
{ "name": "promiseCreationFrame", "$ref": "CallFrame", "optional": true, "experimental": true, "description": "Creation frame of the Promise which produced the next synchronous trace when resolved, if available." }
|
||||
]
|
||||
},
|
||||
{ "id": "CoverageRange",
|
||||
"type": "object",
|
||||
"description": "Coverage data for a source range.",
|
||||
"properties": [
|
||||
{ "name": "startLineNumber", "type": "integer", "description": "JavaScript script line number (0-based) for the range start." },
|
||||
{ "name": "startColumnNumber", "type": "integer", "description": "JavaScript script column number (0-based) for the range start." },
|
||||
{ "name": "endLineNumber", "type": "integer", "description": "JavaScript script line number (0-based) for the range end." },
|
||||
{ "name": "endColumnNumber", "type": "integer", "description": "JavaScript script column number (0-based) for the range end." },
|
||||
{ "name": "count", "type": "integer", "description": "Collected execution count of the source range." }
|
||||
],
|
||||
"experimental": "true"
|
||||
},
|
||||
{ "id": "FunctionCoverage",
|
||||
"type": "object",
|
||||
"description": "Coverage data for a JavaScript function.",
|
||||
"properties": [
|
||||
{ "name": "functionName", "type": "string", "description": "JavaScript function name." },
|
||||
{ "name": "ranges", "type": "array", "items": { "$ref": "CoverageRange" }, "description": "Source ranges inside the function with coverage data." }
|
||||
],
|
||||
"experimental": "true"
|
||||
},
|
||||
{
|
||||
"id": "ScriptCoverage",
|
||||
"type": "object",
|
||||
"description": "Coverage data for a JavaScript script.",
|
||||
"properties": [
|
||||
{ "name": "scriptId", "$ref": "ScriptId", "description": "JavaScript script id." },
|
||||
{ "name": "url", "type": "string", "description": "JavaScript script name or url." },
|
||||
{ "name": "functions", "type": "array", "items": { "$ref": "FunctionCoverage" }, "description": "Functions contained in the script that has coverage data." }
|
||||
],
|
||||
"experimental": "true"
|
||||
}
|
||||
],
|
||||
"commands": [
|
||||
@ -375,32 +343,6 @@
|
||||
{ "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "description": "Exception details."}
|
||||
],
|
||||
"description": "Runs script with given id in a given context."
|
||||
},
|
||||
{
|
||||
"name": "startPreciseCoverage",
|
||||
"description": "Enable precise code coverage. Coverage data for JavaScript executed before enabling precise code coverage may be incomplete. Enabling prevents running optimized code and resets execution counters.",
|
||||
"experimental": true
|
||||
},
|
||||
{
|
||||
"name": "stopPreciseCoverage",
|
||||
"description": "Disable precise code coverage. Disabling releases unnecessary execution count records and allows executing optimized code.",
|
||||
"experimental": true
|
||||
},
|
||||
{
|
||||
"name": "takePreciseCoverage",
|
||||
"returns": [
|
||||
{ "name": "result", "type": "array", "items": { "$ref": "ScriptCoverage" }, "description": "Coverage data for the current isolate." }
|
||||
],
|
||||
"description": "Collect coverage data for the current isolate, and resets execution counters. Precise code coverage needs to have started.",
|
||||
"experimental": true
|
||||
},
|
||||
{
|
||||
"name": "getBestEffortCoverage",
|
||||
"returns": [
|
||||
{ "name": "result", "type": "array", "items": { "$ref": "ScriptCoverage" }, "description": "Coverage data for the current isolate." }
|
||||
],
|
||||
"description": "Collect coverage data for the current isolate. The coverage data may be incomplete due to garbage collection.",
|
||||
"experimental": true
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@ -882,6 +824,38 @@
|
||||
{ "name": "line", "type": "integer", "description": "Source line number (1-based)." },
|
||||
{ "name": "ticks", "type": "integer", "description": "Number of samples attributed to the source line." }
|
||||
]
|
||||
},
|
||||
{ "id": "CoverageRange",
|
||||
"type": "object",
|
||||
"description": "Coverage data for a source range.",
|
||||
"properties": [
|
||||
{ "name": "startLineNumber", "type": "integer", "description": "JavaScript script line number (0-based) for the range start." },
|
||||
{ "name": "startColumnNumber", "type": "integer", "description": "JavaScript script column number (0-based) for the range start." },
|
||||
{ "name": "endLineNumber", "type": "integer", "description": "JavaScript script line number (0-based) for the range end." },
|
||||
{ "name": "endColumnNumber", "type": "integer", "description": "JavaScript script column number (0-based) for the range end." },
|
||||
{ "name": "count", "type": "integer", "description": "Collected execution count of the source range." }
|
||||
],
|
||||
"experimental": true
|
||||
},
|
||||
{ "id": "FunctionCoverage",
|
||||
"type": "object",
|
||||
"description": "Coverage data for a JavaScript function.",
|
||||
"properties": [
|
||||
{ "name": "functionName", "type": "string", "description": "JavaScript function name." },
|
||||
{ "name": "ranges", "type": "array", "items": { "$ref": "CoverageRange" }, "description": "Source ranges inside the function with coverage data." }
|
||||
],
|
||||
"experimental": true
|
||||
},
|
||||
{
|
||||
"id": "ScriptCoverage",
|
||||
"type": "object",
|
||||
"description": "Coverage data for a JavaScript script.",
|
||||
"properties": [
|
||||
{ "name": "scriptId", "$ref": "Runtime.ScriptId", "description": "JavaScript script id." },
|
||||
{ "name": "url", "type": "string", "description": "JavaScript script name or url." },
|
||||
{ "name": "functions", "type": "array", "items": { "$ref": "FunctionCoverage" }, "description": "Functions contained in the script that has coverage data." }
|
||||
],
|
||||
"experimental": true
|
||||
}
|
||||
],
|
||||
"commands": [
|
||||
@ -906,6 +880,32 @@
|
||||
"returns": [
|
||||
{ "name": "profile", "$ref": "Profile", "description": "Recorded profile." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "startPreciseCoverage",
|
||||
"description": "Enable precise code coverage. Coverage data for JavaScript executed before enabling precise code coverage may be incomplete. Enabling prevents running optimized code and resets execution counters.",
|
||||
"experimental": true
|
||||
},
|
||||
{
|
||||
"name": "stopPreciseCoverage",
|
||||
"description": "Disable precise code coverage. Disabling releases unnecessary execution count records and allows executing optimized code.",
|
||||
"experimental": true
|
||||
},
|
||||
{
|
||||
"name": "takePreciseCoverage",
|
||||
"returns": [
|
||||
{ "name": "result", "type": "array", "items": { "$ref": "ScriptCoverage" }, "description": "Coverage data for the current isolate." }
|
||||
],
|
||||
"description": "Collect coverage data for the current isolate, and resets execution counters. Precise code coverage needs to have started.",
|
||||
"experimental": true
|
||||
},
|
||||
{
|
||||
"name": "getBestEffortCoverage",
|
||||
"returns": [
|
||||
{ "name": "result", "type": "array", "items": { "$ref": "ScriptCoverage" }, "description": "Coverage data for the current isolate." }
|
||||
],
|
||||
"description": "Collect coverage data for the current isolate. The coverage data may be incomplete due to garbage collection.",
|
||||
"experimental": true
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
|
@ -22,6 +22,7 @@ namespace ProfilerAgentState {
|
||||
static const char samplingInterval[] = "samplingInterval";
|
||||
static const char userInitiatedProfiling[] = "userInitiatedProfiling";
|
||||
static const char profilerEnabled[] = "profilerEnabled";
|
||||
static const char preciseCoverageStarted[] = "preciseCoverageStarted";
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -152,11 +153,8 @@ V8ProfilerAgentImpl::V8ProfilerAgentImpl(
|
||||
protocol::DictionaryValue* state)
|
||||
: m_session(session),
|
||||
m_isolate(m_session->inspector()->isolate()),
|
||||
m_profiler(nullptr),
|
||||
m_state(state),
|
||||
m_frontend(frontendChannel),
|
||||
m_enabled(false),
|
||||
m_recordingCPUProfile(false) {}
|
||||
m_frontend(frontendChannel) {}
|
||||
|
||||
V8ProfilerAgentImpl::~V8ProfilerAgentImpl() {
|
||||
if (m_profiler) m_profiler->Dispose();
|
||||
@ -204,8 +202,6 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) {
|
||||
Response V8ProfilerAgentImpl::enable() {
|
||||
if (m_enabled) return Response::OK();
|
||||
m_enabled = true;
|
||||
DCHECK(!m_profiler);
|
||||
m_profiler = v8::CpuProfiler::New(m_isolate);
|
||||
m_state->setBoolean(ProfilerAgentState::profilerEnabled, true);
|
||||
return Response::OK();
|
||||
}
|
||||
@ -216,18 +212,18 @@ Response V8ProfilerAgentImpl::disable() {
|
||||
stopProfiling(m_startedProfiles[i - 1].m_id, false);
|
||||
m_startedProfiles.clear();
|
||||
stop(nullptr);
|
||||
m_profiler->Dispose();
|
||||
m_profiler = nullptr;
|
||||
stopPreciseCoverage();
|
||||
DCHECK(!m_profiler);
|
||||
m_enabled = false;
|
||||
m_state->setBoolean(ProfilerAgentState::profilerEnabled, false);
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
Response V8ProfilerAgentImpl::setSamplingInterval(int interval) {
|
||||
if (m_recordingCPUProfile)
|
||||
if (m_profiler) {
|
||||
return Response::Error("Cannot change sampling interval when profiling.");
|
||||
}
|
||||
m_state->setInteger(ProfilerAgentState::samplingInterval, interval);
|
||||
m_profiler->SetSamplingInterval(interval);
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
@ -237,14 +233,14 @@ void V8ProfilerAgentImpl::restore() {
|
||||
return;
|
||||
m_enabled = true;
|
||||
DCHECK(!m_profiler);
|
||||
m_profiler = v8::CpuProfiler::New(m_isolate);
|
||||
int interval = 0;
|
||||
m_state->getInteger(ProfilerAgentState::samplingInterval, &interval);
|
||||
if (interval) m_profiler->SetSamplingInterval(interval);
|
||||
if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling,
|
||||
false)) {
|
||||
start();
|
||||
}
|
||||
if (m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
|
||||
false)) {
|
||||
startPreciseCoverage();
|
||||
}
|
||||
}
|
||||
|
||||
Response V8ProfilerAgentImpl::start() {
|
||||
@ -259,8 +255,9 @@ Response V8ProfilerAgentImpl::start() {
|
||||
|
||||
Response V8ProfilerAgentImpl::stop(
|
||||
std::unique_ptr<protocol::Profiler::Profile>* profile) {
|
||||
if (!m_recordingCPUProfile)
|
||||
if (!m_recordingCPUProfile) {
|
||||
return Response::Error("No recording profiles found");
|
||||
}
|
||||
m_recordingCPUProfile = false;
|
||||
std::unique_ptr<protocol::Profiler::Profile> cpuProfile =
|
||||
stopProfiling(m_frontendInitiatedProfileId, !!profile);
|
||||
@ -273,6 +270,90 @@ Response V8ProfilerAgentImpl::stop(
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
Response V8ProfilerAgentImpl::startPreciseCoverage() {
|
||||
if (!m_enabled) return Response::Error("Profiler is not enabled");
|
||||
m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, true);
|
||||
v8::debug::Coverage::TogglePrecise(m_isolate, true);
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
Response V8ProfilerAgentImpl::stopPreciseCoverage() {
|
||||
if (!m_enabled) return Response::Error("Profiler is not enabled");
|
||||
m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, false);
|
||||
v8::debug::Coverage::TogglePrecise(m_isolate, false);
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
namespace {
|
||||
Response takeCoverage(
|
||||
v8::Isolate* isolate, bool reset_count,
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
|
||||
out_result) {
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>> result =
|
||||
protocol::Array<protocol::Profiler::ScriptCoverage>::create();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::debug::Coverage coverage =
|
||||
v8::debug::Coverage::Collect(isolate, reset_count);
|
||||
for (size_t i = 0; i < coverage.ScriptCount(); i++) {
|
||||
v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i);
|
||||
v8::Local<v8::debug::Script> script = script_data.GetScript();
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::FunctionCoverage>>
|
||||
functions =
|
||||
protocol::Array<protocol::Profiler::FunctionCoverage>::create();
|
||||
for (size_t j = 0; j < script_data.FunctionCount(); j++) {
|
||||
v8::debug::Coverage::FunctionData function_data =
|
||||
script_data.GetFunctionData(j);
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::CoverageRange>>
|
||||
ranges = protocol::Array<protocol::Profiler::CoverageRange>::create();
|
||||
// At this point we only have per-function coverage data, so there is
|
||||
// only one range per function.
|
||||
ranges->addItem(
|
||||
protocol::Profiler::CoverageRange::create()
|
||||
.setStartLineNumber(function_data.Start().GetLineNumber())
|
||||
.setStartColumnNumber(function_data.Start().GetColumnNumber())
|
||||
.setEndLineNumber(function_data.End().GetLineNumber())
|
||||
.setEndColumnNumber(function_data.End().GetColumnNumber())
|
||||
.setCount(function_data.Count())
|
||||
.build());
|
||||
functions->addItem(
|
||||
protocol::Profiler::FunctionCoverage::create()
|
||||
.setFunctionName(toProtocolString(
|
||||
function_data.Name().FromMaybe(v8::Local<v8::String>())))
|
||||
.setRanges(std::move(ranges))
|
||||
.build());
|
||||
}
|
||||
String16 url;
|
||||
v8::Local<v8::String> name;
|
||||
if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) {
|
||||
url = toProtocolString(name);
|
||||
}
|
||||
result->addItem(protocol::Profiler::ScriptCoverage::create()
|
||||
.setScriptId(String16::fromInteger(script->Id()))
|
||||
.setUrl(url)
|
||||
.setFunctions(std::move(functions))
|
||||
.build());
|
||||
}
|
||||
*out_result = std::move(result);
|
||||
return Response::OK();
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
Response V8ProfilerAgentImpl::takePreciseCoverage(
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
|
||||
out_result) {
|
||||
if (!m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
|
||||
false)) {
|
||||
return Response::Error("Precise coverage has not been started.");
|
||||
}
|
||||
return takeCoverage(m_isolate, true, out_result);
|
||||
}
|
||||
|
||||
Response V8ProfilerAgentImpl::getBestEffortCoverage(
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
|
||||
out_result) {
|
||||
return takeCoverage(m_isolate, false, out_result);
|
||||
}
|
||||
|
||||
String16 V8ProfilerAgentImpl::nextProfileId() {
|
||||
return String16::fromInteger(
|
||||
v8::base::NoBarrier_AtomicIncrement(&s_lastProfileId, 1));
|
||||
@ -280,6 +361,15 @@ String16 V8ProfilerAgentImpl::nextProfileId() {
|
||||
|
||||
void V8ProfilerAgentImpl::startProfiling(const String16& title) {
|
||||
v8::HandleScope handleScope(m_isolate);
|
||||
if (!m_startedProfilesCount) {
|
||||
DCHECK(!m_profiler);
|
||||
m_profiler = v8::CpuProfiler::New(m_isolate);
|
||||
m_profiler->SetIdle(m_idle);
|
||||
int interval =
|
||||
m_state->integerProperty(ProfilerAgentState::samplingInterval, 0);
|
||||
if (interval) m_profiler->SetSamplingInterval(interval);
|
||||
}
|
||||
++m_startedProfilesCount;
|
||||
m_profiler->StartProfiling(toV8String(m_isolate, title), true);
|
||||
}
|
||||
|
||||
@ -288,24 +378,28 @@ std::unique_ptr<protocol::Profiler::Profile> V8ProfilerAgentImpl::stopProfiling(
|
||||
v8::HandleScope handleScope(m_isolate);
|
||||
v8::CpuProfile* profile =
|
||||
m_profiler->StopProfiling(toV8String(m_isolate, title));
|
||||
if (!profile) return nullptr;
|
||||
std::unique_ptr<protocol::Profiler::Profile> result;
|
||||
if (serialize) result = createCPUProfile(m_isolate, profile);
|
||||
profile->Delete();
|
||||
if (profile) {
|
||||
if (serialize) result = createCPUProfile(m_isolate, profile);
|
||||
profile->Delete();
|
||||
}
|
||||
--m_startedProfilesCount;
|
||||
if (!m_startedProfilesCount) {
|
||||
m_profiler->Dispose();
|
||||
m_profiler = nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool V8ProfilerAgentImpl::isRecording() const {
|
||||
return m_recordingCPUProfile || !m_startedProfiles.empty();
|
||||
}
|
||||
|
||||
bool V8ProfilerAgentImpl::idleStarted() {
|
||||
if (m_profiler) m_profiler->SetIdle(true);
|
||||
m_idle = true;
|
||||
if (m_profiler) m_profiler->SetIdle(m_idle);
|
||||
return m_profiler;
|
||||
}
|
||||
|
||||
bool V8ProfilerAgentImpl::idleFinished() {
|
||||
if (m_profiler) m_profiler->SetIdle(false);
|
||||
m_idle = false;
|
||||
if (m_profiler) m_profiler->SetIdle(m_idle);
|
||||
return m_profiler;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,15 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend {
|
||||
Response start() override;
|
||||
Response stop(std::unique_ptr<protocol::Profiler::Profile>*) override;
|
||||
|
||||
Response startPreciseCoverage() override;
|
||||
Response stopPreciseCoverage() override;
|
||||
Response takePreciseCoverage(
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
|
||||
out_result) override;
|
||||
Response getBestEffortCoverage(
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
|
||||
out_result) override;
|
||||
|
||||
void consoleProfile(const String16& title);
|
||||
void consoleProfileEnd(const String16& title);
|
||||
|
||||
@ -50,18 +59,18 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend {
|
||||
std::unique_ptr<protocol::Profiler::Profile> stopProfiling(
|
||||
const String16& title, bool serialize);
|
||||
|
||||
bool isRecording() const;
|
||||
|
||||
V8InspectorSessionImpl* m_session;
|
||||
v8::Isolate* m_isolate;
|
||||
v8::CpuProfiler* m_profiler;
|
||||
v8::CpuProfiler* m_profiler = nullptr;
|
||||
protocol::DictionaryValue* m_state;
|
||||
protocol::Profiler::Frontend m_frontend;
|
||||
bool m_enabled;
|
||||
bool m_recordingCPUProfile;
|
||||
bool m_enabled = false;
|
||||
bool m_recordingCPUProfile = false;
|
||||
class ProfileDescriptor;
|
||||
std::vector<ProfileDescriptor> m_startedProfiles;
|
||||
String16 m_frontendInitiatedProfileId;
|
||||
bool m_idle = false;
|
||||
int m_startedProfilesCount = 0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(V8ProfilerAgentImpl);
|
||||
};
|
||||
|
@ -52,7 +52,6 @@ namespace V8RuntimeAgentImplState {
|
||||
static const char customObjectFormatterEnabled[] =
|
||||
"customObjectFormatterEnabled";
|
||||
static const char runtimeEnabled[] = "runtimeEnabled";
|
||||
static const char preciseCoverageStarted[] = "preciseCoverageStarted";
|
||||
};
|
||||
|
||||
using protocol::Runtime::RemoteObject;
|
||||
@ -647,88 +646,6 @@ void V8RuntimeAgentImpl::runScript(
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
Response V8RuntimeAgentImpl::startPreciseCoverage() {
|
||||
m_state->setBoolean(V8RuntimeAgentImplState::preciseCoverageStarted, true);
|
||||
v8::debug::Coverage::TogglePrecise(m_inspector->isolate(), true);
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
Response V8RuntimeAgentImpl::stopPreciseCoverage() {
|
||||
m_state->setBoolean(V8RuntimeAgentImplState::preciseCoverageStarted, false);
|
||||
v8::debug::Coverage::TogglePrecise(m_inspector->isolate(), false);
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
namespace {
|
||||
Response takeCoverage(
|
||||
v8::Isolate* isolate, bool reset_count,
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>>*
|
||||
out_result) {
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>> result =
|
||||
protocol::Array<protocol::Runtime::ScriptCoverage>::create();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::debug::Coverage coverage =
|
||||
v8::debug::Coverage::Collect(isolate, reset_count);
|
||||
for (size_t i = 0; i < coverage.ScriptCount(); i++) {
|
||||
v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i);
|
||||
v8::Local<v8::debug::Script> script = script_data.GetScript();
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::FunctionCoverage>>
|
||||
functions =
|
||||
protocol::Array<protocol::Runtime::FunctionCoverage>::create();
|
||||
for (size_t j = 0; j < script_data.FunctionCount(); j++) {
|
||||
v8::debug::Coverage::FunctionData function_data =
|
||||
script_data.GetFunctionData(j);
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::CoverageRange>>
|
||||
ranges = protocol::Array<protocol::Runtime::CoverageRange>::create();
|
||||
// At this point we only have per-function coverage data, so there is
|
||||
// only one range per function.
|
||||
ranges->addItem(
|
||||
protocol::Runtime::CoverageRange::create()
|
||||
.setStartLineNumber(function_data.Start().GetLineNumber())
|
||||
.setStartColumnNumber(function_data.Start().GetColumnNumber())
|
||||
.setEndLineNumber(function_data.End().GetLineNumber())
|
||||
.setEndColumnNumber(function_data.End().GetColumnNumber())
|
||||
.setCount(function_data.Count())
|
||||
.build());
|
||||
functions->addItem(
|
||||
protocol::Runtime::FunctionCoverage::create()
|
||||
.setFunctionName(toProtocolString(
|
||||
function_data.Name().FromMaybe(v8::Local<v8::String>())))
|
||||
.setRanges(std::move(ranges))
|
||||
.build());
|
||||
}
|
||||
String16 url;
|
||||
v8::Local<v8::String> name;
|
||||
if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) {
|
||||
url = toProtocolString(name);
|
||||
}
|
||||
result->addItem(protocol::Runtime::ScriptCoverage::create()
|
||||
.setScriptId(String16::fromInteger(script->Id()))
|
||||
.setUrl(url)
|
||||
.setFunctions(std::move(functions))
|
||||
.build());
|
||||
}
|
||||
*out_result = std::move(result);
|
||||
return Response::OK();
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
Response V8RuntimeAgentImpl::takePreciseCoverage(
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>>*
|
||||
out_result) {
|
||||
if (!m_state->booleanProperty(V8RuntimeAgentImplState::preciseCoverageStarted,
|
||||
false)) {
|
||||
return Response::Error("Precise coverage has not been started.");
|
||||
}
|
||||
return takeCoverage(m_inspector->isolate(), true, out_result);
|
||||
}
|
||||
|
||||
Response V8RuntimeAgentImpl::getBestEffortCoverage(
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>>*
|
||||
out_result) {
|
||||
return takeCoverage(m_inspector->isolate(), false, out_result);
|
||||
}
|
||||
|
||||
void V8RuntimeAgentImpl::restore() {
|
||||
if (!m_state->booleanProperty(V8RuntimeAgentImplState::runtimeEnabled, false))
|
||||
return;
|
||||
@ -737,9 +654,6 @@ void V8RuntimeAgentImpl::restore() {
|
||||
if (m_state->booleanProperty(
|
||||
V8RuntimeAgentImplState::customObjectFormatterEnabled, false))
|
||||
m_session->setCustomObjectFormatterEnabled(true);
|
||||
if (m_state->booleanProperty(V8RuntimeAgentImplState::preciseCoverageStarted,
|
||||
false))
|
||||
startPreciseCoverage();
|
||||
}
|
||||
|
||||
Response V8RuntimeAgentImpl::enable() {
|
||||
@ -767,7 +681,6 @@ Response V8RuntimeAgentImpl::disable() {
|
||||
reset();
|
||||
m_inspector->client()->endEnsureAllContextsInGroup(
|
||||
m_session->contextGroupId());
|
||||
stopPreciseCoverage();
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
|
@ -97,14 +97,6 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend {
|
||||
Maybe<bool> includeCommandLineAPI, Maybe<bool> returnByValue,
|
||||
Maybe<bool> generatePreview, Maybe<bool> awaitPromise,
|
||||
std::unique_ptr<RunScriptCallback>) override;
|
||||
Response startPreciseCoverage() override;
|
||||
Response stopPreciseCoverage() override;
|
||||
Response takePreciseCoverage(
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>>*
|
||||
out_result) override;
|
||||
Response getBestEffortCoverage(
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>>*
|
||||
out_result) override;
|
||||
|
||||
void reset();
|
||||
void reportExecutionContextCreated(InspectedContext*);
|
||||
|
@ -1,4 +1,4 @@
|
||||
Test collecting code coverage data with Runtime.collectCoverage.
|
||||
Test collecting code coverage data with Profiler.collectCoverage.
|
||||
|
||||
Running test: testPreciseCoverage
|
||||
{
|
@ -14,7 +14,7 @@ function fib(x) {
|
||||
fib(5);
|
||||
`;
|
||||
|
||||
print("Test collecting code coverage data with Runtime.collectCoverage.");
|
||||
print("Test collecting code coverage data with Profiler.collectCoverage.");
|
||||
|
||||
function ClearAndGC() {
|
||||
return Protocol.Runtime.evaluate({ expression: "fib = null;" })
|
||||
@ -32,30 +32,34 @@ InspectorTest.runTestSuite([
|
||||
function testPreciseCoverage(next)
|
||||
{
|
||||
Protocol.Runtime.enable()
|
||||
.then(Protocol.Runtime.startPreciseCoverage)
|
||||
.then(Protocol.Profiler.enable)
|
||||
.then(Protocol.Profiler.startPreciseCoverage)
|
||||
.then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: "1", persistScript: true }))
|
||||
.then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
|
||||
.then(ClearAndGC)
|
||||
.then(InspectorTest.logMessage)
|
||||
.then(Protocol.Runtime.takePreciseCoverage)
|
||||
.then(Protocol.Profiler.takePreciseCoverage)
|
||||
.then(LogSorted)
|
||||
.then(Protocol.Runtime.takePreciseCoverage)
|
||||
.then(Protocol.Profiler.takePreciseCoverage)
|
||||
.then(LogSorted)
|
||||
.then(ClearAndGC)
|
||||
.then(Protocol.Runtime.stopPreciseCoverage)
|
||||
.then(Protocol.Profiler.stopPreciseCoverage)
|
||||
.then(Protocol.Profiler.disable)
|
||||
.then(Protocol.Runtime.disable)
|
||||
.then(next);
|
||||
},
|
||||
function testPreciseCoverageFail(next)
|
||||
{
|
||||
Protocol.Runtime.enable()
|
||||
.then(Protocol.Profiler.enable)
|
||||
.then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: "2", persistScript: true }))
|
||||
.then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
|
||||
.then(InspectorTest.logMessage)
|
||||
.then(ClearAndGC)
|
||||
.then(Protocol.Runtime.takePreciseCoverage)
|
||||
.then(Protocol.Profiler.takePreciseCoverage)
|
||||
.then(InspectorTest.logMessage)
|
||||
.then(ClearAndGC)
|
||||
.then(Protocol.Profiler.disable)
|
||||
.then(Protocol.Runtime.disable)
|
||||
.then(next);
|
||||
},
|
||||
@ -66,9 +70,9 @@ InspectorTest.runTestSuite([
|
||||
.then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
|
||||
.then(InspectorTest.logMessage)
|
||||
.then(ClearAndGC)
|
||||
.then(Protocol.Runtime.getBestEffortCoverage)
|
||||
.then(Protocol.Profiler.getBestEffortCoverage)
|
||||
.then(LogSorted)
|
||||
.then(Protocol.Runtime.getBestEffortCoverage)
|
||||
.then(Protocol.Profiler.getBestEffortCoverage)
|
||||
.then(LogSorted)
|
||||
.then(ClearAndGC)
|
||||
.then(Protocol.Runtime.disable)
|
||||
@ -77,17 +81,19 @@ InspectorTest.runTestSuite([
|
||||
function testBestEffortCoveragePrecise(next)
|
||||
{
|
||||
Protocol.Runtime.enable()
|
||||
.then(Protocol.Runtime.startPreciseCoverage)
|
||||
.then(Protocol.Profiler.enable)
|
||||
.then(Protocol.Profiler.startPreciseCoverage)
|
||||
.then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: "4", persistScript: true }))
|
||||
.then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
|
||||
.then(InspectorTest.logMessage)
|
||||
.then(ClearAndGC)
|
||||
.then(Protocol.Runtime.getBestEffortCoverage)
|
||||
.then(Protocol.Profiler.getBestEffortCoverage)
|
||||
.then(LogSorted)
|
||||
.then(Protocol.Runtime.getBestEffortCoverage)
|
||||
.then(Protocol.Profiler.getBestEffortCoverage)
|
||||
.then(LogSorted)
|
||||
.then(ClearAndGC)
|
||||
.then(Protocol.Runtime.stopPreciseCoverage)
|
||||
.then(Protocol.Profiler.stopPreciseCoverage)
|
||||
.then(Protocol.Profiler.disable)
|
||||
.then(Protocol.Runtime.disable)
|
||||
.then(next);
|
||||
},
|
Loading…
Reference in New Issue
Block a user