[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:
kozyatinskiy 2017-02-24 18:44:56 -08:00 committed by Commit bot
parent 6b7650f039
commit 64a563c97f
7 changed files with 209 additions and 195 deletions

View File

@ -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": [

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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();
}

View File

@ -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*);

View File

@ -1,4 +1,4 @@
Test collecting code coverage data with Runtime.collectCoverage.
Test collecting code coverage data with Profiler.collectCoverage.
Running test: testPreciseCoverage
{

View File

@ -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);
},