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

Side by Side Diff: test/cctest/test-cpu-profiler.cc

Issue 1013143003: CpuProfiler: push the collected information about deopts to cpu profiler (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: comments addressed Created 5 years, 9 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
« src/compiler.h ('K') | « src/profile-generator.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 using i::SmartPointer; 49 using i::SmartPointer;
50 using i::Vector; 50 using i::Vector;
51 51
52 52
53 // Helper methods 53 // Helper methods
54 static v8::Local<v8::Function> GetFunction(v8::Context* env, const char* name) { 54 static v8::Local<v8::Function> GetFunction(v8::Context* env, const char* name) {
55 return v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str(name))); 55 return v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str(name)));
56 } 56 }
57 57
58 58
59 static int offset(const char* src, const char* substring) {
60 return static_cast<int>(strstr(src, substring) - src);
61 }
62
63
59 static const char* reason(const i::Deoptimizer::DeoptReason reason) { 64 static const char* reason(const i::Deoptimizer::DeoptReason reason) {
60 return i::Deoptimizer::GetDeoptReason(reason); 65 return i::Deoptimizer::GetDeoptReason(reason);
61 } 66 }
62 67
63 68
64 TEST(StartStop) { 69 TEST(StartStop) {
65 i::Isolate* isolate = CcTest::i_isolate(); 70 i::Isolate* isolate = CcTest::i_isolate();
66 CpuProfilesCollection profiles(isolate->heap()); 71 CpuProfilesCollection profiles(isolate->heap());
67 ProfileGenerator generator(&profiles); 72 ProfileGenerator generator(&profiles);
68 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor( 73 SmartPointer<ProfilerEventsProcessor> processor(new ProfilerEventsProcessor(
(...skipping 1638 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 outer_profile = NULL; 1712 outer_profile = NULL;
1708 CHECK_EQ(0, iprofiler->GetProfilesCount()); 1713 CHECK_EQ(0, iprofiler->GetProfilesCount());
1709 } 1714 }
1710 1715
1711 1716
1712 const char* GetBranchDeoptReason(i::CpuProfile* iprofile, const char* branch[], 1717 const char* GetBranchDeoptReason(i::CpuProfile* iprofile, const char* branch[],
1713 int length) { 1718 int length) {
1714 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); 1719 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile);
1715 const ProfileNode* iopt_function = NULL; 1720 const ProfileNode* iopt_function = NULL;
1716 iopt_function = GetSimpleBranch(profile, branch, length); 1721 iopt_function = GetSimpleBranch(profile, branch, length);
1717 CHECK_EQ(1, iopt_function->deopt_infos().length()); 1722 CHECK_EQ(1, iopt_function->deopt_infos().size());
1718 return iopt_function->deopt_infos()[0].deopt_reason; 1723 return iopt_function->deopt_infos()[0].deopt_reason;
1719 } 1724 }
1720 1725
1721 1726
1722 // deopt at top function 1727 // deopt at top function
1723 TEST(CollectDeoptEvents) { 1728 TEST(CollectDeoptEvents) {
1724 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; 1729 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
1725 i::FLAG_allow_natives_syntax = true; 1730 i::FLAG_allow_natives_syntax = true;
1726 v8::HandleScope scope(CcTest::isolate()); 1731 v8::HandleScope scope(CcTest::isolate());
1727 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); 1732 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 "opt_function2(1, 1);\n" 1775 "opt_function2(1, 1);\n"
1771 "\n" 1776 "\n"
1772 "opt_function2(0, 1);\n" 1777 "opt_function2(0, 1);\n"
1773 "\n" 1778 "\n"
1774 "stopProfiling();\n" 1779 "stopProfiling();\n"
1775 "\n"; 1780 "\n";
1776 1781
1777 v8::Script::Compile(v8_str(source))->Run(); 1782 v8::Script::Compile(v8_str(source))->Run();
1778 i::CpuProfile* iprofile = iprofiler->GetProfile(0); 1783 i::CpuProfile* iprofile = iprofiler->GetProfile(0);
1779 iprofile->Print(); 1784 iprofile->Print();
1785 /* The expected profile
1786 [Top down]:
1787 0 (root) 0 #1
1788 23 32 #2
1789 1 opt_function2 31 #7
1790 1 opt_function2 31 #8
1791 ;;; deopted at script_id: 31 position: 106 with reason
1792 'division by zero'.
1793 2 opt_function0 29 #3
1794 4 opt_function0 29 #4
1795 ;;; deopted at script_id: 29 position: 108 with reason 'not a
1796 heap number'.
1797 0 opt_function1 30 #5
1798 1 opt_function1 30 #6
1799 ;;; deopted at script_id: 30 position: 108 with reason 'lost
1800 precision or NaN'.
1801 */
1802
1780 { 1803 {
1781 const char* branch[] = {"", "opt_function0", "opt_function0"}; 1804 const char* branch[] = {"", "opt_function0", "opt_function0"};
1782 CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), 1805 CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber),
1783 GetBranchDeoptReason(iprofile, branch, arraysize(branch))); 1806 GetBranchDeoptReason(iprofile, branch, arraysize(branch)));
1784 } 1807 }
1785 { 1808 {
1786 const char* branch[] = {"", "opt_function1", "opt_function1"}; 1809 const char* branch[] = {"", "opt_function1", "opt_function1"};
1787 const char* deopt_reason = 1810 const char* deopt_reason =
1788 GetBranchDeoptReason(iprofile, branch, arraysize(branch)); 1811 GetBranchDeoptReason(iprofile, branch, arraysize(branch));
1789 if (deopt_reason != reason(i::Deoptimizer::kNaN) && 1812 if (deopt_reason != reason(i::Deoptimizer::kNaN) &&
(...skipping 17 matching lines...) Expand all
1807 v8::HandleScope scope(CcTest::isolate()); 1830 v8::HandleScope scope(CcTest::isolate());
1808 1831
1809 const char* source = 1832 const char* source =
1810 "function CompareStatementWithThis() {\n" 1833 "function CompareStatementWithThis() {\n"
1811 " if (this === 1) {}\n" 1834 " if (this === 1) {}\n"
1812 "}\n" 1835 "}\n"
1813 "CompareStatementWithThis();\n"; 1836 "CompareStatementWithThis();\n";
1814 1837
1815 v8::Script::Compile(v8_str(source))->Run(); 1838 v8::Script::Compile(v8_str(source))->Run();
1816 } 1839 }
1840
1841
1842 static const char* inlined_source =
1843 "function opt_function(left, right) { var k = left / 10; var r = 10 / "
1844 "right; return k + r; }\n";
1845 // 0.........1.........2.........3.........4....*....5.........6......*..7
1846
1847
1848 // deopt at the first level inlined function
1849 TEST(DeoptAtFirstLevelInlinedSource) {
1850 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
1851 i::FLAG_allow_natives_syntax = true;
1852 v8::HandleScope scope(CcTest::isolate());
1853 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
1854 v8::Context::Scope context_scope(env);
1855 v8::Isolate* isolate = env->GetIsolate();
1856 v8::CpuProfiler* profiler = isolate->GetCpuProfiler();
1857 i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
1858
1859 // 0.........1.........2.........3.........4.........5.........6.........7
1860 const char* source =
1861 "function test(left, right) { return opt_function(left, right); }\n"
1862 "\n"
1863 "startProfiling();\n"
1864 "\n"
1865 "test(10, 10);\n"
1866 "\n"
1867 "%OptimizeFunctionOnNextCall(test)\n"
1868 "\n"
1869 "test(10, 10);\n"
1870 "\n"
1871 "test(undefined, 10);\n"
1872 "\n"
1873 "stopProfiling();\n"
1874 "\n";
1875
1876 v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source);
1877 inlined_script->Run();
1878 int inlined_script_id = inlined_script->GetUnboundScript()->GetId();
1879
1880 v8::Handle<v8::Script> script = v8_compile(source);
1881 script->Run();
1882 int script_id = script->GetUnboundScript()->GetId();
1883
1884 i::CpuProfile* iprofile = iprofiler->GetProfile(0);
1885 iprofile->Print();
1886 /* The expected profile output
1887 [Top down]:
1888 0 (root) 0 #1
1889 10 30 #2
1890 1 test 30 #3
1891 ;;; deopted at script_id: 29 position: 45 with reason 'not a
1892 heap number'.
1893 ;;; Inline point: script_id 30 position: 36.
1894 4 opt_function 29 #4
1895 */
1896 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile);
1897
1898 const char* branch[] = {"", "test"};
1899 const ProfileNode* itest_node =
1900 GetSimpleBranch(profile, branch, arraysize(branch));
1901 const std::vector<i::DeoptInfo>& deopt_infos = itest_node->deopt_infos();
1902 CHECK_EQ(1, deopt_infos.size());
1903
1904 const i::DeoptInfo& info = deopt_infos[0];
1905 CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), info.deopt_reason);
1906 CHECK_EQ(2, info.stack.size());
1907 CHECK_EQ(inlined_script_id, info.stack[0].script_id);
1908 CHECK_EQ(offset(inlined_source, "left /"), info.stack[0].position);
1909 CHECK_EQ(script_id, info.stack[1].script_id);
1910 CHECK_EQ(offset(source, "opt_function(left,"), info.stack[1].position);
1911
1912 iprofiler->DeleteProfile(iprofile);
1913 }
1914
1915
1916 // deopt at the second level inlined function
1917 TEST(DeoptAtSecondLevelInlinedSource) {
1918 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
1919 i::FLAG_allow_natives_syntax = true;
1920 v8::HandleScope scope(CcTest::isolate());
1921 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
1922 v8::Context::Scope context_scope(env);
1923 v8::Isolate* isolate = env->GetIsolate();
1924 v8::CpuProfiler* profiler = isolate->GetCpuProfiler();
1925 i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
1926
1927 // 0.........1.........2.........3.........4.........5.........6.........7
1928 const char* source =
1929 "function test2(left, right) { return opt_function(left, right); }\n"
1930 "function test1(left, right) { return test2(left, right); }\n"
1931 "\n"
1932 "startProfiling();\n"
1933 "\n"
1934 "test1(10, 10);\n"
1935 "\n"
1936 "%OptimizeFunctionOnNextCall(test1)\n"
1937 "\n"
1938 "test1(10, 10);\n"
1939 "\n"
1940 "test1(undefined, 10);\n"
1941 "\n"
1942 "stopProfiling();\n"
1943 "\n";
1944
1945 v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source);
1946 inlined_script->Run();
1947 int inlined_script_id = inlined_script->GetUnboundScript()->GetId();
1948
1949 v8::Handle<v8::Script> script = v8_compile(source);
1950 script->Run();
1951 int script_id = script->GetUnboundScript()->GetId();
1952
1953 i::CpuProfile* iprofile = iprofiler->GetProfile(0);
1954 iprofile->Print();
1955 /* The expected profile output
1956 [Top down]:
1957 0 (root) 0 #1
1958 11 30 #2
1959 1 test1 30 #3
1960 ;;; deopted at script_id: 29 position: 45 with reason 'not a
1961 heap number'.
1962 ;;; Inline point: script_id 30 position: 37.
1963 ;;; Inline point: script_id 30 position: 103.
1964 1 test2 30 #4
1965 3 opt_function 29 #5
1966 */
1967
1968 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile);
1969
1970 const char* branch[] = {"", "test1"};
1971 const ProfileNode* itest_node =
1972 GetSimpleBranch(profile, branch, arraysize(branch));
1973 const std::vector<i::DeoptInfo>& deopt_infos = itest_node->deopt_infos();
1974 CHECK_EQ(1, deopt_infos.size());
1975
1976 const i::DeoptInfo info = deopt_infos[0];
1977 CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), info.deopt_reason);
1978 CHECK_EQ(3, info.stack.size());
1979 CHECK_EQ(inlined_script_id, info.stack[0].script_id);
1980 CHECK_EQ(offset(inlined_source, "left /"), info.stack[0].position);
1981 CHECK_EQ(script_id, info.stack[1].script_id);
1982 CHECK_EQ(offset(source, "opt_function(left,"), info.stack[1].position);
1983 CHECK_EQ(offset(source, "test2(left, right);"), info.stack[2].position);
1984
1985 iprofiler->DeleteProfile(iprofile);
1986 }
1987
1988
1989 // deopt in untracked function
1990 TEST(DeoptUntrackedFunction) {
1991 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
1992 i::FLAG_allow_natives_syntax = true;
1993 v8::HandleScope scope(CcTest::isolate());
1994 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
1995 v8::Context::Scope context_scope(env);
1996 v8::Isolate* isolate = env->GetIsolate();
1997 v8::CpuProfiler* profiler = isolate->GetCpuProfiler();
1998 i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
1999
2000 // 0.........1.........2.........3.........4.........5.........6.........7
2001 const char* source =
2002 "function test(left, right) { return opt_function(left, right); }\n"
2003 "\n"
2004 "test(10, 10);\n"
2005 "\n"
2006 "%OptimizeFunctionOnNextCall(test)\n"
2007 "\n"
2008 "test(10, 10);\n"
2009 "\n"
2010 "startProfiling();\n" // profiler started after compilation.
2011 "\n"
2012 "test(undefined, 10);\n"
2013 "\n"
2014 "stopProfiling();\n"
2015 "\n";
2016
2017 v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source);
2018 inlined_script->Run();
2019
2020 v8::Handle<v8::Script> script = v8_compile(source);
2021 script->Run();
2022
2023 i::CpuProfile* iprofile = iprofiler->GetProfile(0);
2024 iprofile->Print();
2025 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile);
2026
2027 const char* branch[] = {"", "test"};
2028 const ProfileNode* itest_node =
2029 GetSimpleBranch(profile, branch, arraysize(branch));
2030 CHECK_EQ(0, itest_node->deopt_infos().size());
2031
2032 iprofiler->DeleteProfile(iprofile);
2033 }
OLDNEW
« src/compiler.h ('K') | « src/profile-generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698