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 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 | 419 |
420 | 420 |
421 static v8::CpuProfile* RunProfiler(v8::Local<v8::Context> env, | 421 static v8::CpuProfile* RunProfiler(v8::Local<v8::Context> env, |
422 v8::Local<v8::Function> function, | 422 v8::Local<v8::Function> function, |
423 v8::Local<v8::Value> argv[], int argc, | 423 v8::Local<v8::Value> argv[], int argc, |
424 unsigned min_js_samples, | 424 unsigned min_js_samples, |
425 bool collect_samples = false) { | 425 bool collect_samples = false) { |
426 v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); | 426 v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); |
427 v8::Local<v8::String> profile_name = v8_str("my_profile"); | 427 v8::Local<v8::String> profile_name = v8_str("my_profile"); |
428 | 428 |
| 429 cpu_profiler->SetSamplingInterval(100); |
429 cpu_profiler->StartProfiling(profile_name, collect_samples); | 430 cpu_profiler->StartProfiling(profile_name, collect_samples); |
430 | 431 |
431 i::Sampler* sampler = | 432 i::Sampler* sampler = |
432 reinterpret_cast<i::Isolate*>(env->GetIsolate())->logger()->sampler(); | 433 reinterpret_cast<i::Isolate*>(env->GetIsolate())->logger()->sampler(); |
433 sampler->StartCountingSamples(); | 434 sampler->StartCountingSamples(); |
434 do { | 435 do { |
435 function->Call(env, env->Global(), argc, argv).ToLocalChecked(); | 436 function->Call(env, env->Global(), argc, argv).ToLocalChecked(); |
436 } while (sampler->js_and_external_sample_count() < min_js_samples); | 437 } while (sampler->js_and_external_sample_count() < min_js_samples); |
437 | 438 |
438 v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name); | 439 v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 static const ProfileNode* GetSimpleBranch(v8::Local<v8::Context> context, | 531 static const ProfileNode* GetSimpleBranch(v8::Local<v8::Context> context, |
531 v8::CpuProfile* profile, | 532 v8::CpuProfile* profile, |
532 const char* names[], int length) { | 533 const char* names[], int length) { |
533 const v8::CpuProfileNode* node = profile->GetTopDownRoot(); | 534 const v8::CpuProfileNode* node = profile->GetTopDownRoot(); |
534 for (int i = 0; i < length; i++) { | 535 for (int i = 0; i < length; i++) { |
535 node = GetChild(context, node, names[i]); | 536 node = GetChild(context, node, names[i]); |
536 } | 537 } |
537 return reinterpret_cast<const ProfileNode*>(node); | 538 return reinterpret_cast<const ProfileNode*>(node); |
538 } | 539 } |
539 | 540 |
| 541 static void CallCollectSample(const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 542 info.GetIsolate()->GetCpuProfiler()->CollectSample(); |
| 543 } |
540 | 544 |
541 static const char* cpu_profiler_test_source = "function loop(timeout) {\n" | 545 static const char* cpu_profiler_test_source = "function loop(timeout) {\n" |
542 " this.mmm = 0;\n" | 546 " this.mmm = 0;\n" |
543 " var start = Date.now();\n" | 547 " var start = Date.now();\n" |
544 " while (Date.now() - start < timeout) {\n" | 548 " while (Date.now() - start < timeout) {\n" |
545 " var n = 100*1000;\n" | 549 " var n = 100*1000;\n" |
546 " while(n > 1) {\n" | 550 " while(n > 1) {\n" |
547 " n--;\n" | 551 " n--;\n" |
548 " this.mmm += n * n * n;\n" | 552 " this.mmm += n * n * n;\n" |
549 " }\n" | 553 " }\n" |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 GetChild(env, nativeNode2, "foo"); | 1605 GetChild(env, nativeNode2, "foo"); |
1602 | 1606 |
1603 profile->Delete(); | 1607 profile->Delete(); |
1604 } | 1608 } |
1605 | 1609 |
1606 static const char* js_force_collect_sample_source = | 1610 static const char* js_force_collect_sample_source = |
1607 "function start() {\n" | 1611 "function start() {\n" |
1608 " CallCollectSample();\n" | 1612 " CallCollectSample();\n" |
1609 "}"; | 1613 "}"; |
1610 | 1614 |
1611 static void CallCollectSample(const v8::FunctionCallbackInfo<v8::Value>& info) { | |
1612 info.GetIsolate()->GetCpuProfiler()->CollectSample(); | |
1613 } | |
1614 | |
1615 TEST(CollectSampleAPI) { | 1615 TEST(CollectSampleAPI) { |
1616 v8::HandleScope scope(CcTest::isolate()); | 1616 v8::HandleScope scope(CcTest::isolate()); |
1617 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); | 1617 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); |
1618 v8::Context::Scope context_scope(env); | 1618 v8::Context::Scope context_scope(env); |
1619 | 1619 |
1620 v8::Local<v8::FunctionTemplate> func_template = | 1620 v8::Local<v8::FunctionTemplate> func_template = |
1621 v8::FunctionTemplate::New(env->GetIsolate(), CallCollectSample); | 1621 v8::FunctionTemplate::New(env->GetIsolate(), CallCollectSample); |
1622 v8::Local<v8::Function> func = | 1622 v8::Local<v8::Function> func = |
1623 func_template->GetFunction(env).ToLocalChecked(); | 1623 func_template->GetFunction(env).ToLocalChecked(); |
1624 func->SetName(v8_str("CallCollectSample")); | 1624 func->SetName(v8_str("CallCollectSample")); |
1625 env->Global()->Set(env, v8_str("CallCollectSample"), func).FromJust(); | 1625 env->Global()->Set(env, v8_str("CallCollectSample"), func).FromJust(); |
1626 | 1626 |
1627 CompileRun(js_force_collect_sample_source); | 1627 CompileRun(js_force_collect_sample_source); |
1628 v8::Local<v8::Function> function = GetFunction(env, "start"); | 1628 v8::Local<v8::Function> function = GetFunction(env, "start"); |
1629 | 1629 |
1630 v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0); | 1630 v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0); |
1631 | 1631 |
1632 const v8::CpuProfileNode* root = profile->GetTopDownRoot(); | 1632 const v8::CpuProfileNode* root = profile->GetTopDownRoot(); |
1633 const v8::CpuProfileNode* startNode = GetChild(env, root, "start"); | 1633 const v8::CpuProfileNode* startNode = GetChild(env, root, "start"); |
1634 CHECK_LE(1, startNode->GetChildrenCount()); | 1634 CHECK_LE(1, startNode->GetChildrenCount()); |
1635 GetChild(env, startNode, "CallCollectSample"); | 1635 GetChild(env, startNode, "CallCollectSample"); |
1636 | 1636 |
1637 profile->Delete(); | 1637 profile->Delete(); |
1638 } | 1638 } |
1639 | 1639 |
| 1640 static const char* js_native_js_runtime_multiple_test_source = |
| 1641 "function foo() {\n" |
| 1642 " CallCollectSample();" |
| 1643 " return Math.sin(Math.random());\n" |
| 1644 "}\n" |
| 1645 "var bound = foo.bind(this);\n" |
| 1646 "function bar() {\n" |
| 1647 " try { return bound(); } catch(e) {}\n" |
| 1648 "}\n" |
| 1649 "function start() {\n" |
| 1650 " try {\n" |
| 1651 " startProfiling('my_profile');\n" |
| 1652 " var startTime = Date.now();\n" |
| 1653 " do {\n" |
| 1654 " CallJsFunction(bar);\n" |
| 1655 " } while (Date.now() - startTime < 200);\n" |
| 1656 " } catch(e) {}\n" |
| 1657 "}"; |
| 1658 |
| 1659 // The test check multiple entrances/exits between JS and native code. |
| 1660 // |
| 1661 // [Top down]: |
| 1662 // (root) #0 1 |
| 1663 // start #16 3 |
| 1664 // CallJsFunction #0 4 |
| 1665 // bar #16 5 |
| 1666 // foo #16 6 |
| 1667 // CallCollectSample |
| 1668 // (program) #0 2 |
| 1669 TEST(JsNativeJsRuntimeJsSampleMultiple) { |
| 1670 v8::HandleScope scope(CcTest::isolate()); |
| 1671 v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); |
| 1672 v8::Context::Scope context_scope(env); |
| 1673 |
| 1674 v8::Local<v8::FunctionTemplate> func_template = |
| 1675 v8::FunctionTemplate::New(env->GetIsolate(), CallJsFunction); |
| 1676 v8::Local<v8::Function> func = |
| 1677 func_template->GetFunction(env).ToLocalChecked(); |
| 1678 func->SetName(v8_str("CallJsFunction")); |
| 1679 env->Global()->Set(env, v8_str("CallJsFunction"), func).FromJust(); |
| 1680 |
| 1681 func_template = |
| 1682 v8::FunctionTemplate::New(env->GetIsolate(), CallCollectSample); |
| 1683 func = func_template->GetFunction(env).ToLocalChecked(); |
| 1684 func->SetName(v8_str("CallCollectSample")); |
| 1685 env->Global()->Set(env, v8_str("CallCollectSample"), func).FromJust(); |
| 1686 |
| 1687 CompileRun(js_native_js_runtime_multiple_test_source); |
| 1688 v8::Local<v8::Function> function = GetFunction(env, "start"); |
| 1689 |
| 1690 v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 1000); |
| 1691 |
| 1692 const v8::CpuProfileNode* root = profile->GetTopDownRoot(); |
| 1693 const v8::CpuProfileNode* startNode = GetChild(env, root, "start"); |
| 1694 const v8::CpuProfileNode* nativeFunctionNode = |
| 1695 GetChild(env, startNode, "CallJsFunction"); |
| 1696 |
| 1697 const v8::CpuProfileNode* barNode = GetChild(env, nativeFunctionNode, "bar"); |
| 1698 const v8::CpuProfileNode* fooNode = GetChild(env, barNode, "foo"); |
| 1699 GetChild(env, fooNode, "CallCollectSample"); |
| 1700 |
| 1701 profile->Delete(); |
| 1702 } |
| 1703 |
1640 // [Top down]: | 1704 // [Top down]: |
1641 // 0 (root) #0 1 | 1705 // 0 (root) #0 1 |
1642 // 2 (program) #0 2 | 1706 // 2 (program) #0 2 |
1643 // 3 (idle) #0 3 | 1707 // 3 (idle) #0 3 |
1644 TEST(IdleTime) { | 1708 TEST(IdleTime) { |
1645 LocalContext env; | 1709 LocalContext env; |
1646 v8::HandleScope scope(env->GetIsolate()); | 1710 v8::HandleScope scope(env->GetIsolate()); |
1647 v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); | 1711 v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); |
1648 | 1712 |
1649 v8::Local<v8::String> profile_name = v8_str("my_profile"); | 1713 v8::Local<v8::String> profile_name = v8_str("my_profile"); |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2100 iprofile->Print(); | 2164 iprofile->Print(); |
2101 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); | 2165 v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); |
2102 | 2166 |
2103 const char* branch[] = {"", "test"}; | 2167 const char* branch[] = {"", "test"}; |
2104 const ProfileNode* itest_node = | 2168 const ProfileNode* itest_node = |
2105 GetSimpleBranch(env, profile, branch, arraysize(branch)); | 2169 GetSimpleBranch(env, profile, branch, arraysize(branch)); |
2106 CHECK_EQ(0U, itest_node->deopt_infos().size()); | 2170 CHECK_EQ(0U, itest_node->deopt_infos().size()); |
2107 | 2171 |
2108 iprofiler->DeleteProfile(iprofile); | 2172 iprofiler->DeleteProfile(iprofile); |
2109 } | 2173 } |
OLD | NEW |