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

Unified Diff: src/d8.cc

Issue 2695823003: [debugger] add lcov support to d8. (Closed)
Patch Set: actual fix 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/d8.h ('k') | src/debug/debug-coverage.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index fcdf2b6e43e0a57f57520d904099e75a63ee7af0..e7e8c98343e5679f7c8550fe01e8a912433bb338 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -30,6 +30,7 @@
#include "src/base/platform/time.h"
#include "src/base/sys-info.h"
#include "src/basic-block-profiler.h"
+#include "src/debug/debug-coverage.h"
#include "src/interpreter/interpreter.h"
#include "src/list-inl.h"
#include "src/msan.h"
@@ -1654,6 +1655,70 @@ void Shell::WriteIgnitionDispatchCountersFile(v8::Isolate* isolate) {
JSON::Stringify(context, dispatch_counters).ToLocalChecked());
}
+namespace {
+void ReadRange(std::ofstream* s, std::vector<uint32_t>* lines,
+ i::Handle<i::Script> script, const i::Coverage::Range* range) {
+ // Compute line and column numbers from source position.
+ i::Script::PositionInfo start;
+ i::Script::PositionInfo end;
+ i::Script::GetPositionInfo(script, range->start, &start,
+ i::Script::NO_OFFSET);
+ i::Script::GetPositionInfo(script, range->end, &end, i::Script::NO_OFFSET);
+ // Boundary lines could be shared between two functions with different
+ // invocation counts. Take the maximum.
+ lines->at(start.line) = std::max(lines->at(start.line), range->count);
+ lines->at(end.line) = std::max(lines->at(end.line), range->count);
+ // Invocation counts for non-boundary lines are overwritten.
+ for (int i = start.line + 1; i < end.line; i++) lines->at(i) = range->count;
+ // Note that we use 0-based line numbers. But LCOV uses 1-based line numbers.
+ if (!range->name.empty()) {
+ // Truncate UC16 characters down to Latin1.
+ std::unique_ptr<char[]> name(new char[range->name.size() + 1]);
+ for (size_t i = 0; i < range->name.size(); i++) {
+ name[i] = static_cast<char>(range->name.data()[i]);
+ }
+ name[range->name.size()] = 0;
+ *s << "FN:" << (start.line + 1) << "," << name.get() << std::endl;
+ *s << "FNDA:" << range->count << "," << name.get() << std::endl;
+ } else {
+ // Anonymous function. Use line and column as name.
+ *s << "FN:" << (start.line + 1) << ",";
+ *s << "<" << (start.line + 1) << "-" << start.column << ">" << std::endl;
+ *s << "FNDA:" << range->count << ",";
+ *s << "<" << (start.line + 1) << "-" << start.column << ">" << std::endl;
+ }
+ // Recurse over inner ranges.
+ for (const auto& inner : range->inner) ReadRange(s, lines, script, &inner);
+}
+} // anonymous 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;
+ HandleScope handle_scope(isolate);
+ std::vector<i::Coverage::ScriptData> data =
+ i::Coverage::Collect(reinterpret_cast<i::Isolate*>(isolate));
+ std::ofstream sink(file, std::ofstream::app);
+ for (const auto& script_data : data) {
+ i::Handle<i::Script> script = script_data.script;
+ // Skip unnamed scripts.
+ if (!script->name()->IsString()) continue;
+ std::string file_name = ToSTLString(v8::Utils::ToLocal(
+ i::Handle<i::String>(i::String::cast(script->name()))));
+ // Skip scripts not backed by a file.
+ if (!std::ifstream(file_name).good()) continue;
+ sink << "SF:";
+ sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl;
+ std::vector<uint32_t> lines;
+ lines.resize(i::FixedArray::cast(script->line_ends())->length(), 0);
+ ReadRange(&sink, &lines, script, &script_data.toplevel);
+ // Write per-line coverage. LCOV uses 1-based line numbers.
+ for (size_t i = 0; i < lines.size(); i++) {
+ sink << "DA:" << (i + 1) << "," << lines[i] << std::endl;
+ }
+ sink << "end_of_record" << std::endl;
+ }
+}
void Shell::OnExit(v8::Isolate* isolate) {
if (i::FLAG_dump_counters || i::FLAG_dump_counters_nvp) {
@@ -1714,7 +1779,6 @@ void Shell::OnExit(v8::Isolate* isolate) {
}
-
static FILE* FOpen(const char* path, const char* mode) {
#if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
FILE* result;
@@ -2396,6 +2460,9 @@ bool Shell::SetOptions(int argc, char* argv[]) {
} else if (strcmp(argv[i], "--enable-inspector") == 0) {
options.enable_inspector = true;
argv[i] = NULL;
+ } else if (strncmp(argv[i], "--lcov=", 7) == 0) {
+ options.lcov_file = argv[i] + 7;
+ argv[i] = NULL;
}
}
@@ -2437,6 +2504,9 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) {
options.isolate_sources[i].StartExecuteInThread();
}
{
+ if (options.lcov_file) {
+ i::Coverage::EnablePrecise(reinterpret_cast<i::Isolate*>(isolate));
+ }
HandleScope scope(isolate);
Local<Context> context = CreateEvaluationContext(isolate);
if (last_run && options.use_interactive_shell()) {
@@ -2450,6 +2520,7 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) {
options.isolate_sources[0].Execute(isolate);
}
DisposeModuleEmbedderData(context);
+ WriteLcovData(isolate, options.lcov_file);
}
CollectGarbage(isolate);
for (int i = 1; i < options.num_isolates; ++i) {
« no previous file with comments | « src/d8.h ('k') | src/debug/debug-coverage.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698