| Index: src/d8.cc
|
| diff --git a/src/d8.cc b/src/d8.cc
|
| index c23458fc4f84955c1220aba6045fc98872384d1c..8ac494f5ffc0c70c32dcbe9b4f2b6a1c8a481485 100644
|
| --- a/src/d8.cc
|
| +++ b/src/d8.cc
|
| @@ -1849,6 +1849,33 @@ void Shell::WriteIgnitionDispatchCountersFile(v8::Isolate* isolate) {
|
| JSON::Stringify(context, dispatch_counters).ToLocalChecked());
|
| }
|
|
|
| +namespace {
|
| +int LineFromOffset(Local<debug::Script> script, int offset) {
|
| + debug::Location location = script->GetSourceLocation(offset);
|
| + return location.GetLineNumber();
|
| +}
|
| +
|
| +void WriteLcovDataForRange(std::vector<uint32_t>& lines, int start_line,
|
| + int end_line, uint32_t count) {
|
| + // Ensure space in the array.
|
| + lines.resize(std::max(static_cast<size_t>(end_line + 1), lines.size()), 0);
|
| + // Boundary lines could be shared between two functions with different
|
| + // invocation counts. Take the maximum.
|
| + lines[start_line] = std::max(lines[start_line], count);
|
| + lines[end_line] = std::max(lines[end_line], count);
|
| + // Invocation counts for non-boundary lines are overwritten.
|
| + for (int k = start_line + 1; k < end_line; k++) lines[k] = count;
|
| +}
|
| +
|
| +void WriteLcovDataForNamedRange(std::ostream& sink,
|
| + std::vector<uint32_t>& lines, std::string name,
|
| + int start_line, int end_line, uint32_t count) {
|
| + WriteLcovDataForRange(lines, start_line, end_line, count);
|
| + sink << "FN:" << start_line + 1 << "," << name << std::endl;
|
| + sink << "FNDA:" << count << "," << name << std::endl;
|
| +}
|
| +} // namespace
|
| +
|
| // Write coverage data in LCOV format. See man page for geninfo(1).
|
| void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) {
|
| if (!file) return;
|
| @@ -1870,33 +1897,38 @@ void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) {
|
| for (size_t j = 0; j < script_data.FunctionCount(); j++) {
|
| debug::Coverage::FunctionData function_data =
|
| script_data.GetFunctionData(j);
|
| - debug::Location start =
|
| - script->GetSourceLocation(function_data.StartOffset());
|
| - debug::Location end =
|
| - script->GetSourceLocation(function_data.EndOffset());
|
| - int start_line = start.GetLineNumber();
|
| - int end_line = end.GetLineNumber();
|
| - uint32_t count = function_data.Count();
|
| - // Ensure space in the array.
|
| - lines.resize(std::max(static_cast<size_t>(end_line + 1), lines.size()),
|
| - 0);
|
| - // Boundary lines could be shared between two functions with different
|
| - // invocation counts. Take the maximum.
|
| - lines[start_line] = std::max(lines[start_line], count);
|
| - lines[end_line] = std::max(lines[end_line], count);
|
| - // Invocation counts for non-boundary lines are overwritten.
|
| - for (int k = start_line + 1; k < end_line; k++) lines[k] = count;
|
| +
|
| // Write function stats.
|
| - Local<String> name;
|
| - std::stringstream name_stream;
|
| - if (function_data.Name().ToLocal(&name)) {
|
| - name_stream << ToSTLString(name);
|
| - } else {
|
| - name_stream << "<" << start_line + 1 << "-";
|
| - name_stream << start.GetColumnNumber() << ">";
|
| + {
|
| + debug::Location start =
|
| + script->GetSourceLocation(function_data.StartOffset());
|
| + debug::Location end =
|
| + script->GetSourceLocation(function_data.EndOffset());
|
| + int start_line = start.GetLineNumber();
|
| + int end_line = end.GetLineNumber();
|
| + uint32_t count = function_data.Count();
|
| +
|
| + Local<String> name;
|
| + std::stringstream name_stream;
|
| + if (function_data.Name().ToLocal(&name)) {
|
| + name_stream << ToSTLString(name);
|
| + } else {
|
| + name_stream << "<" << start_line + 1 << "-";
|
| + name_stream << start.GetColumnNumber() << ">";
|
| + }
|
| +
|
| + WriteLcovDataForNamedRange(sink, lines, name_stream.str(), start_line,
|
| + end_line, count);
|
| + }
|
| +
|
| + // Process inner blocks.
|
| + for (size_t k = 0; k < function_data.BlockCount(); k++) {
|
| + debug::Coverage::BlockData block_data = function_data.GetBlockData(k);
|
| + int start_line = LineFromOffset(script, block_data.StartOffset());
|
| + int end_line = LineFromOffset(script, block_data.EndOffset());
|
| + uint32_t count = block_data.Count();
|
| + WriteLcovDataForRange(lines, start_line, end_line, count);
|
| }
|
| - sink << "FN:" << start_line + 1 << "," << name_stream.str() << std::endl;
|
| - sink << "FNDA:" << count << "," << name_stream.str() << std::endl;
|
| }
|
| // Write per-line coverage. LCOV uses 1-based line numbers.
|
| for (size_t i = 0; i < lines.size(); i++) {
|
| @@ -2706,7 +2738,10 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) {
|
| {
|
| EnsureEventLoopInitialized(isolate);
|
| if (options.lcov_file) {
|
| - debug::Coverage::SelectMode(isolate, debug::Coverage::kPreciseCount);
|
| + debug::Coverage::Mode mode = i::FLAG_block_coverage
|
| + ? debug::Coverage::kBlockCount
|
| + : debug::Coverage::kPreciseCount;
|
| + debug::Coverage::SelectMode(isolate, mode);
|
| }
|
| HandleScope scope(isolate);
|
| Local<Context> context = CreateEvaluationContext(isolate);
|
|
|