@@ -1668,6 +1668,85 @@ TEST(FunctionDetails) {
16681668 script_a->GetUnboundScript ()->GetId (), 5 , 14 );
16691669}
16701670
1671+ TEST (FunctionDetailsInlining) {
1672+ if (!CcTest::i_isolate ()->use_optimizer () || i::FLAG_always_opt) return ;
1673+ i::FLAG_allow_natives_syntax = true ;
1674+ v8::HandleScope scope (CcTest::isolate ());
1675+ v8::Local<v8::Context> env = CcTest::NewContext (PROFILER_EXTENSION);
1676+ v8::Context::Scope context_scope (env);
1677+ ProfilerHelper helper (env);
1678+
1679+ // alpha is in a_script, beta in b_script. beta is
1680+ // inlined in alpha, but it should be attributed to b_script.
1681+
1682+ v8::Local<v8::Script> script_b = CompileWithOrigin (
1683+ " function beta(k) {\n "
1684+ " let sum = 2;\n "
1685+ " for(let i = 0; i < k; i ++) {\n "
1686+ " sum += i;\n "
1687+ " sum = sum + 'a';\n "
1688+ " }\n "
1689+ " return sum;\n "
1690+ " }\n "
1691+ " \n " ,
1692+ " script_b" );
1693+
1694+ v8::Local<v8::Script> script_a = CompileWithOrigin (
1695+ " function alpha(p) {\n "
1696+ " let res = beta(p);\n "
1697+ " res = res + res;\n "
1698+ " return res;\n "
1699+ " }\n "
1700+ " let p = 2;\n "
1701+ " \n "
1702+ " \n "
1703+ " // Warm up before profiling or the inlining doesn't happen.\n "
1704+ " p = alpha(p);\n "
1705+ " p = alpha(p);\n "
1706+ " %OptimizeFunctionOnNextCall(alpha);\n "
1707+ " p = alpha(p);\n "
1708+ " \n "
1709+ " \n "
1710+ " startProfiling();\n "
1711+ " for(let i = 0; i < 10000; i++) {\n "
1712+ " p = alpha(p);\n "
1713+ " }\n "
1714+ " stopProfiling();\n "
1715+ " \n "
1716+ " \n " ,
1717+ " script_a" );
1718+
1719+ script_b->Run (env).ToLocalChecked ();
1720+ script_a->Run (env).ToLocalChecked ();
1721+
1722+ const v8::CpuProfile* profile = i::ProfilerExtension::last_profile;
1723+ const v8::CpuProfileNode* current = profile->GetTopDownRoot ();
1724+ reinterpret_cast <ProfileNode*>(const_cast <v8::CpuProfileNode*>(current))
1725+ ->Print (0 );
1726+ // The tree should look like this:
1727+ // 0 (root) 0 #1
1728+ // 5 (program) 0 #6
1729+ // 2 14 #2 script_a:1
1730+ // ;;; deopted at script_id: 14 position: 299 with reason 'Insufficient
1731+ // type feedback for call'.
1732+ // 1 alpha 14 #4 script_a:1
1733+ // 9 beta 13 #5 script_b:0
1734+ // 0 startProfiling 0 #3
1735+
1736+ const v8::CpuProfileNode* root = profile->GetTopDownRoot ();
1737+ const v8::CpuProfileNode* script = GetChild (env, root, " " );
1738+ CheckFunctionDetails (env->GetIsolate (), script, " " , " script_a" ,
1739+ script_a->GetUnboundScript ()->GetId (), 1 , 1 );
1740+ const v8::CpuProfileNode* alpha = FindChild (env, script, " alpha" );
1741+ // Return early if profiling didn't sample alpha.
1742+ if (!alpha) return ;
1743+ CheckFunctionDetails (env->GetIsolate (), alpha, " alpha" , " script_a" ,
1744+ script_a->GetUnboundScript ()->GetId (), 1 , 15 );
1745+ const v8::CpuProfileNode* beta = FindChild (env, alpha, " beta" );
1746+ if (!beta) return ;
1747+ CheckFunctionDetails (env->GetIsolate (), beta, " beta" , " script_b" ,
1748+ script_b->GetUnboundScript ()->GetId (), 0 , 0 );
1749+ }
16711750
16721751TEST (DontStopOnFinishedProfileDelete) {
16731752 v8::HandleScope scope (CcTest::isolate ());
0 commit comments