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 1801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1812 | 1812 |
1813 Local<Object> dispatch_counters = reinterpret_cast<i::Isolate*>(isolate) | 1813 Local<Object> dispatch_counters = reinterpret_cast<i::Isolate*>(isolate) |
1814 ->interpreter() | 1814 ->interpreter() |
1815 ->GetDispatchCountersObject(); | 1815 ->GetDispatchCountersObject(); |
1816 std::ofstream dispatch_counters_stream( | 1816 std::ofstream dispatch_counters_stream( |
1817 i::FLAG_trace_ignition_dispatches_output_file); | 1817 i::FLAG_trace_ignition_dispatches_output_file); |
1818 dispatch_counters_stream << *String::Utf8Value( | 1818 dispatch_counters_stream << *String::Utf8Value( |
1819 JSON::Stringify(context, dispatch_counters).ToLocalChecked()); | 1819 JSON::Stringify(context, dispatch_counters).ToLocalChecked()); |
1820 } | 1820 } |
1821 | 1821 |
| 1822 namespace { |
| 1823 int LineFromOffset(Local<debug::Script> script, int offset) { |
| 1824 debug::Location location = script->GetSourceLocation(offset); |
| 1825 return location.GetLineNumber(); |
| 1826 } |
| 1827 |
| 1828 void WriteLcovDataForRange(std::vector<uint32_t>& lines, int start_line, |
| 1829 int end_line, uint32_t count) { |
| 1830 // Ensure space in the array. |
| 1831 lines.resize(std::max(static_cast<size_t>(end_line + 1), lines.size()), 0); |
| 1832 // Boundary lines could be shared between two functions with different |
| 1833 // invocation counts. Take the maximum. |
| 1834 lines[start_line] = std::max(lines[start_line], count); |
| 1835 lines[end_line] = std::max(lines[end_line], count); |
| 1836 // Invocation counts for non-boundary lines are overwritten. |
| 1837 for (int k = start_line + 1; k < end_line; k++) lines[k] = count; |
| 1838 } |
| 1839 |
| 1840 void WriteLcovDataForNamedRange(std::ostream& sink, |
| 1841 std::vector<uint32_t>& lines, std::string name, |
| 1842 int start_line, int end_line, uint32_t count) { |
| 1843 WriteLcovDataForRange(lines, start_line, end_line, count); |
| 1844 sink << "FN:" << start_line + 1 << "," << name << std::endl; |
| 1845 sink << "FNDA:" << count << "," << name << std::endl; |
| 1846 } |
| 1847 } // namespace |
| 1848 |
1822 // Write coverage data in LCOV format. See man page for geninfo(1). | 1849 // Write coverage data in LCOV format. See man page for geninfo(1). |
1823 void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) { | 1850 void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) { |
1824 if (!file) return; | 1851 if (!file) return; |
1825 HandleScope handle_scope(isolate); | 1852 HandleScope handle_scope(isolate); |
1826 debug::Coverage coverage = debug::Coverage::CollectPrecise(isolate); | 1853 debug::Coverage coverage = debug::Coverage::CollectPrecise(isolate); |
1827 std::ofstream sink(file, std::ofstream::app); | 1854 std::ofstream sink(file, std::ofstream::app); |
1828 for (size_t i = 0; i < coverage.ScriptCount(); i++) { | 1855 for (size_t i = 0; i < coverage.ScriptCount(); i++) { |
1829 debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); | 1856 debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); |
1830 Local<debug::Script> script = script_data.GetScript(); | 1857 Local<debug::Script> script = script_data.GetScript(); |
1831 // Skip unnamed scripts. | 1858 // Skip unnamed scripts. |
1832 Local<String> name; | 1859 Local<String> name; |
1833 if (!script->Name().ToLocal(&name)) continue; | 1860 if (!script->Name().ToLocal(&name)) continue; |
1834 std::string file_name = ToSTLString(name); | 1861 std::string file_name = ToSTLString(name); |
1835 // Skip scripts not backed by a file. | 1862 // Skip scripts not backed by a file. |
1836 if (!std::ifstream(file_name).good()) continue; | 1863 if (!std::ifstream(file_name).good()) continue; |
1837 sink << "SF:"; | 1864 sink << "SF:"; |
1838 sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl; | 1865 sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl; |
1839 std::vector<uint32_t> lines; | 1866 std::vector<uint32_t> lines; |
1840 for (size_t j = 0; j < script_data.FunctionCount(); j++) { | 1867 for (size_t j = 0; j < script_data.FunctionCount(); j++) { |
1841 debug::Coverage::FunctionData function_data = | 1868 debug::Coverage::FunctionData function_data = |
1842 script_data.GetFunctionData(j); | 1869 script_data.GetFunctionData(j); |
1843 debug::Location start = | 1870 |
1844 script->GetSourceLocation(function_data.StartOffset()); | |
1845 debug::Location end = | |
1846 script->GetSourceLocation(function_data.EndOffset()); | |
1847 int start_line = start.GetLineNumber(); | |
1848 int end_line = end.GetLineNumber(); | |
1849 uint32_t count = function_data.Count(); | |
1850 // Ensure space in the array. | |
1851 lines.resize(std::max(static_cast<size_t>(end_line + 1), lines.size()), | |
1852 0); | |
1853 // Boundary lines could be shared between two functions with different | |
1854 // invocation counts. Take the maximum. | |
1855 lines[start_line] = std::max(lines[start_line], count); | |
1856 lines[end_line] = std::max(lines[end_line], count); | |
1857 // Invocation counts for non-boundary lines are overwritten. | |
1858 for (int k = start_line + 1; k < end_line; k++) lines[k] = count; | |
1859 // Write function stats. | 1871 // Write function stats. |
1860 Local<String> name; | 1872 { |
1861 std::stringstream name_stream; | 1873 debug::Location start = |
1862 if (function_data.Name().ToLocal(&name)) { | 1874 script->GetSourceLocation(function_data.StartOffset()); |
1863 name_stream << ToSTLString(name); | 1875 debug::Location end = |
1864 } else { | 1876 script->GetSourceLocation(function_data.EndOffset()); |
1865 name_stream << "<" << start_line + 1 << "-"; | 1877 int start_line = start.GetLineNumber(); |
1866 name_stream << start.GetColumnNumber() << ">"; | 1878 int end_line = end.GetLineNumber(); |
| 1879 uint32_t count = function_data.Count(); |
| 1880 |
| 1881 Local<String> name; |
| 1882 std::stringstream name_stream; |
| 1883 if (function_data.Name().ToLocal(&name)) { |
| 1884 name_stream << ToSTLString(name); |
| 1885 } else { |
| 1886 name_stream << "<" << start_line + 1 << "-"; |
| 1887 name_stream << start.GetColumnNumber() << ">"; |
| 1888 } |
| 1889 |
| 1890 WriteLcovDataForNamedRange(sink, lines, name_stream.str(), start_line, |
| 1891 end_line, count); |
1867 } | 1892 } |
1868 sink << "FN:" << start_line + 1 << "," << name_stream.str() << std::endl; | 1893 |
1869 sink << "FNDA:" << count << "," << name_stream.str() << std::endl; | 1894 // Process inner blocks. |
| 1895 for (size_t k = 0; k < function_data.BlockCount(); k++) { |
| 1896 debug::Coverage::BlockData block_data = function_data.GetBlockData(k); |
| 1897 int start_line = LineFromOffset(script, block_data.StartOffset()); |
| 1898 int end_line = LineFromOffset(script, block_data.EndOffset()); |
| 1899 uint32_t count = block_data.Count(); |
| 1900 WriteLcovDataForRange(lines, start_line, end_line, count); |
| 1901 } |
1870 } | 1902 } |
1871 // Write per-line coverage. LCOV uses 1-based line numbers. | 1903 // Write per-line coverage. LCOV uses 1-based line numbers. |
1872 for (size_t i = 0; i < lines.size(); i++) { | 1904 for (size_t i = 0; i < lines.size(); i++) { |
1873 sink << "DA:" << (i + 1) << "," << lines[i] << std::endl; | 1905 sink << "DA:" << (i + 1) << "," << lines[i] << std::endl; |
1874 } | 1906 } |
1875 sink << "end_of_record" << std::endl; | 1907 sink << "end_of_record" << std::endl; |
1876 } | 1908 } |
1877 } | 1909 } |
1878 | 1910 |
1879 void Shell::OnExit(v8::Isolate* isolate) { | 1911 void Shell::OnExit(v8::Isolate* isolate) { |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2668 } | 2700 } |
2669 | 2701 |
2670 | 2702 |
2671 int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) { | 2703 int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) { |
2672 for (int i = 1; i < options.num_isolates; ++i) { | 2704 for (int i = 1; i < options.num_isolates; ++i) { |
2673 options.isolate_sources[i].StartExecuteInThread(); | 2705 options.isolate_sources[i].StartExecuteInThread(); |
2674 } | 2706 } |
2675 { | 2707 { |
2676 EnsureEventLoopInitialized(isolate); | 2708 EnsureEventLoopInitialized(isolate); |
2677 if (options.lcov_file) { | 2709 if (options.lcov_file) { |
2678 debug::Coverage::SelectMode(isolate, debug::Coverage::kPreciseCount); | 2710 debug::Coverage::Mode mode = i::FLAG_block_coverage |
| 2711 ? debug::Coverage::kBlockBinary |
| 2712 : debug::Coverage::kPreciseCount; |
| 2713 debug::Coverage::SelectMode(isolate, mode); |
2679 } | 2714 } |
2680 HandleScope scope(isolate); | 2715 HandleScope scope(isolate); |
2681 Local<Context> context = CreateEvaluationContext(isolate); | 2716 Local<Context> context = CreateEvaluationContext(isolate); |
2682 bool use_existing_context = last_run && options.use_interactive_shell(); | 2717 bool use_existing_context = last_run && options.use_interactive_shell(); |
2683 if (use_existing_context) { | 2718 if (use_existing_context) { |
2684 // Keep using the same context in the interactive shell. | 2719 // Keep using the same context in the interactive shell. |
2685 evaluation_context_.Reset(isolate, context); | 2720 evaluation_context_.Reset(isolate, context); |
2686 } | 2721 } |
2687 { | 2722 { |
2688 Context::Scope cscope(context); | 2723 Context::Scope cscope(context); |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3173 } | 3208 } |
3174 | 3209 |
3175 } // namespace v8 | 3210 } // namespace v8 |
3176 | 3211 |
3177 | 3212 |
3178 #ifndef GOOGLE3 | 3213 #ifndef GOOGLE3 |
3179 int main(int argc, char* argv[]) { | 3214 int main(int argc, char* argv[]) { |
3180 return v8::Shell::Main(argc, argv); | 3215 return v8::Shell::Main(argc, argv); |
3181 } | 3216 } |
3182 #endif | 3217 #endif |
OLD | NEW |