| OLD | NEW |
| 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 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1650 | 1650 |
| 1651 Local<Object> dispatch_counters = reinterpret_cast<i::Isolate*>(isolate) | 1651 Local<Object> dispatch_counters = reinterpret_cast<i::Isolate*>(isolate) |
| 1652 ->interpreter() | 1652 ->interpreter() |
| 1653 ->GetDispatchCountersObject(); | 1653 ->GetDispatchCountersObject(); |
| 1654 std::ofstream dispatch_counters_stream( | 1654 std::ofstream dispatch_counters_stream( |
| 1655 i::FLAG_trace_ignition_dispatches_output_file); | 1655 i::FLAG_trace_ignition_dispatches_output_file); |
| 1656 dispatch_counters_stream << *String::Utf8Value( | 1656 dispatch_counters_stream << *String::Utf8Value( |
| 1657 JSON::Stringify(context, dispatch_counters).ToLocalChecked()); | 1657 JSON::Stringify(context, dispatch_counters).ToLocalChecked()); |
| 1658 } | 1658 } |
| 1659 | 1659 |
| 1660 namespace { | |
| 1661 void ReadRange(std::ofstream* s, std::vector<uint32_t>* lines, | |
| 1662 debug::Coverage::Range range) { | |
| 1663 // Ensure space in the array. | |
| 1664 lines->resize(std::max(static_cast<size_t>(range.End().GetLineNumber() + 1), | |
| 1665 lines->size()), | |
| 1666 0); | |
| 1667 // Boundary lines could be shared between two functions with different | |
| 1668 // invocation counts. Take the maximum. | |
| 1669 lines->at(range.Start().GetLineNumber()) = | |
| 1670 std::max(lines->at(range.Start().GetLineNumber()), range.Count()); | |
| 1671 lines->at(range.End().GetLineNumber()) = | |
| 1672 std::max(lines->at(range.End().GetLineNumber()), range.Count()); | |
| 1673 // Invocation counts for non-boundary lines are overwritten. | |
| 1674 int line_plus_one = range.Start().GetLineNumber() + 1; | |
| 1675 for (int i = line_plus_one; i < range.End().GetLineNumber(); i++) { | |
| 1676 lines->at(i) = range.Count(); | |
| 1677 } | |
| 1678 // Note that we use 0-based line numbers. But LCOV uses 1-based line numbers. | |
| 1679 // Recurse over inner ranges. | |
| 1680 for (size_t i = 0; i < range.NestedCount(); i++) { | |
| 1681 ReadRange(s, lines, range.GetNested(i)); | |
| 1682 } | |
| 1683 // Write function stats. | |
| 1684 Local<String> name; | |
| 1685 std::stringstream name_stream; | |
| 1686 if (range.Name().ToLocal(&name)) { | |
| 1687 name_stream << ToSTLString(name); | |
| 1688 } else { | |
| 1689 name_stream << "<" << line_plus_one << "-"; | |
| 1690 name_stream << range.Start().GetColumnNumber() << ">"; | |
| 1691 } | |
| 1692 *s << "FN:" << line_plus_one << "," << name_stream.str() << std::endl; | |
| 1693 *s << "FNDA:" << range.Count() << "," << name_stream.str() << std::endl; | |
| 1694 } | |
| 1695 } // anonymous namespace | |
| 1696 | |
| 1697 // Write coverage data in LCOV format. See man page for geninfo(1). | 1660 // Write coverage data in LCOV format. See man page for geninfo(1). |
| 1698 void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) { | 1661 void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) { |
| 1699 if (!file) return; | 1662 if (!file) return; |
| 1700 HandleScope handle_scope(isolate); | 1663 HandleScope handle_scope(isolate); |
| 1701 debug::Coverage coverage = debug::Coverage::Collect(isolate); | 1664 debug::Coverage coverage = debug::Coverage::Collect(isolate, false); |
| 1702 std::ofstream sink(file, std::ofstream::app); | 1665 std::ofstream sink(file, std::ofstream::app); |
| 1703 for (size_t i = 0; i < coverage.ScriptCount(); i++) { | 1666 for (size_t i = 0; i < coverage.ScriptCount(); i++) { |
| 1704 Local<debug::Script> script = coverage.GetScript(i); | 1667 debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); |
| 1668 Local<debug::Script> script = script_data.GetScript(); |
| 1705 // Skip unnamed scripts. | 1669 // Skip unnamed scripts. |
| 1706 Local<String> name; | 1670 Local<String> name; |
| 1707 if (!script->Name().ToLocal(&name)) continue; | 1671 if (!script->Name().ToLocal(&name)) continue; |
| 1708 std::string file_name = ToSTLString(name); | 1672 std::string file_name = ToSTLString(name); |
| 1709 // Skip scripts not backed by a file. | 1673 // Skip scripts not backed by a file. |
| 1710 if (!std::ifstream(file_name).good()) continue; | 1674 if (!std::ifstream(file_name).good()) continue; |
| 1711 sink << "SF:"; | 1675 sink << "SF:"; |
| 1712 sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl; | 1676 sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl; |
| 1713 std::vector<uint32_t> lines; | 1677 std::vector<uint32_t> lines; |
| 1714 ReadRange(&sink, &lines, coverage.GetRange(i)); | 1678 for (size_t j = 0; j < script_data.FunctionCount(); j++) { |
| 1679 debug::Coverage::FunctionData function_data = |
| 1680 script_data.GetFunctionData(j); |
| 1681 int start_line = function_data.Start().GetLineNumber(); |
| 1682 int end_line = function_data.End().GetLineNumber(); |
| 1683 uint32_t count = function_data.Count(); |
| 1684 // Ensure space in the array. |
| 1685 lines.resize(std::max(static_cast<size_t>(end_line + 1), lines.size()), |
| 1686 0); |
| 1687 // Boundary lines could be shared between two functions with different |
| 1688 // invocation counts. Take the maximum. |
| 1689 lines[start_line] = std::max(lines[start_line], count); |
| 1690 lines[end_line] = std::max(lines[end_line], count); |
| 1691 // Invocation counts for non-boundary lines are overwritten. |
| 1692 for (int k = start_line + 1; k < end_line; k++) lines[k] = count; |
| 1693 // Write function stats. |
| 1694 Local<String> name; |
| 1695 std::stringstream name_stream; |
| 1696 if (function_data.Name().ToLocal(&name)) { |
| 1697 name_stream << ToSTLString(name); |
| 1698 } else { |
| 1699 name_stream << "<" << start_line + 1 << "-"; |
| 1700 name_stream << function_data.Start().GetColumnNumber() << ">"; |
| 1701 } |
| 1702 sink << "FN:" << start_line + 1 << "," << name_stream.str() << std::endl; |
| 1703 sink << "FNDA:" << count << "," << name_stream.str() << std::endl; |
| 1704 } |
| 1715 // Write per-line coverage. LCOV uses 1-based line numbers. | 1705 // Write per-line coverage. LCOV uses 1-based line numbers. |
| 1716 for (size_t i = 0; i < lines.size(); i++) { | 1706 for (size_t i = 0; i < lines.size(); i++) { |
| 1717 sink << "DA:" << (i + 1) << "," << lines[i] << std::endl; | 1707 sink << "DA:" << (i + 1) << "," << lines[i] << std::endl; |
| 1718 } | 1708 } |
| 1719 sink << "end_of_record" << std::endl; | 1709 sink << "end_of_record" << std::endl; |
| 1720 } | 1710 } |
| 1721 } | 1711 } |
| 1722 | 1712 |
| 1723 void Shell::OnExit(v8::Isolate* isolate) { | 1713 void Shell::OnExit(v8::Isolate* isolate) { |
| 1724 // Dump basic block profiling data. | 1714 // Dump basic block profiling data. |
| (...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3006 } | 2996 } |
| 3007 | 2997 |
| 3008 } // namespace v8 | 2998 } // namespace v8 |
| 3009 | 2999 |
| 3010 | 3000 |
| 3011 #ifndef GOOGLE3 | 3001 #ifndef GOOGLE3 |
| 3012 int main(int argc, char* argv[]) { | 3002 int main(int argc, char* argv[]) { |
| 3013 return v8::Shell::Main(argc, argv); | 3003 return v8::Shell::Main(argc, argv); |
| 3014 } | 3004 } |
| 3015 #endif | 3005 #endif |
| OLD | NEW |