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

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

Issue 13454002: Allow recording individual samples in addition to the aggregated CPU profiles (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 years, 8 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-cpu-profiler.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 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 ProfileNode node(NULL, NULL); 88 ProfileTree tree;
89 ProfileNode node(&tree, NULL);
89 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0, 90 CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
90 TokenEnumerator::kNoSecurityToken); 91 TokenEnumerator::kNoSecurityToken);
91 ProfileNode* childNode1 = node.FindOrAddChild(&entry1); 92 ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
92 CHECK_NE(NULL, childNode1); 93 CHECK_NE(NULL, childNode1);
93 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 94 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
94 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0, 95 CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0,
95 TokenEnumerator::kNoSecurityToken); 96 TokenEnumerator::kNoSecurityToken);
96 ProfileNode* childNode2 = node.FindOrAddChild(&entry2); 97 ProfileNode* childNode2 = node.FindOrAddChild(&entry2);
97 CHECK_NE(NULL, childNode2); 98 CHECK_NE(NULL, childNode2);
98 CHECK_NE(childNode1, childNode2); 99 CHECK_NE(childNode1, childNode2);
99 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 100 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
100 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); 101 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
101 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0, 102 CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
102 TokenEnumerator::kNoSecurityToken); 103 TokenEnumerator::kNoSecurityToken);
103 ProfileNode* childNode3 = node.FindOrAddChild(&entry3); 104 ProfileNode* childNode3 = node.FindOrAddChild(&entry3);
104 CHECK_NE(NULL, childNode3); 105 CHECK_NE(NULL, childNode3);
105 CHECK_NE(childNode1, childNode3); 106 CHECK_NE(childNode1, childNode3);
106 CHECK_NE(childNode2, childNode3); 107 CHECK_NE(childNode2, childNode3);
107 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 108 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
108 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2)); 109 CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
109 CHECK_EQ(childNode3, node.FindOrAddChild(&entry3)); 110 CHECK_EQ(childNode3, node.FindOrAddChild(&entry3));
110 } 111 }
111 112
112 113
113 TEST(ProfileNodeFindOrAddChildForSameFunction) { 114 TEST(ProfileNodeFindOrAddChildForSameFunction) {
114 const char* empty = ""; 115 const char* empty = "";
115 const char* aaa = "aaa"; 116 const char* aaa = "aaa";
116 ProfileNode node(NULL, NULL); 117 ProfileTree tree;
118 ProfileNode node(&tree, NULL);
117 CodeEntry entry1(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0, 119 CodeEntry entry1(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
118 TokenEnumerator::kNoSecurityToken); 120 TokenEnumerator::kNoSecurityToken);
119 ProfileNode* childNode1 = node.FindOrAddChild(&entry1); 121 ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
120 CHECK_NE(NULL, childNode1); 122 CHECK_NE(NULL, childNode1);
121 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1)); 123 CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
122 // The same function again. 124 // The same function again.
123 CodeEntry entry2(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0, 125 CodeEntry entry2(i::Logger::FUNCTION_TAG, empty, aaa, empty, 0,
124 TokenEnumerator::kNoSecurityToken); 126 TokenEnumerator::kNoSecurityToken);
125 CHECK_EQ(childNode1, node.FindOrAddChild(&entry2)); 127 CHECK_EQ(childNode1, node.FindOrAddChild(&entry2));
126 // Now with a different security token. 128 // Now with a different security token.
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 602
601 private: 603 private:
602 bool old_flag_prof_browser_mode_; 604 bool old_flag_prof_browser_mode_;
603 }; 605 };
604 606
605 } // namespace 607 } // namespace
606 608
607 TEST(RecordTickSample) { 609 TEST(RecordTickSample) {
608 TestSetup test_setup; 610 TestSetup test_setup;
609 CpuProfilesCollection profiles; 611 CpuProfilesCollection profiles;
610 profiles.StartProfiling("", 1); 612 profiles.StartProfiling("", 1, false);
611 ProfileGenerator generator(&profiles); 613 ProfileGenerator generator(&profiles);
612 CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa"); 614 CodeEntry* entry1 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "aaa");
613 CodeEntry* entry2 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb"); 615 CodeEntry* entry2 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "bbb");
614 CodeEntry* entry3 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc"); 616 CodeEntry* entry3 = generator.NewCodeEntry(i::Logger::FUNCTION_TAG, "ccc");
615 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200); 617 generator.code_map()->AddCode(ToAddress(0x1500), entry1, 0x200);
616 generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100); 618 generator.code_map()->AddCode(ToAddress(0x1700), entry2, 0x100);
617 generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50); 619 generator.code_map()->AddCode(ToAddress(0x1900), entry3, 0x50);
618 620
619 // We are building the following calls tree: 621 // We are building the following calls tree:
620 // -> aaa - sample1 622 // -> aaa - sample1
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 calc3.UpdateMeasurements(time); 708 calc3.UpdateMeasurements(time);
707 // (1.0 + 0.5) / 2 709 // (1.0 + 0.5) / 2
708 CHECK_EQ(kSamplingIntervalMs * 0.75, calc3.ticks_per_ms()); 710 CHECK_EQ(kSamplingIntervalMs * 0.75, calc3.ticks_per_ms());
709 time += SampleRateCalculator::kWallTimeQueryIntervalMs * 1.5; 711 time += SampleRateCalculator::kWallTimeQueryIntervalMs * 1.5;
710 calc3.UpdateMeasurements(time); 712 calc3.UpdateMeasurements(time);
711 // (1.0 + 0.5 + 0.5) / 3 713 // (1.0 + 0.5 + 0.5) / 3
712 CHECK_EQ(kSamplingIntervalMs * 2.0, floor(calc3.ticks_per_ms() * 3.0 + 0.5)); 714 CHECK_EQ(kSamplingIntervalMs * 2.0, floor(calc3.ticks_per_ms() * 3.0 + 0.5));
713 } 715 }
714 716
715 717
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
716 // --- P r o f i l e r E x t e n s i o n --- 800 // --- P r o f i l e r E x t e n s i o n ---
717 801
718 class ProfilerExtension : public v8::Extension { 802 class ProfilerExtension : public v8::Extension {
719 public: 803 public:
720 ProfilerExtension() : v8::Extension("v8/profiler", kSource) { } 804 ProfilerExtension() : v8::Extension("v8/profiler", kSource) { }
721 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( 805 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
722 v8::Handle<v8::String> name); 806 v8::Handle<v8::String> name);
723 static v8::Handle<v8::Value> StartProfiling(const v8::Arguments& args); 807 static v8::Handle<v8::Value> StartProfiling(const v8::Arguments& args);
724 static v8::Handle<v8::Value> StopProfiling(const v8::Arguments& args); 808 static v8::Handle<v8::Value> StopProfiling(const v8::Arguments& args);
725 private: 809 private:
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 } 915 }
832 916
833 917
834 TEST(Issue51919) { 918 TEST(Issue51919) {
835 CpuProfilesCollection collection; 919 CpuProfilesCollection collection;
836 i::EmbeddedVector<char*, 920 i::EmbeddedVector<char*,
837 CpuProfilesCollection::kMaxSimultaneousProfiles> titles; 921 CpuProfilesCollection::kMaxSimultaneousProfiles> titles;
838 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) { 922 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) {
839 i::Vector<char> title = i::Vector<char>::New(16); 923 i::Vector<char> title = i::Vector<char>::New(16);
840 i::OS::SNPrintF(title, "%d", i); 924 i::OS::SNPrintF(title, "%d", i);
841 CHECK(collection.StartProfiling(title.start(), i + 1)); // UID must be > 0. 925 // UID must be > 0.
926 CHECK(collection.StartProfiling(title.start(), i + 1, false));
842 titles[i] = title.start(); 927 titles[i] = title.start();
843 } 928 }
844 CHECK(!collection.StartProfiling( 929 CHECK(!collection.StartProfiling(
845 "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1)); 930 "maximum", CpuProfilesCollection::kMaxSimultaneousProfiles + 1, false));
846 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i) 931 for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i)
847 i::DeleteArray(titles[i]); 932 i::DeleteArray(titles[i]);
848 } 933 }
OLDNEW
« no previous file with comments | « test/cctest/test-cpu-profiler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698