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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |