Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: src/d8.cc

Issue 2696163002: [debugger] implement inspector-facing API for code coverage. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <errno.h> 5 #include <errno.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <string.h> 7 #include <string.h>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 12 matching lines...) Expand all
23 #include "include/libplatform/libplatform.h" 23 #include "include/libplatform/libplatform.h"
24 #include "include/libplatform/v8-tracing.h" 24 #include "include/libplatform/v8-tracing.h"
25 #include "src/api.h" 25 #include "src/api.h"
26 #include "src/base/cpu.h" 26 #include "src/base/cpu.h"
27 #include "src/base/debug/stack_trace.h" 27 #include "src/base/debug/stack_trace.h"
28 #include "src/base/logging.h" 28 #include "src/base/logging.h"
29 #include "src/base/platform/platform.h" 29 #include "src/base/platform/platform.h"
30 #include "src/base/platform/time.h" 30 #include "src/base/platform/time.h"
31 #include "src/base/sys-info.h" 31 #include "src/base/sys-info.h"
32 #include "src/basic-block-profiler.h" 32 #include "src/basic-block-profiler.h"
33 #include "src/debug/debug-coverage.h" 33 #include "src/debug/debug-interface.h"
34 #include "src/interpreter/interpreter.h" 34 #include "src/interpreter/interpreter.h"
35 #include "src/list-inl.h" 35 #include "src/list-inl.h"
36 #include "src/msan.h" 36 #include "src/msan.h"
37 #include "src/objects-inl.h" 37 #include "src/objects-inl.h"
38 #include "src/snapshot/natives.h" 38 #include "src/snapshot/natives.h"
39 #include "src/utils.h" 39 #include "src/utils.h"
40 #include "src/v8.h" 40 #include "src/v8.h"
41 41
42 #ifdef V8_INSPECTOR_ENABLED 42 #ifdef V8_INSPECTOR_ENABLED
43 #include "include/v8-inspector.h" 43 #include "include/v8-inspector.h"
(...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 ->interpreter() 1650 ->interpreter()
1651 ->GetDispatchCountersObject(); 1651 ->GetDispatchCountersObject();
1652 std::ofstream dispatch_counters_stream( 1652 std::ofstream dispatch_counters_stream(
1653 i::FLAG_trace_ignition_dispatches_output_file); 1653 i::FLAG_trace_ignition_dispatches_output_file);
1654 dispatch_counters_stream << *String::Utf8Value( 1654 dispatch_counters_stream << *String::Utf8Value(
1655 JSON::Stringify(context, dispatch_counters).ToLocalChecked()); 1655 JSON::Stringify(context, dispatch_counters).ToLocalChecked());
1656 } 1656 }
1657 1657
1658 namespace { 1658 namespace {
1659 void ReadRange(std::ofstream* s, std::vector<uint32_t>* lines, 1659 void ReadRange(std::ofstream* s, std::vector<uint32_t>* lines,
1660 i::Handle<i::Script> script, const i::Coverage::Range* range) { 1660 debug::Coverage::Range range) {
1661 // Compute line and column numbers from source position. 1661 // Ensure space in the array.
1662 i::Script::PositionInfo start; 1662 lines->resize(std::max(static_cast<size_t>(range.End().GetLineNumber() + 1),
1663 i::Script::PositionInfo end; 1663 lines->size()),
1664 i::Script::GetPositionInfo(script, range->start, &start, 1664 0);
1665 i::Script::NO_OFFSET);
1666 i::Script::GetPositionInfo(script, range->end, &end, i::Script::NO_OFFSET);
1667 // Boundary lines could be shared between two functions with different 1665 // Boundary lines could be shared between two functions with different
1668 // invocation counts. Take the maximum. 1666 // invocation counts. Take the maximum.
1669 lines->at(start.line) = std::max(lines->at(start.line), range->count); 1667 lines->at(range.Start().GetLineNumber()) =
1670 lines->at(end.line) = std::max(lines->at(end.line), range->count); 1668 std::max(lines->at(range.Start().GetLineNumber()), range.Count());
1669 lines->at(range.End().GetLineNumber()) =
1670 std::max(lines->at(range.End().GetLineNumber()), range.Count());
1671 // Invocation counts for non-boundary lines are overwritten. 1671 // Invocation counts for non-boundary lines are overwritten.
1672 for (int i = start.line + 1; i < end.line; i++) lines->at(i) = range->count; 1672 int line_plus_one = range.Start().GetLineNumber() + 1;
1673 for (int i = line_plus_one; i < range.End().GetLineNumber(); i++) {
1674 lines->at(i) = range.Count();
1675 }
1673 // Note that we use 0-based line numbers. But LCOV uses 1-based line numbers. 1676 // Note that we use 0-based line numbers. But LCOV uses 1-based line numbers.
1674 if (!range->name.empty()) { 1677 // Recurse over inner ranges.
1675 // Truncate UC16 characters down to Latin1. 1678 for (size_t i = 0; i < range.NestedCount(); i++) {
1676 std::unique_ptr<char[]> name(new char[range->name.size() + 1]); 1679 ReadRange(s, lines, range.GetNested(i));
1677 for (size_t i = 0; i < range->name.size(); i++) { 1680 }
1678 name[i] = static_cast<char>(range->name.data()[i]); 1681 // Write function stats.
1679 } 1682 Local<String> name;
1680 name[range->name.size()] = 0; 1683 std::stringstream name_stream;
1681 *s << "FN:" << (start.line + 1) << "," << name.get() << std::endl; 1684 if (range.Name().ToLocal(&name)) {
1682 *s << "FNDA:" << range->count << "," << name.get() << std::endl; 1685 name_stream << ToSTLString(name);
1683 } else { 1686 } else {
1684 // Anonymous function. Use line and column as name. 1687 name_stream << "<" << line_plus_one << "-";
1685 *s << "FN:" << (start.line + 1) << ","; 1688 name_stream << range.Start().GetColumnNumber() << ">";
1686 *s << "<" << (start.line + 1) << "-" << start.column << ">" << std::endl;
1687 *s << "FNDA:" << range->count << ",";
1688 *s << "<" << (start.line + 1) << "-" << start.column << ">" << std::endl;
1689 } 1689 }
1690 // Recurse over inner ranges. 1690 *s << "FN:" << line_plus_one << "," << name_stream.str() << std::endl;
1691 for (const auto& inner : range->inner) ReadRange(s, lines, script, &inner); 1691 *s << "FNDA:" << range.Count() << "," << name_stream.str() << std::endl;
1692 } 1692 }
1693 } // anonymous namespace 1693 } // anonymous namespace
1694 1694
1695 // Write coverage data in LCOV format. See man page for geninfo(1). 1695 // Write coverage data in LCOV format. See man page for geninfo(1).
1696 void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) { 1696 void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) {
1697 if (!file) return; 1697 if (!file) return;
1698 HandleScope handle_scope(isolate); 1698 HandleScope handle_scope(isolate);
1699 std::vector<i::Coverage::ScriptData> data = 1699 debug::Coverage coverage = debug::Coverage::Collect(isolate);
1700 i::Coverage::Collect(reinterpret_cast<i::Isolate*>(isolate));
1701 std::ofstream sink(file, std::ofstream::app); 1700 std::ofstream sink(file, std::ofstream::app);
1702 for (const auto& script_data : data) { 1701 for (size_t i = 0; i < coverage.ScriptCount(); i++) {
1703 i::Handle<i::Script> script = script_data.script; 1702 Local<debug::Script> script = coverage.GetScript(i);
1704 // Skip unnamed scripts. 1703 // Skip unnamed scripts.
1705 if (!script->name()->IsString()) continue; 1704 Local<String> name;
1706 std::string file_name = ToSTLString(v8::Utils::ToLocal( 1705 if (!script->Name().ToLocal(&name)) continue;
1707 i::Handle<i::String>(i::String::cast(script->name())))); 1706 std::string file_name = ToSTLString(name);
1708 // Skip scripts not backed by a file. 1707 // Skip scripts not backed by a file.
1709 if (!std::ifstream(file_name).good()) continue; 1708 if (!std::ifstream(file_name).good()) continue;
1710 sink << "SF:"; 1709 sink << "SF:";
1711 sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl; 1710 sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl;
1712 std::vector<uint32_t> lines; 1711 std::vector<uint32_t> lines;
1713 lines.resize(i::FixedArray::cast(script->line_ends())->length(), 0); 1712 ReadRange(&sink, &lines, coverage.GetRange(i));
1714 ReadRange(&sink, &lines, script, &script_data.toplevel);
1715 // Write per-line coverage. LCOV uses 1-based line numbers. 1713 // Write per-line coverage. LCOV uses 1-based line numbers.
1716 for (size_t i = 0; i < lines.size(); i++) { 1714 for (size_t i = 0; i < lines.size(); i++) {
1717 sink << "DA:" << (i + 1) << "," << lines[i] << std::endl; 1715 sink << "DA:" << (i + 1) << "," << lines[i] << std::endl;
1718 } 1716 }
1719 sink << "end_of_record" << std::endl; 1717 sink << "end_of_record" << std::endl;
1720 } 1718 }
1721 } 1719 }
1722 1720
1723 void Shell::OnExit(v8::Isolate* isolate) { 1721 void Shell::OnExit(v8::Isolate* isolate) {
1724 if (i::FLAG_dump_counters || i::FLAG_dump_counters_nvp) { 1722 if (i::FLAG_dump_counters || i::FLAG_dump_counters_nvp) {
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 2495
2498 return true; 2496 return true;
2499 } 2497 }
2500 2498
2501 2499
2502 int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) { 2500 int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) {
2503 for (int i = 1; i < options.num_isolates; ++i) { 2501 for (int i = 1; i < options.num_isolates; ++i) {
2504 options.isolate_sources[i].StartExecuteInThread(); 2502 options.isolate_sources[i].StartExecuteInThread();
2505 } 2503 }
2506 { 2504 {
2507 if (options.lcov_file) { 2505 if (options.lcov_file) debug::Coverage::TogglePrecise(isolate, true);
2508 i::Coverage::EnablePrecise(reinterpret_cast<i::Isolate*>(isolate));
2509 }
2510 HandleScope scope(isolate); 2506 HandleScope scope(isolate);
2511 Local<Context> context = CreateEvaluationContext(isolate); 2507 Local<Context> context = CreateEvaluationContext(isolate);
2512 if (last_run && options.use_interactive_shell()) { 2508 if (last_run && options.use_interactive_shell()) {
2513 // Keep using the same context in the interactive shell. 2509 // Keep using the same context in the interactive shell.
2514 evaluation_context_.Reset(isolate, context); 2510 evaluation_context_.Reset(isolate, context);
2515 } 2511 }
2516 { 2512 {
2517 Context::Scope cscope(context); 2513 Context::Scope cscope(context);
2518 InspectorClient inspector_client(context, options.enable_inspector); 2514 InspectorClient inspector_client(context, options.enable_inspector);
2519 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); 2515 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
2999 } 2995 }
3000 2996
3001 } // namespace v8 2997 } // namespace v8
3002 2998
3003 2999
3004 #ifndef GOOGLE3 3000 #ifndef GOOGLE3
3005 int main(int argc, char* argv[]) { 3001 int main(int argc, char* argv[]) {
3006 return v8::Shell::Main(argc, argv); 3002 return v8::Shell::Main(argc, argv);
3007 } 3003 }
3008 #endif 3004 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698