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

Side by Side Diff: test/cctest/test-profile-generator.cc

Issue 12475016: Maintain API compatibility with older versions of V8. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-heap-profiler.cc ('k') | test/cctest/test-thread-termination.cc » ('j') | 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 } 78 }
79 CHECK(!i::TokenEnumeratorTester::token_removed(&te)->at(2)); 79 CHECK(!i::TokenEnumeratorTester::token_removed(&te)->at(2));
80 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 80 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
81 CHECK(i::TokenEnumeratorTester::token_removed(&te)->at(2)); 81 CHECK(i::TokenEnumeratorTester::token_removed(&te)->at(2));
82 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2))); 82 CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
83 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1))); 83 CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
84 } 84 }
85 85
86 86
87 TEST(ProfileNodeFindOrAddChild) { 87 TEST(ProfileNodeFindOrAddChild) {
88 ProfileTree tree; 88 ProfileNode node(NULL, NULL);
89 ProfileNode node(&tree, NULL);
90 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0, 89 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
91 TokenEnumerator::kNoSecurityToken); 90 TokenEnumerator::kNoSecurityToken);
92 ProfileNode* childNode1 = node.FindOrAddChild(&entry1); 91 ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
93 CHECK_NE(NULL, childNode1); 92 CHECK_NE(NULL, childNode1);
94 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 93 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
95 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0, 94 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
96 TokenEnumerator::kNoSecurityToken); 95 TokenEnumerator::kNoSecurityToken);
97 ProfileNode* childNode2 = node.FindOrAddChild(&entry2); 96 ProfileNode* childNode2 = node.FindOrAddChild(&entry2);
98 CHECK_NE(NULL, childNode2); 97 CHECK_NE(NULL, childNode2);
99 CHECK_NE(childNode1, childNode2); 98 CHECK_NE(childNode1, childNode2);
100 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 99 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
101 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); 100 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
102 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0, 101 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
103 TokenEnumerator::kNoSecurityToken); 102 TokenEnumerator::kNoSecurityToken);
104 ProfileNode* childNode3 = node.FindOrAddChild(&entry3); 103 ProfileNode* childNode3 = node.FindOrAddChild(&entry3);
105 CHECK_NE(NULL, childNode3); 104 CHECK_NE(NULL, childNode3);
106 CHECK_NE(childNode1, childNode3); 105 CHECK_NE(childNode1, childNode3);
107 CHECK_NE(childNode2, childNode3); 106 CHECK_NE(childNode2, childNode3);
108 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 107 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
109 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); 108 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
110 CHECK_EQ(childNode3, node.FindOrAddChild(&entry3)); 109 CHECK_EQ(childNode3, node.FindOrAddChild(&entry3));
111 } 110 }
112 111
113 112
114 TEST(ProfileNodeFindOrAddChildForSameFunction) { 113 TEST(ProfileNodeFindOrAddChildForSameFunction) {
115 const char* empty = ""; 114 const char* empty = "";
116 const char* aaa = "aaa"; 115 const char* aaa = "aaa";
117 ProfileTree tree; 116 ProfileNode node(NULL, NULL);
118 ProfileNode node(&tree, NULL);
119 CodeEntry entry1(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0, 117 CodeEntry entry1(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
120 TokenEnumerator::kNoSecurityToken); 118 TokenEnumerator::kNoSecurityToken);
121 ProfileNode* childNode1 = node.FindOrAddChild(&entry1); 119 ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
122 CHECK_NE(NULL, childNode1); 120 CHECK_NE(NULL, childNode1);
123 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 121 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
124 // The same function again. 122 // The same function again.
125 CodeEntry entry2(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0, 123 CodeEntry entry2(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
126 TokenEnumerator::kNoSecurityToken); 124 TokenEnumerator::kNoSecurityToken);
127 CHECK_EQ(childNode1, node.FindOrAddChild(&entry2)); 125 CHECK_EQ(childNode1, node.FindOrAddChild(&entry2));
128 // Now with a different security token. 126 // Now with a different security token.
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 600
603 private: 601 private:
604 bool old_flag_prof_browser_mode_; 602 bool old_flag_prof_browser_mode_;
605 }; 603 };
606 604
607 } // namespace 605 } // namespace
608 606
609 TEST(RecordTickSample) { 607 TEST(RecordTickSample) {
610 TestSetup test_setup; 608 TestSetup test_setup;
611 CpuProfilesCollection profiles; 609 CpuProfilesCollection profiles;
612 profiles.StartProfiling("", 1, false); 610 profiles.StartProfiling("", 1);
613 ProfileGenerator generator(&profiles); 611 ProfileGenerator generator(&profiles);
614 CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); 612 CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
615 CodeEntry* entry2 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb"); 613 CodeEntry* entry2 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb");
616 CodeEntry* entry3 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc"); 614 CodeEntry* entry3 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc");
617 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200); 615 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
618 generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100); 616 generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
619 generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50); 617 generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50);
620 618
621 // We are building the following calls tree: 619 // We are building the following calls tree:
622 // -> aaa - sample1 620 // -> aaa - sample1
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 calc3.UpdateMeasurements(time); 706 calc3.UpdateMeasurements(time);
709 // (1.0 + 0.5) / 2 707 // (1.0 + 0.5) / 2
710 CHECK_EQ(kSamplingIntervalMs * 0.75, calc3.ticks_per_ms()); 708 CHECK_EQ(kSamplingIntervalMs * 0.75, calc3.ticks_per_ms());
711 time += SampleRateCalculator::kWallTimeQueryIntervalMs * 1.5; 709 time += SampleRateCalculator::kWallTimeQueryIntervalMs * 1.5;
712 calc3.UpdateMeasurements(time); 710 calc3.UpdateMeasurements(time);
713 // (1.0 + 0.5 + 0.5) / 3 711 // (1.0 + 0.5 + 0.5) / 3
714 CHECK_EQ(kSamplingIntervalMs * 2.0, floor(calc3.ticks_per_ms() * 3.0 + 0.5)); 712 CHECK_EQ(kSamplingIntervalMs * 2.0, floor(calc3.ticks_per_ms() * 3.0 + 0.5));
715 } 713 }
716 714
717 715
718 static void CheckNodeIds(ProfileNode* node, int* expectedId) {
719 CHECK_EQ((*expectedId)++, node->id());
720 for (int i = 0; i < node->children()->length(); i++) {
721 CheckNodeIds(node->children()->at(i), expectedId);
722 }
723 }
724
725 TEST(SampleIds) {
726 TestSetup test_setup;
727 CpuProfilesCollection profiles;
728 profiles.StartProfiling("", 1, true);
729 ProfileGenerator generator(&profiles);
730 CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
731 CodeEntry* entry2 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb");
732 CodeEntry* entry3 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc");
733 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
734 generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
735 generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50);
736
737 // We are building the following calls tree:
738 // -> aaa #3 - sample1
739 // (root)#1 -> aaa #2 -> bbb #4 -> ccc #5 - sample2
740 // -> ccc #6 -> aaa #7 - sample3
741 TickSample sample1;
742 sample1.pc = ToAddress(0x1600);
743 sample1.stack[0] = ToAddress(0x1510);
744 sample1.frames_count = 1;
745 generator.RecordTickSample(sample1);
746 TickSample sample2;
747 sample2.pc = ToAddress(0x1925);
748 sample2.stack[0] = ToAddress(0x1780);
749 sample2.stack[1] = ToAddress(0x10000); // non-existent.
750 sample2.stack[2] = ToAddress(0x1620);
751 sample2.frames_count = 3;
752 generator.RecordTickSample(sample2);
753 TickSample sample3;
754 sample3.pc = ToAddress(0x1510);
755 sample3.stack[0] = ToAddress(0x1910);
756 sample3.stack[1] = ToAddress(0x1610);
757 sample3.frames_count = 2;
758 generator.RecordTickSample(sample3);
759
760 CpuProfile* profile =
761 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
762 int nodeId = 1;
763 CheckNodeIds(profile->top_down()->root(), &nodeId);
764 CHECK_EQ(7, nodeId - 1);
765
766 CHECK_EQ(3, profile->samples_count());
767 int expected_id[] = {3, 5, 7};
768 for (int i = 0; i < 3; i++) {
769 CHECK_EQ(expected_id[i], profile->sample(i)->id());
770 }
771 }
772
773
774 TEST(NoSamples) {
775 TestSetup test_setup;
776 CpuProfilesCollection profiles;
777 profiles.StartProfiling("", 1, false);
778 ProfileGenerator generator(&profiles);
779 CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
780 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
781
782 // We are building the following calls tree:
783 // (root)#1 -> aaa #2 -> aaa #3 - sample1
784 TickSample sample1;
785 sample1.pc = ToAddress(0x1600);
786 sample1.stack[0] = ToAddress(0x1510);
787 sample1.frames_count = 1;
788 generator.RecordTickSample(sample1);
789
790 CpuProfile* profile =
791 profiles.StopProfiling(TokenEnumerator::kNoSecurityToken, "", 1);
792 int nodeId = 1;
793 CheckNodeIds(profile->top_down()->root(), &nodeId);
794 CHECK_EQ(3, nodeId - 1);
795
796 CHECK_EQ(0, profile->samples_count());
797 }
798
799
800 // --- P r o f i l e r E x t e n s i o n --- 716 // --- P r o f i l e r E x t e n s i o n ---
801 717
802 class ProfilerExtension : public v8::Extension { 718 class ProfilerExtension : public v8::Extension {
803 public: 719 public:
804 ProfilerExtension() : v8::Extension("v8/profiler", kSource) { } 720 ProfilerExtension() : v8::Extension("v8/profiler", kSource) { }
805 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( 721 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
806 v8::Handle<v8::String> name); 722 v8::Handle<v8::String> name);
807 static v8::Handle<v8::Value> StartProfiling(const v8::Arguments& args); 723 static v8::Handle<v8::Value> StartProfiling(const v8::Arguments& args);
808 static v8::Handle<v8::Value> StopProfiling(const v8::Arguments& args); 724 static v8::Handle<v8::Value> StopProfiling(const v8::Arguments& args);
809 private: 725 private:
(...skipping 13 matching lines...) Expand all
823 return v8::FunctionTemplate::New(ProfilerExtension::StopProfiling); 739 return v8::FunctionTemplate::New(ProfilerExtension::StopProfiling);
824 } else { 740 } else {
825 CHECK(false); 741 CHECK(false);
826 return v8::Handle<v8::FunctionTemplate>(); 742 return v8::Handle<v8::FunctionTemplate>();
827 } 743 }
828 } 744 }
829 745
830 746
831 v8::Handle<v8::Value> ProfilerExtension::StartProfiling( 747 v8::Handle<v8::Value> ProfilerExtension::StartProfiling(
832 const v8::Arguments& args) { 748 const v8::Arguments& args) {
833 v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler();
834 if (args.Length() > 0) 749 if (args.Length() > 0)
835 cpu_profiler->StartCpuProfiling(args[0].As<v8::String>()); 750 v8::CpuProfiler::StartProfiling(args[0].As<v8::String>());
836 else 751 else
837 cpu_profiler->StartCpuProfiling(v8::String::New("")); 752 v8::CpuProfiler::StartProfiling(v8::String::New(""));
838 return v8::Undefined(); 753 return v8::Undefined();
839 } 754 }
840 755
841 756
842 v8::Handle<v8::Value> ProfilerExtension::StopProfiling( 757 v8::Handle<v8::Value> ProfilerExtension::StopProfiling(
843 const v8::Arguments& args) { 758 const v8::Arguments& args) {
844 v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler();
845 if (args.Length() > 0) 759 if (args.Length() > 0)
846 cpu_profiler->StopCpuProfiling(args[0].As<v8::String>()); 760 v8::CpuProfiler::StopProfiling(args[0].As<v8::String>());
847 else 761 else
848 cpu_profiler->StopCpuProfiling(v8::String::New("")); 762 v8::CpuProfiler::StopProfiling(v8::String::New(""));
849 return v8::Undefined(); 763 return v8::Undefined();
850 } 764 }
851 765
852 766
853 static ProfilerExtension kProfilerExtension; 767 static ProfilerExtension kProfilerExtension;
854 v8::DeclareExtension kProfilerExtensionDeclaration(&kProfilerExtension); 768 v8::DeclareExtension kProfilerExtensionDeclaration(&kProfilerExtension);
855 static v8::Persistent<v8::Context> env; 769 static v8::Persistent<v8::Context> env;
856 770
857 static const ProfileNode* PickChild(const ProfileNode* parent, 771 static const ProfileNode* PickChild(const ProfileNode* parent,
858 const char* name) { 772 const char* name) {
(...skipping 12 matching lines...) Expand all
871 785
872 if (env.IsEmpty()) { 786 if (env.IsEmpty()) {
873 v8::HandleScope scope(v8::Isolate::GetCurrent()); 787 v8::HandleScope scope(v8::Isolate::GetCurrent());
874 const char* extensions[] = { "v8/profiler" }; 788 const char* extensions[] = { "v8/profiler" };
875 v8::ExtensionConfiguration config(1, extensions); 789 v8::ExtensionConfiguration config(1, extensions);
876 env = v8::Context::New(&config); 790 env = v8::Context::New(&config);
877 } 791 }
878 v8::HandleScope scope(v8::Isolate::GetCurrent()); 792 v8::HandleScope scope(v8::Isolate::GetCurrent());
879 env->Enter(); 793 env->Enter();
880 794
881 CpuProfiler* profiler = i::Isolate::Current()->cpu_profiler(); 795 CHECK_EQ(0, CpuProfiler::GetProfilesCount());
882 CHECK_EQ(0, profiler->GetProfilesCount());
883 CompileRun( 796 CompileRun(
884 "function c() { startProfiling(); }\n" 797 "function c() { startProfiling(); }\n"
885 "function b() { c(); }\n" 798 "function b() { c(); }\n"
886 "function a() { b(); }\n" 799 "function a() { b(); }\n"
887 "a();\n" 800 "a();\n"
888 "stopProfiling();"); 801 "stopProfiling();");
889 CHECK_EQ(1, profiler->GetProfilesCount()); 802 CHECK_EQ(1, CpuProfiler::GetProfilesCount());
890 CpuProfile* profile = profiler->GetProfile(NULL, 0); 803 CpuProfile* profile =
804 CpuProfiler::GetProfile(NULL, 0);
891 const ProfileTree* topDown = profile->top_down(); 805 const ProfileTree* topDown = profile->top_down();
892 const ProfileNode* current = topDown->root(); 806 const ProfileNode* current = topDown->root();
893 const_cast<ProfileNode*>(current)->Print(0); 807 const_cast<ProfileNode*>(current)->Print(0);
894 // The tree should look like this: 808 // The tree should look like this:
895 // (root) 809 // (root)
896 // (anonymous function) 810 // (anonymous function)
897 // a 811 // a
898 // b 812 // b
899 // c 813 // c
900 // There can also be: 814 // There can also be:
(...skipping 16 matching lines...) Expand all
917 } 831 }
918 832
919 833
920 TEST(Issue51919) { 834 TEST(Issue51919) {
921 CpuProfilesCollection collection; 835 CpuProfilesCollection collection;
922 i::EmbeddedVector<char*, 836 i::EmbeddedVector<char*,
923 CpuProfilesCollection::kMaxSimultaneousProfiles> titles; 837 CpuProfilesCollection::kMaxSimultaneousProfiles> titles;
924 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) { 838 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) {
925 i::Vector<char> title = i::Vector<char>::New(16); 839 i::Vector<char> title = i::Vector<char>::New(16);
926 i::OS::SNPrintF(title, "%d", i); 840 i::OS::SNPrintF(title, "%d", i);
927 // UID must be > 0. 841 CHECK(collection.StartProfiling(title.start(), i + 1)); // UID must be > 0.
928 CHECK(collection.StartProfiling(title.start(), i + 1, false));
929 titles[i] = title.start(); 842 titles[i] = title.start();
930 } 843 }
931 CHECK(!collection.StartProfiling( 844 CHECK(!collection.StartProfiling(
932 "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1, false)); 845 "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1));
933 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) 846 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i)
934 i::DeleteArray(titles[i]); 847 i::DeleteArray(titles[i]);
935 } 848 }
OLDNEW
« no previous file with comments | « test/cctest/test-heap-profiler.cc ('k') | test/cctest/test-thread-termination.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698