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 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1842 | 1842 |
1843 Local<Object> dispatch_counters = reinterpret_cast<i::Isolate*>(isolate) | 1843 Local<Object> dispatch_counters = reinterpret_cast<i::Isolate*>(isolate) |
1844 ->interpreter() | 1844 ->interpreter() |
1845 ->GetDispatchCountersObject(); | 1845 ->GetDispatchCountersObject(); |
1846 std::ofstream dispatch_counters_stream( | 1846 std::ofstream dispatch_counters_stream( |
1847 i::FLAG_trace_ignition_dispatches_output_file); | 1847 i::FLAG_trace_ignition_dispatches_output_file); |
1848 dispatch_counters_stream << *String::Utf8Value( | 1848 dispatch_counters_stream << *String::Utf8Value( |
1849 JSON::Stringify(context, dispatch_counters).ToLocalChecked()); | 1849 JSON::Stringify(context, dispatch_counters).ToLocalChecked()); |
1850 } | 1850 } |
1851 | 1851 |
| 1852 namespace { |
| 1853 int LineFromOffset(Local<debug::Script> script, int offset) { |
| 1854 debug::Location location = script->GetSourceLocation(offset); |
| 1855 return location.GetLineNumber(); |
| 1856 } |
| 1857 |
| 1858 void WriteLcovDataForRange(std::vector<uint32_t>& lines, int start_line, |
| 1859 int end_line, uint32_t count) { |
| 1860 // Ensure space in the array. |
| 1861 lines.resize(std::max(static_cast<size_t>(end_line + 1), lines.size()), 0); |
| 1862 // Boundary lines could be shared between two functions with different |
| 1863 // invocation counts. Take the maximum. |
| 1864 lines[start_line] = std::max(lines[start_line], count); |
| 1865 lines[end_line] = std::max(lines[end_line], count); |
| 1866 // Invocation counts for non-boundary lines are overwritten. |
| 1867 for (int k = start_line + 1; k < end_line; k++) lines[k] = count; |
| 1868 } |
| 1869 |
| 1870 void WriteLcovDataForNamedRange(std::ostream& sink, |
| 1871 std::vector<uint32_t>& lines, std::string name, |
| 1872 int start_line, int end_line, uint32_t count) { |
| 1873 WriteLcovDataForRange(lines, start_line, end_line, count); |
| 1874 sink << "FN:" << start_line + 1 << "," << name << std::endl; |
| 1875 sink << "FNDA:" << count << "," << name << std::endl; |
| 1876 } |
| 1877 } // namespace |
| 1878 |
1852 // Write coverage data in LCOV format. See man page for geninfo(1). | 1879 // Write coverage data in LCOV format. See man page for geninfo(1). |
1853 void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) { | 1880 void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) { |
1854 if (!file) return; | 1881 if (!file) return; |
1855 HandleScope handle_scope(isolate); | 1882 HandleScope handle_scope(isolate); |
1856 debug::Coverage coverage = debug::Coverage::CollectPrecise(isolate); | 1883 debug::Coverage coverage = debug::Coverage::CollectPrecise(isolate); |
1857 std::ofstream sink(file, std::ofstream::app); | 1884 std::ofstream sink(file, std::ofstream::app); |
1858 for (size_t i = 0; i < coverage.ScriptCount(); i++) { | 1885 for (size_t i = 0; i < coverage.ScriptCount(); i++) { |
1859 debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); | 1886 debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); |
1860 Local<debug::Script> script = script_data.GetScript(); | 1887 Local<debug::Script> script = script_data.GetScript(); |
1861 // Skip unnamed scripts. | 1888 // Skip unnamed scripts. |
1862 Local<String> name; | 1889 Local<String> name; |
1863 if (!script->Name().ToLocal(&name)) continue; | 1890 if (!script->Name().ToLocal(&name)) continue; |
1864 std::string file_name = ToSTLString(name); | 1891 std::string file_name = ToSTLString(name); |
1865 // Skip scripts not backed by a file. | 1892 // Skip scripts not backed by a file. |
1866 if (!std::ifstream(file_name).good()) continue; | 1893 if (!std::ifstream(file_name).good()) continue; |
1867 sink << "SF:"; | 1894 sink << "SF:"; |
1868 sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl; | 1895 sink << NormalizePath(file_name, GetWorkingDirectory()) << std::endl; |
1869 std::vector<uint32_t> lines; | 1896 std::vector<uint32_t> lines; |
1870 for (size_t j = 0; j < script_data.FunctionCount(); j++) { | 1897 for (size_t j = 0; j < script_data.FunctionCount(); j++) { |
1871 debug::Coverage::FunctionData function_data = | 1898 debug::Coverage::FunctionData function_data = |
1872 script_data.GetFunctionData(j); | 1899 script_data.GetFunctionData(j); |
1873 debug::Location start = | 1900 |
1874 script->GetSourceLocation(function_data.StartOffset()); | |
1875 debug::Location end = | |
1876 script->GetSourceLocation(function_data.EndOffset()); | |
1877 int start_line = start.GetLineNumber(); | |
1878 int end_line = end.GetLineNumber(); | |
1879 uint32_t count = function_data.Count(); | |
1880 // Ensure space in the array. | |
1881 lines.resize(std::max(static_cast<size_t>(end_line + 1), lines.size()), | |
1882 0); | |
1883 // Boundary lines could be shared between two functions with different | |
1884 // invocation counts. Take the maximum. | |
1885 lines[start_line] = std::max(lines[start_line], count); | |
1886 lines[end_line] = std::max(lines[end_line], count); | |
1887 // Invocation counts for non-boundary lines are overwritten. | |
1888 for (int k = start_line + 1; k < end_line; k++) lines[k] = count; | |
1889 // Write function stats. | 1901 // Write function stats. |
1890 Local<String> name; | 1902 { |
1891 std::stringstream name_stream; | 1903 debug::Location start = |
1892 if (function_data.Name().ToLocal(&name)) { | 1904 script->GetSourceLocation(function_data.StartOffset()); |
1893 name_stream << ToSTLString(name); | 1905 debug::Location end = |
1894 } else { | 1906 script->GetSourceLocation(function_data.EndOffset()); |
1895 name_stream << "<" << start_line + 1 << "-"; | 1907 int start_line = start.GetLineNumber(); |
1896 name_stream << start.GetColumnNumber() << ">"; | 1908 int end_line = end.GetLineNumber(); |
| 1909 uint32_t count = function_data.Count(); |
| 1910 |
| 1911 Local<String> name; |
| 1912 std::stringstream name_stream; |
| 1913 if (function_data.Name().ToLocal(&name)) { |
| 1914 name_stream << ToSTLString(name); |
| 1915 } else { |
| 1916 name_stream << "<" << start_line + 1 << "-"; |
| 1917 name_stream << start.GetColumnNumber() << ">"; |
| 1918 } |
| 1919 |
| 1920 WriteLcovDataForNamedRange(sink, lines, name_stream.str(), start_line, |
| 1921 end_line, count); |
1897 } | 1922 } |
1898 sink << "FN:" << start_line + 1 << "," << name_stream.str() << std::endl; | 1923 |
1899 sink << "FNDA:" << count << "," << name_stream.str() << std::endl; | 1924 // Process inner blocks. |
| 1925 for (size_t k = 0; k < function_data.BlockCount(); k++) { |
| 1926 debug::Coverage::BlockData block_data = function_data.GetBlockData(k); |
| 1927 int start_line = LineFromOffset(script, block_data.StartOffset()); |
| 1928 int end_line = LineFromOffset(script, block_data.EndOffset()); |
| 1929 uint32_t count = block_data.Count(); |
| 1930 WriteLcovDataForRange(lines, start_line, end_line, count); |
| 1931 } |
1900 } | 1932 } |
1901 // Write per-line coverage. LCOV uses 1-based line numbers. | 1933 // Write per-line coverage. LCOV uses 1-based line numbers. |
1902 for (size_t i = 0; i < lines.size(); i++) { | 1934 for (size_t i = 0; i < lines.size(); i++) { |
1903 sink << "DA:" << (i + 1) << "," << lines[i] << std::endl; | 1935 sink << "DA:" << (i + 1) << "," << lines[i] << std::endl; |
1904 } | 1936 } |
1905 sink << "end_of_record" << std::endl; | 1937 sink << "end_of_record" << std::endl; |
1906 } | 1938 } |
1907 } | 1939 } |
1908 | 1940 |
1909 void Shell::OnExit(v8::Isolate* isolate) { | 1941 void Shell::OnExit(v8::Isolate* isolate) { |
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2699 } | 2731 } |
2700 | 2732 |
2701 | 2733 |
2702 int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) { | 2734 int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) { |
2703 for (int i = 1; i < options.num_isolates; ++i) { | 2735 for (int i = 1; i < options.num_isolates; ++i) { |
2704 options.isolate_sources[i].StartExecuteInThread(); | 2736 options.isolate_sources[i].StartExecuteInThread(); |
2705 } | 2737 } |
2706 { | 2738 { |
2707 EnsureEventLoopInitialized(isolate); | 2739 EnsureEventLoopInitialized(isolate); |
2708 if (options.lcov_file) { | 2740 if (options.lcov_file) { |
2709 debug::Coverage::SelectMode(isolate, debug::Coverage::kPreciseCount); | 2741 debug::Coverage::Mode mode = i::FLAG_block_coverage |
| 2742 ? debug::Coverage::kBlockCount |
| 2743 : debug::Coverage::kPreciseCount; |
| 2744 debug::Coverage::SelectMode(isolate, mode); |
2710 } | 2745 } |
2711 HandleScope scope(isolate); | 2746 HandleScope scope(isolate); |
2712 Local<Context> context = CreateEvaluationContext(isolate); | 2747 Local<Context> context = CreateEvaluationContext(isolate); |
2713 bool use_existing_context = last_run && options.use_interactive_shell(); | 2748 bool use_existing_context = last_run && options.use_interactive_shell(); |
2714 if (use_existing_context) { | 2749 if (use_existing_context) { |
2715 // Keep using the same context in the interactive shell. | 2750 // Keep using the same context in the interactive shell. |
2716 evaluation_context_.Reset(isolate, context); | 2751 evaluation_context_.Reset(isolate, context); |
2717 } | 2752 } |
2718 { | 2753 { |
2719 Context::Scope cscope(context); | 2754 Context::Scope cscope(context); |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3197 } | 3232 } |
3198 | 3233 |
3199 } // namespace v8 | 3234 } // namespace v8 |
3200 | 3235 |
3201 | 3236 |
3202 #ifndef GOOGLE3 | 3237 #ifndef GOOGLE3 |
3203 int main(int argc, char* argv[]) { | 3238 int main(int argc, char* argv[]) { |
3204 return v8::Shell::Main(argc, argv); | 3239 return v8::Shell::Main(argc, argv); |
3205 } | 3240 } |
3206 #endif | 3241 #endif |
OLD | NEW |