Commit a7577ede authored by yangguo's avatar yangguo Committed by Commit bot

[debug] do not report unnecessary coverage data.

Only include function ranges for with non-0 counts or if the immediate outer function has non-0 count.

R=caseq@chromium.org, jgruber@chromium.org
BUG=v8:5808

Review-Url: https://codereview.chromium.org/2764073004
Cr-Commit-Position: refs/heads/master@{#44079}
parent b123ee34
...@@ -121,7 +121,7 @@ Coverage* Coverage::Collect(Isolate* isolate, ...@@ -121,7 +121,7 @@ Coverage* Coverage::Collect(Isolate* isolate,
// Create and add new script data. // Create and add new script data.
Handle<Script> script_handle(script, isolate); Handle<Script> script_handle(script, isolate);
result->emplace_back(isolate, script_handle); result->emplace_back(script_handle);
std::vector<CoverageFunction>* functions = &result->back().functions; std::vector<CoverageFunction>* functions = &result->back().functions;
std::vector<SharedFunctionInfo*> sorted; std::vector<SharedFunctionInfo*> sorted;
...@@ -135,11 +135,18 @@ Coverage* Coverage::Collect(Isolate* isolate, ...@@ -135,11 +135,18 @@ Coverage* Coverage::Collect(Isolate* isolate,
std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo); std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo);
} }
// Stack to track nested functions, referring function by index.
std::vector<size_t> nesting;
// Use sorted list to reconstruct function nesting. // Use sorted list to reconstruct function nesting.
for (SharedFunctionInfo* info : sorted) { for (SharedFunctionInfo* info : sorted) {
int start = StartPosition(info); int start = StartPosition(info);
int end = info->end_position(); int end = info->end_position();
uint32_t count = counter_map.Get(info); uint32_t count = counter_map.Get(info);
// Find the correct outer function based on start position.
while (!nesting.empty() && functions->at(nesting.back()).end <= start) {
nesting.pop_back();
}
if (count != 0) { if (count != 0) {
switch (collectionMode) { switch (collectionMode) {
case v8::debug::Coverage::kPreciseCount: case v8::debug::Coverage::kPreciseCount:
...@@ -152,10 +159,18 @@ Coverage* Coverage::Collect(Isolate* isolate, ...@@ -152,10 +159,18 @@ Coverage* Coverage::Collect(Isolate* isolate,
count = 1; count = 1;
break; break;
} }
} else if (nesting.empty() || functions->at(nesting.back()).count == 0) {
// Only include a function range if it has a non-0 count, or
// if it is directly nested inside a function with non-0 count.
continue;
} }
Handle<String> name(info->DebugName(), isolate); Handle<String> name(info->DebugName(), isolate);
nesting.push_back(functions->size());
functions->emplace_back(start, end, count, name); functions->emplace_back(start, end, count, name);
} }
// Remove entries for scripts that have no coverage.
if (functions->empty()) result->pop_back();
} }
return result; return result;
} }
......
...@@ -27,7 +27,7 @@ struct CoverageFunction { ...@@ -27,7 +27,7 @@ struct CoverageFunction {
struct CoverageScript { struct CoverageScript {
// Initialize top-level function in case it has been garbage-collected. // Initialize top-level function in case it has been garbage-collected.
CoverageScript(Isolate* isolate, Handle<Script> s) : script(s) {} explicit CoverageScript(Handle<Script> s) : script(s) {}
Handle<Script> script; Handle<Script> script;
// Functions are sorted by start position, from outer to inner function. // Functions are sorted by start position, from outer to inner function.
std::vector<CoverageFunction> functions; std::vector<CoverageFunction> functions;
......
...@@ -17,16 +17,6 @@ Running test: testPreciseCountBaseline ...@@ -17,16 +17,6 @@ Running test: testPreciseCountBaseline
} }
] ]
} }
[1] : {
functionName : is_optimized
ranges : [
[0] : {
count : 0
endOffset : 175
startOffset : 74
}
]
}
] ]
scriptId : <scriptId> scriptId : <scriptId>
url : testPreciseCountBaseline url : testPreciseCountBaseline
...@@ -38,32 +28,6 @@ Running test: testPreciseCountBaseline ...@@ -38,32 +28,6 @@ Running test: testPreciseCountBaseline
id : <messageId> id : <messageId>
result : { result : {
result : [ result : [
[0] : {
functions : [
[0] : {
functionName : fib
ranges : [
[0] : {
count : 0
endOffset : 73
startOffset : 1
}
]
}
[1] : {
functionName : is_optimized
ranges : [
[0] : {
count : 0
endOffset : 175
startOffset : 74
}
]
}
]
scriptId : <scriptId>
url : testPreciseCountBaseline
}
] ]
} }
} }
...@@ -72,6 +36,11 @@ Running test: testPreciseCountCoverage ...@@ -72,6 +36,11 @@ Running test: testPreciseCountCoverage
{ {
id : <messageId> id : <messageId>
result : { result : {
result : {
description : 8
type : number
value : 8
}
} }
} }
{ {
...@@ -147,68 +116,6 @@ Running test: testPreciseCountCoverage ...@@ -147,68 +116,6 @@ Running test: testPreciseCountCoverage
id : <messageId> id : <messageId>
result : { result : {
result : [ result : [
[0] : {
functions : [
[0] : {
functionName :
ranges : [
[0] : {
count : 0
endOffset : 221
startOffset : 0
}
]
}
[1] : {
functionName : fib
ranges : [
[0] : {
count : 0
endOffset : 73
startOffset : 1
}
]
}
[2] : {
functionName : is_optimized
ranges : [
[0] : {
count : 0
endOffset : 175
startOffset : 74
}
]
}
[3] : {
functionName : iife
ranges : [
[0] : {
count : 0
endOffset : 208
startOffset : 177
}
]
}
]
scriptId : <scriptId>
url : testPreciseCountCoverage
}
[1] : {
functions : [
[0] : {
functionName :
ranges : [
[0] : {
count : 0
endOffset : 38
startOffset : 0
}
]
}
]
scriptId : <scriptId>
url :
}
] ]
} }
} }
...@@ -734,75 +641,196 @@ Running test: testPreciseBinaryCoverage ...@@ -734,75 +641,196 @@ Running test: testPreciseBinaryCoverage
result : { result : {
result : [ result : [
[0] : { [0] : {
functions : [
[0] : {
functionName : is_optimized
ranges : [
[0] : {
count : 1
endOffset : 175
startOffset : 74
}
]
}
]
scriptId : <scriptId>
url : testPreciseBinaryCoverage
}
[1] : {
functions : [ functions : [
[0] : { [0] : {
functionName : functionName :
ranges : [ ranges : [
[0] : { [0] : {
count : 0 count : 1
endOffset : 221 endOffset : 17
startOffset : 0
}
]
}
]
scriptId : <scriptId>
url :
}
[2] : {
functions : [
[0] : {
functionName :
ranges : [
[0] : {
count : 1
endOffset : 7
startOffset : 0
}
]
}
]
scriptId : <scriptId>
url :
}
]
}
}
Running test: testPreciseEmptyScriptCoverageEntries
{
id : <messageId>
result : {
result : [
]
}
}
Running test: testPreciseCountCoveragePartial
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
{
id : <messageId>
result : {
result : [
[0] : {
functions : [
[0] : {
functionName :
ranges : [
[0] : {
count : 1
endOffset : 238
startOffset : 0 startOffset : 0
} }
] ]
} }
[1] : { [1] : {
functionName : fib functionName : outer
ranges : [ ranges : [
[0] : { [0] : {
count : 0 count : 1
endOffset : 73 endOffset : 224
startOffset : 1 startOffset : 10
} }
] ]
} }
[2] : { [2] : {
functionName : is_optimized functionName : nested_0
ranges : [ ranges : [
[0] : { [0] : {
count : 1 count : 1
endOffset : 175 endOffset : 176
startOffset : 74 startOffset : 31
} }
] ]
} }
[3] : { [3] : {
functionName : iife functionName : nested_1
ranges : [
[0] : {
count : 1
endOffset : 172
startOffset : 64
}
]
}
[4] : {
functionName : nested_2
ranges : [
[0] : {
count : 1
endOffset : 166
startOffset : 99
}
]
}
[5] : {
functionName : nested_3
ranges : [
[0] : {
count : 1
endOffset : 158
startOffset : 136
}
]
}
[6] : {
functionName : nested_4
ranges : [ ranges : [
[0] : { [0] : {
count : 0 count : 0
endOffset : 208 endOffset : 201
startOffset : 177 startOffset : 179
} }
] ]
} }
] ]
scriptId : <scriptId> scriptId : <scriptId>
url : testPreciseBinaryCoverage url : testPreciseCountCoveragePartial
} }
[1] : { ]
}
}
{
id : <messageId>
result : {
result : [
[0] : {
functions : [ functions : [
[0] : { [0] : {
functionName : functionName : nested_1
ranges : [ ranges : [
[0] : { [0] : {
count : 1 count : 1
endOffset : 17 endOffset : 172
startOffset : 0 startOffset : 64
}
]
}
[1] : {
functionName : nested_2
ranges : [
[0] : {
count : 0
endOffset : 166
startOffset : 99
} }
] ]
} }
] ]
scriptId : <scriptId> scriptId : <scriptId>
url : url : testPreciseCountCoveragePartial
} }
[2] : { [1] : {
functions : [ functions : [
[0] : { [0] : {
functionName : functionName :
ranges : [ ranges : [
[0] : { [0] : {
count : 1 count : 1
endOffset : 7 endOffset : 3
startOffset : 0 startOffset : 0
} }
] ]
......
...@@ -34,6 +34,22 @@ function h() { ...@@ -34,6 +34,22 @@ function h() {
f(3); f(3);
`; `;
var nested =
`
var f = (function outer() {
function nested_0() {
return function nested_1() {
return function nested_2() {
return function nested_3() {}
}
}
}
function nested_4() {}
return nested_0();
})();
f()()();
`;
InspectorTest.log("Test collecting code coverage data with Profiler.collectCoverage."); InspectorTest.log("Test collecting code coverage data with Profiler.collectCoverage.");
function ClearAndGC() { function ClearAndGC() {
...@@ -78,8 +94,8 @@ InspectorTest.runTestSuite([ ...@@ -78,8 +94,8 @@ InspectorTest.runTestSuite([
.then(() => Protocol.Profiler.startPreciseCoverage({callCount: true})) .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true}))
.then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true })) .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
.then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId })) .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
.then(ClearAndGC)
.then(InspectorTest.logMessage) .then(InspectorTest.logMessage)
.then(ClearAndGC)
.then(Protocol.Profiler.takePreciseCoverage) .then(Protocol.Profiler.takePreciseCoverage)
.then(LogSorted) .then(LogSorted)
.then(Protocol.Profiler.takePreciseCoverage) .then(Protocol.Profiler.takePreciseCoverage)
...@@ -208,4 +224,44 @@ InspectorTest.runTestSuite([ ...@@ -208,4 +224,44 @@ InspectorTest.runTestSuite([
.then(ClearAndGC) .then(ClearAndGC)
.then(next); .then(next);
}, },
function testPreciseEmptyScriptCoverageEntries(next)
{
// Enabling the debugger holds onto script objects even though its
// functions can be garbage collected. We would get empty ScriptCoverage
// entires unless we remove them.
Protocol.Debugger.enable()
.then(Protocol.Runtime.enable)
.then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
.then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
.then(ClearAndGC)
.then(Protocol.Profiler.enable)
.then(Protocol.Profiler.startPreciseCoverage)
.then(Protocol.Profiler.takePreciseCoverage)
.then(LogSorted)
.then(Protocol.Profiler.stopPreciseCoverage)
.then(Protocol.Profiler.disable)
.then(Protocol.Runtime.disable)
.then(Protocol.Debugger.disable)
.then(ClearAndGC)
.then(next);
},
function testPreciseCountCoveragePartial(next)
{
Protocol.Runtime.enable()
.then(Protocol.Profiler.enable)
.then(() => Protocol.Profiler.startPreciseCoverage({callCount: true}))
.then(() => Protocol.Runtime.compileScript({ expression: nested, sourceURL: arguments.callee.name, persistScript: true }))
.then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
.then(InspectorTest.logMessage)
.then(Protocol.Profiler.takePreciseCoverage)
.then(LogSorted)
.then(() => Protocol.Runtime.evaluate({ expression: "f()" }))
.then(Protocol.Profiler.takePreciseCoverage)
.then(LogSorted)
.then(Protocol.Profiler.stopPreciseCoverage)
.then(Protocol.Profiler.disable)
.then(Protocol.Runtime.disable)
.then(ClearAndGC)
.then(next);
},
]); ]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment