OLD | NEW |
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 return v8::Local<v8::Function>::Cast( | 59 return v8::Local<v8::Function>::Cast( |
60 env->Global()->Get(env, v8_str(name)).ToLocalChecked()); | 60 env->Global()->Get(env, v8_str(name)).ToLocalChecked()); |
61 } | 61 } |
62 | 62 |
63 static size_t offset(const char* src, const char* substring) { | 63 static size_t offset(const char* src, const char* substring) { |
64 const char* it = strstr(src, substring); | 64 const char* it = strstr(src, substring); |
65 CHECK(it); | 65 CHECK(it); |
66 return static_cast<size_t>(it - src); | 66 return static_cast<size_t>(it - src); |
67 } | 67 } |
68 | 68 |
69 template <typename A, typename B> | |
70 static int dist(A a, B b) { | |
71 return abs(static_cast<int>(a) - static_cast<int>(b)); | |
72 } | |
73 | |
74 static const char* reason(const i::DeoptimizeReason reason) { | 69 static const char* reason(const i::DeoptimizeReason reason) { |
75 return i::DeoptimizeReasonToString(reason); | 70 return i::DeoptimizeReasonToString(reason); |
76 } | 71 } |
77 | 72 |
78 TEST(StartStop) { | 73 TEST(StartStop) { |
79 i::Isolate* isolate = CcTest::i_isolate(); | 74 i::Isolate* isolate = CcTest::i_isolate(); |
80 CpuProfilesCollection profiles(isolate); | 75 CpuProfilesCollection profiles(isolate); |
81 ProfileGenerator generator(isolate, &profiles); | 76 ProfileGenerator generator(isolate, &profiles); |
82 std::unique_ptr<ProfilerEventsProcessor> processor( | 77 std::unique_ptr<ProfilerEventsProcessor> processor( |
83 new ProfilerEventsProcessor(isolate, &generator, | 78 new ProfilerEventsProcessor(isolate, &generator, |
(...skipping 1820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1904 "}\n" | 1899 "}\n" |
1905 "CompareStatementWithThis();\n"; | 1900 "CompareStatementWithThis();\n"; |
1906 | 1901 |
1907 v8::Script::Compile(env.local(), v8_str(source)) | 1902 v8::Script::Compile(env.local(), v8_str(source)) |
1908 .ToLocalChecked() | 1903 .ToLocalChecked() |
1909 ->Run(env.local()) | 1904 ->Run(env.local()) |
1910 .ToLocalChecked(); | 1905 .ToLocalChecked(); |
1911 } | 1906 } |
1912 | 1907 |
1913 static const char* inlined_source = | 1908 static const char* inlined_source = |
1914 "function opt_function(left, right) { var k = left*right; return k + 1; " | 1909 "function opt_function(f) { return f()*f(); }\n"; |
1915 "}\n"; | |
1916 // 0.........1.........2.........3.........4....*....5.........6......*..7 | 1910 // 0.........1.........2.........3.........4....*....5.........6......*..7 |
1917 | 1911 |
1918 | 1912 |
1919 // deopt at the first level inlined function | 1913 // deopt at the first level inlined function |
1920 TEST(DeoptAtFirstLevelInlinedSource) { | 1914 TEST(DeoptAtFirstLevelInlinedSource) { |
1921 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 1915 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
1922 i::FLAG_allow_natives_syntax = true; | 1916 i::FLAG_allow_natives_syntax = true; |
1923 v8::HandleScope scope(CcTest::isolate()); | 1917 v8::HandleScope scope(CcTest::isolate()); |
1924 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); | 1918 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); |
1925 v8::Context::Scope context_scope(env); | 1919 v8::Context::Scope context_scope(env); |
1926 ProfilerHelper helper(env); | 1920 ProfilerHelper helper(env); |
1927 i::CpuProfiler* iprofiler = | 1921 i::CpuProfiler* iprofiler = |
1928 reinterpret_cast<i::CpuProfiler*>(helper.profiler()); | 1922 reinterpret_cast<i::CpuProfiler*>(helper.profiler()); |
1929 | 1923 |
1930 // 0.........1.........2.........3.........4.........5.........6.........7 | 1924 // 0.........1.........2.........3.........4.........5.........6.........7 |
1931 const char* source = | 1925 const char* source = |
1932 "function test(left, right) { return opt_function(left, right); }\n" | 1926 "function test(f) { return opt_function(f); }\n" |
1933 "\n" | 1927 "\n" |
1934 "startProfiling();\n" | 1928 "startProfiling();\n" |
1935 "\n" | 1929 "\n" |
1936 "test(10, 10);\n" | 1930 "test(function(){return 10});test(function(){return 12});\n" |
1937 "\n" | 1931 "\n" |
| 1932 "%SetForceInlineFlag(opt_function);\n" |
1938 "%OptimizeFunctionOnNextCall(test)\n" | 1933 "%OptimizeFunctionOnNextCall(test)\n" |
1939 "\n" | 1934 "\n" |
1940 "test(10, 10);\n" | 1935 "test(function(){return 100000000000});\n" |
1941 "\n" | |
1942 "test(undefined, 1e9);\n" | |
1943 "\n" | 1936 "\n" |
1944 "stopProfiling();\n" | 1937 "stopProfiling();\n" |
1945 "\n"; | 1938 "\n"; |
1946 | 1939 |
1947 v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); | 1940 v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); |
1948 inlined_script->Run(env).ToLocalChecked(); | 1941 inlined_script->Run(env).ToLocalChecked(); |
1949 int inlined_script_id = inlined_script->GetUnboundScript()->GetId(); | 1942 int inlined_script_id = inlined_script->GetUnboundScript()->GetId(); |
1950 | 1943 |
1951 v8::Local<v8::Script> script = v8_compile(source); | 1944 v8::Local<v8::Script> script = v8_compile(source); |
1952 script->Run(env).ToLocalChecked(); | 1945 script->Run(env).ToLocalChecked(); |
(...skipping 14 matching lines...) Expand all Loading... |
1967 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); | 1960 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); |
1968 | 1961 |
1969 const char* branch[] = {"", "test"}; | 1962 const char* branch[] = {"", "test"}; |
1970 const ProfileNode* itest_node = | 1963 const ProfileNode* itest_node = |
1971 GetSimpleBranch(env, profile, branch, arraysize(branch)); | 1964 GetSimpleBranch(env, profile, branch, arraysize(branch)); |
1972 const std::vector<v8::CpuProfileDeoptInfo>& deopt_infos = | 1965 const std::vector<v8::CpuProfileDeoptInfo>& deopt_infos = |
1973 itest_node->deopt_infos(); | 1966 itest_node->deopt_infos(); |
1974 CHECK_EQ(1U, deopt_infos.size()); | 1967 CHECK_EQ(1U, deopt_infos.size()); |
1975 | 1968 |
1976 const v8::CpuProfileDeoptInfo& info = deopt_infos[0]; | 1969 const v8::CpuProfileDeoptInfo& info = deopt_infos[0]; |
1977 CHECK(reason(i::DeoptimizeReason::kNotASmi) == info.deopt_reason || | 1970 CHECK_EQ(reason(i::DeoptimizeReason::kNotASmi), info.deopt_reason); |
1978 reason(i::DeoptimizeReason::kNotAHeapNumber) == info.deopt_reason); | |
1979 CHECK_EQ(2U, info.stack.size()); | 1971 CHECK_EQ(2U, info.stack.size()); |
1980 CHECK_EQ(inlined_script_id, info.stack[0].script_id); | 1972 CHECK_EQ(inlined_script_id, info.stack[0].script_id); |
1981 CHECK_LE(dist(offset(inlined_source, "*right"), info.stack[0].position), 1); | 1973 CHECK(abs(static_cast<int>(offset(inlined_source, "*f()")) - |
| 1974 static_cast<int>(info.stack[0].position)) <= 1); |
1982 CHECK_EQ(script_id, info.stack[1].script_id); | 1975 CHECK_EQ(script_id, info.stack[1].script_id); |
1983 CHECK_EQ(offset(source, "opt_function(left,"), info.stack[1].position); | 1976 CHECK_EQ(offset(source, "opt_function(f)"), info.stack[1].position); |
1984 | 1977 |
1985 iprofiler->DeleteProfile(iprofile); | 1978 iprofiler->DeleteProfile(iprofile); |
1986 } | 1979 } |
1987 | 1980 |
1988 | 1981 |
1989 // deopt at the second level inlined function | 1982 // deopt at the second level inlined function |
1990 TEST(DeoptAtSecondLevelInlinedSource) { | 1983 TEST(DeoptAtSecondLevelInlinedSource) { |
1991 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 1984 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
1992 i::FLAG_allow_natives_syntax = true; | 1985 i::FLAG_allow_natives_syntax = true; |
1993 v8::HandleScope scope(CcTest::isolate()); | 1986 v8::HandleScope scope(CcTest::isolate()); |
1994 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); | 1987 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); |
1995 v8::Context::Scope context_scope(env); | 1988 v8::Context::Scope context_scope(env); |
1996 ProfilerHelper helper(env); | 1989 ProfilerHelper helper(env); |
1997 i::CpuProfiler* iprofiler = | 1990 i::CpuProfiler* iprofiler = |
1998 reinterpret_cast<i::CpuProfiler*>(helper.profiler()); | 1991 reinterpret_cast<i::CpuProfiler*>(helper.profiler()); |
1999 | 1992 |
2000 // 0.........1.........2.........3.........4.........5.........6.........7 | 1993 // 0.........1.........2.........3.........4.........5.........6.........7 |
2001 const char* source = | 1994 const char* source = |
2002 "function test2(left, right) { return opt_function(left, right); }\n" | 1995 "function test2(f) { return opt_function(f); }\n" |
2003 "function test1(left, right) { return test2(left, right); } \n" | 1996 "function test1(f) { return test2(f); }\n" |
2004 "\n" | 1997 "\n" |
2005 "startProfiling();\n" | 1998 "startProfiling();\n" |
2006 "\n" | 1999 "\n" |
2007 "test1(10, 10);\n" | 2000 "test1(function(){return 10});\n" |
| 2001 "test1(function(){return 11});\n" |
2008 "\n" | 2002 "\n" |
| 2003 "%SetForceInlineFlag(test2);\n" |
| 2004 "%SetForceInlineFlag(opt_function);\n" |
2009 "%OptimizeFunctionOnNextCall(test1)\n" | 2005 "%OptimizeFunctionOnNextCall(test1)\n" |
2010 "\n" | 2006 "\n" |
2011 "test1(10, 10);\n" | 2007 "test1(function(){return 12});\n" |
2012 "\n" | 2008 "\n" |
2013 "test1(undefined, 1e9);\n" | 2009 "test1(function(){return 100000000000});\n" |
2014 "\n" | 2010 "\n" |
2015 "stopProfiling();\n" | 2011 "stopProfiling();\n" |
2016 "\n"; | 2012 "\n"; |
2017 | 2013 |
2018 v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); | 2014 v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); |
2019 inlined_script->Run(env).ToLocalChecked(); | 2015 inlined_script->Run(env).ToLocalChecked(); |
2020 int inlined_script_id = inlined_script->GetUnboundScript()->GetId(); | 2016 int inlined_script_id = inlined_script->GetUnboundScript()->GetId(); |
2021 | 2017 |
2022 v8::Local<v8::Script> script = v8_compile(source); | 2018 v8::Local<v8::Script> script = v8_compile(source); |
2023 script->Run(env).ToLocalChecked(); | 2019 script->Run(env).ToLocalChecked(); |
(...skipping 17 matching lines...) Expand all Loading... |
2041 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); | 2037 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); |
2042 | 2038 |
2043 const char* branch[] = {"", "test1"}; | 2039 const char* branch[] = {"", "test1"}; |
2044 const ProfileNode* itest_node = | 2040 const ProfileNode* itest_node = |
2045 GetSimpleBranch(env, profile, branch, arraysize(branch)); | 2041 GetSimpleBranch(env, profile, branch, arraysize(branch)); |
2046 const std::vector<v8::CpuProfileDeoptInfo>& deopt_infos = | 2042 const std::vector<v8::CpuProfileDeoptInfo>& deopt_infos = |
2047 itest_node->deopt_infos(); | 2043 itest_node->deopt_infos(); |
2048 CHECK_EQ(1U, deopt_infos.size()); | 2044 CHECK_EQ(1U, deopt_infos.size()); |
2049 | 2045 |
2050 const v8::CpuProfileDeoptInfo info = deopt_infos[0]; | 2046 const v8::CpuProfileDeoptInfo info = deopt_infos[0]; |
2051 CHECK(reason(i::DeoptimizeReason::kNotASmi) == info.deopt_reason || | 2047 CHECK_EQ(reason(i::DeoptimizeReason::kNotASmi), info.deopt_reason); |
2052 reason(i::DeoptimizeReason::kNotAHeapNumber) == info.deopt_reason); | |
2053 CHECK_EQ(3U, info.stack.size()); | 2048 CHECK_EQ(3U, info.stack.size()); |
2054 CHECK_EQ(inlined_script_id, info.stack[0].script_id); | 2049 CHECK_EQ(inlined_script_id, info.stack[0].script_id); |
2055 CHECK_LE(dist(offset(inlined_source, "*right"), info.stack[0].position), 1); | 2050 CHECK(abs(static_cast<int>(offset(inlined_source, "*f()")) - |
| 2051 static_cast<int>(info.stack[0].position)) <= 1); |
2056 CHECK_EQ(script_id, info.stack[1].script_id); | 2052 CHECK_EQ(script_id, info.stack[1].script_id); |
2057 CHECK_EQ(offset(source, "opt_function(left,"), info.stack[1].position); | 2053 CHECK_EQ(offset(source, "opt_function(f)"), info.stack[1].position); |
2058 CHECK_EQ(offset(source, "test2(left, right);"), info.stack[2].position); | 2054 CHECK_EQ(offset(source, "test2(f);"), info.stack[2].position); |
2059 | 2055 |
2060 iprofiler->DeleteProfile(iprofile); | 2056 iprofiler->DeleteProfile(iprofile); |
2061 } | 2057 } |
2062 | 2058 |
2063 | 2059 |
2064 // deopt in untracked function | 2060 // deopt in untracked function |
2065 TEST(DeoptUntrackedFunction) { | 2061 TEST(DeoptUntrackedFunction) { |
2066 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2062 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
2067 i::FLAG_allow_natives_syntax = true; | 2063 i::FLAG_allow_natives_syntax = true; |
2068 v8::HandleScope scope(CcTest::isolate()); | 2064 v8::HandleScope scope(CcTest::isolate()); |
2069 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); | 2065 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); |
2070 v8::Context::Scope context_scope(env); | 2066 v8::Context::Scope context_scope(env); |
2071 ProfilerHelper helper(env); | 2067 ProfilerHelper helper(env); |
2072 i::CpuProfiler* iprofiler = | 2068 i::CpuProfiler* iprofiler = |
2073 reinterpret_cast<i::CpuProfiler*>(helper.profiler()); | 2069 reinterpret_cast<i::CpuProfiler*>(helper.profiler()); |
2074 | 2070 |
2075 // 0.........1.........2.........3.........4.........5.........6.........7 | 2071 // 0.........1.........2.........3.........4.........5.........6.........7 |
2076 const char* source = | 2072 const char* source = |
2077 "function test(left, right) { return opt_function(left, right); }\n" | 2073 "function test(left, right) { return opt_function(left, right); }\n" |
2078 "\n" | 2074 "\n" |
2079 "test(10, 10);\n" | 2075 "test(function(){return 10});\n" |
| 2076 "test(function(){return 11});\n" |
2080 "\n" | 2077 "\n" |
| 2078 "%SetForceInlineFlag(opt_function);\n" |
2081 "%OptimizeFunctionOnNextCall(test)\n" | 2079 "%OptimizeFunctionOnNextCall(test)\n" |
2082 "\n" | 2080 "\n" |
2083 "test(10, 10);\n" | 2081 "test(function(){return 10});\n" |
2084 "\n" | 2082 "\n" |
2085 "startProfiling();\n" // profiler started after compilation. | 2083 "startProfiling();\n" // profiler started after compilation. |
2086 "\n" | 2084 "\n" |
2087 "test(undefined, 10);\n" | 2085 "test(function(){return 100000000000});\n" |
2088 "\n" | 2086 "\n" |
2089 "stopProfiling();\n" | 2087 "stopProfiling();\n" |
2090 "\n"; | 2088 "\n"; |
2091 | 2089 |
2092 v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); | 2090 v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); |
2093 inlined_script->Run(env).ToLocalChecked(); | 2091 inlined_script->Run(env).ToLocalChecked(); |
2094 | 2092 |
2095 v8::Local<v8::Script> script = v8_compile(source); | 2093 v8::Local<v8::Script> script = v8_compile(source); |
2096 script->Run(env).ToLocalChecked(); | 2094 script->Run(env).ToLocalChecked(); |
2097 | 2095 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2175 printf("Profile JSON: %s\n", profile_json.c_str()); | 2173 printf("Profile JSON: %s\n", profile_json.c_str()); |
2176 std::string code = profile_checker + profile_json + ")"; | 2174 std::string code = profile_checker + profile_json + ")"; |
2177 v8::Local<v8::Value> result = | 2175 v8::Local<v8::Value> result = |
2178 CompileRunChecked(CcTest::isolate(), code.c_str()); | 2176 CompileRunChecked(CcTest::isolate(), code.c_str()); |
2179 v8::String::Utf8Value value(result); | 2177 v8::String::Utf8Value value(result); |
2180 printf("Check result: %*s\n", value.length(), *value); | 2178 printf("Check result: %*s\n", value.length(), *value); |
2181 CHECK_EQ(0, value.length()); | 2179 CHECK_EQ(0, value.length()); |
2182 | 2180 |
2183 i::V8::SetPlatformForTesting(old_platform); | 2181 i::V8::SetPlatformForTesting(old_platform); |
2184 } | 2182 } |
OLD | NEW |