OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "platform/assert.h" | 5 #include "platform/assert.h" |
6 | 6 |
7 #include "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
8 #include "vm/dart_api_state.h" | 8 #include "vm/dart_api_state.h" |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 #include "vm/profiler.h" | 10 #include "vm/profiler.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 lib.LookupClassAllowPrivate(String::Handle(Symbols::New(name)))); | 125 lib.LookupClassAllowPrivate(String::Handle(Symbols::New(name)))); |
126 EXPECT(!cls.IsNull()); // No ambiguity error expected. | 126 EXPECT(!cls.IsNull()); // No ambiguity error expected. |
127 return cls.raw(); | 127 return cls.raw(); |
128 } | 128 } |
129 | 129 |
130 | 130 |
131 class AllocationFilter : public SampleFilter { | 131 class AllocationFilter : public SampleFilter { |
132 public: | 132 public: |
133 explicit AllocationFilter(Isolate* isolate, intptr_t cid) | 133 explicit AllocationFilter(Isolate* isolate, intptr_t cid) |
134 : SampleFilter(isolate), | 134 : SampleFilter(isolate), |
135 cid_(cid) { | 135 cid_(cid), |
| 136 enable_embedder_ticks_(false) { |
136 } | 137 } |
137 | 138 |
138 bool FilterSample(Sample* sample) { | 139 bool FilterSample(Sample* sample) { |
139 return sample->is_allocation_sample() && (sample->allocation_cid() == cid_); | 140 if (!enable_embedder_ticks_ && |
| 141 (sample->vm_tag() == VMTag::kEmbedderTagId)) { |
| 142 // We don't want to see embedder ticks in the test. |
| 143 return false; |
| 144 } |
| 145 return sample->is_allocation_sample() && |
| 146 (sample->allocation_cid() == cid_); |
| 147 } |
| 148 |
| 149 void set_enable_embedder_ticks(bool enable) { |
| 150 enable_embedder_ticks_ = enable; |
140 } | 151 } |
141 | 152 |
142 private: | 153 private: |
143 intptr_t cid_; | 154 intptr_t cid_; |
| 155 bool enable_embedder_ticks_; |
144 }; | 156 }; |
145 | 157 |
146 | 158 |
147 TEST_CASE(Profiler_TrivialRecordAllocation) { | 159 TEST_CASE(Profiler_TrivialRecordAllocation) { |
148 DisableNativeProfileScope dnps; | 160 DisableNativeProfileScope dnps; |
149 const char* kScript = | 161 const char* kScript = |
150 "class A {\n" | 162 "class A {\n" |
151 " var a;\n" | 163 " var a;\n" |
152 " var b;\n" | 164 " var b;\n" |
153 "}\n" | 165 "}\n" |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 EXPECT_STREQ("_GrowableList._GrowableList", walker.CurrentName()); | 698 EXPECT_STREQ("_GrowableList._GrowableList", walker.CurrentName()); |
687 EXPECT(walker.Down()); | 699 EXPECT(walker.Down()); |
688 EXPECT_STREQ("List.List", walker.CurrentName()); | 700 EXPECT_STREQ("List.List", walker.CurrentName()); |
689 EXPECT(walker.Down()); | 701 EXPECT(walker.Down()); |
690 EXPECT_STREQ("bar", walker.CurrentName()); | 702 EXPECT_STREQ("bar", walker.CurrentName()); |
691 EXPECT(!walker.Down()); | 703 EXPECT(!walker.Down()); |
692 } | 704 } |
693 } | 705 } |
694 | 706 |
695 | 707 |
| 708 TEST_CASE(Profiler_ContextAllocation) { |
| 709 DisableNativeProfileScope dnps; |
| 710 const char* kScript = |
| 711 "var msg1 = 'a';\n" |
| 712 "foo() {\n" |
| 713 " var msg = msg1 + msg1;\n" |
| 714 " return (x) { return '$msg + $msg'; }(msg);\n" |
| 715 "}\n"; |
| 716 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| 717 EXPECT_VALID(lib); |
| 718 Library& root_library = Library::Handle(); |
| 719 root_library ^= Api::UnwrapHandle(lib); |
| 720 Isolate* isolate = Isolate::Current(); |
| 721 |
| 722 const Class& context_class = |
| 723 Class::Handle(Object::context_class()); |
| 724 EXPECT(!context_class.IsNull()); |
| 725 |
| 726 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL); |
| 727 EXPECT_VALID(result); |
| 728 |
| 729 { |
| 730 StackZone zone(isolate); |
| 731 HANDLESCOPE(isolate); |
| 732 Profile profile(isolate); |
| 733 AllocationFilter filter(isolate, context_class.id()); |
| 734 profile.Build(&filter, Profile::kNoTags); |
| 735 // We should have no allocation samples. |
| 736 EXPECT_EQ(0, profile.sample_count()); |
| 737 } |
| 738 |
| 739 context_class.SetTraceAllocation(true); |
| 740 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); |
| 741 EXPECT_VALID(result); |
| 742 |
| 743 { |
| 744 StackZone zone(isolate); |
| 745 HANDLESCOPE(isolate); |
| 746 Profile profile(isolate); |
| 747 AllocationFilter filter(isolate, context_class.id()); |
| 748 profile.Build(&filter, Profile::kNoTags); |
| 749 // We should have one allocation sample. |
| 750 EXPECT_EQ(1, profile.sample_count()); |
| 751 ProfileTrieWalker walker(&profile); |
| 752 |
| 753 walker.Reset(Profile::kExclusiveCode); |
| 754 EXPECT(walker.Down()); |
| 755 EXPECT_STREQ("foo", walker.CurrentName()); |
| 756 EXPECT(!walker.Down()); |
| 757 } |
| 758 |
| 759 context_class.SetTraceAllocation(false); |
| 760 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); |
| 761 EXPECT_VALID(result); |
| 762 |
| 763 { |
| 764 StackZone zone(isolate); |
| 765 HANDLESCOPE(isolate); |
| 766 Profile profile(isolate); |
| 767 AllocationFilter filter(isolate, context_class.id()); |
| 768 profile.Build(&filter, Profile::kNoTags); |
| 769 // We should still only have one allocation sample. |
| 770 EXPECT_EQ(1, profile.sample_count()); |
| 771 } |
| 772 } |
| 773 |
| 774 |
| 775 TEST_CASE(Profiler_ClassAllocation) { |
| 776 DisableNativeProfileScope dnps; |
| 777 const char* kScript = |
| 778 "var msg1 = 'a';\n" |
| 779 "\n" |
| 780 "foo() {\n" |
| 781 " var msg = msg1 + msg1;\n" |
| 782 " var msg2 = msg + msg;\n" |
| 783 " return (x, y, z, w) { return '$x + $y + $z'; }(msg, msg2, msg, msg);\n" |
| 784 "}\n" |
| 785 "bar() {\n" |
| 786 " var msg = msg1 + msg1;\n" |
| 787 " var msg2 = msg + msg;\n" |
| 788 " return (x, y) { return '$x + $y'; }(msg, msg2);\n" |
| 789 "}\n"; |
| 790 |
| 791 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| 792 EXPECT_VALID(lib); |
| 793 Library& root_library = Library::Handle(); |
| 794 root_library ^= Api::UnwrapHandle(lib); |
| 795 Isolate* isolate = Isolate::Current(); |
| 796 |
| 797 const Class& class_class = |
| 798 Class::Handle(Object::class_class()); |
| 799 EXPECT(!class_class.IsNull()); |
| 800 class_class.SetTraceAllocation(true); |
| 801 |
| 802 // Invoke "foo" which during compilation, triggers a closure class allocation. |
| 803 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL); |
| 804 EXPECT_VALID(result); |
| 805 |
| 806 { |
| 807 StackZone zone(isolate); |
| 808 HANDLESCOPE(isolate); |
| 809 Profile profile(isolate); |
| 810 AllocationFilter filter(isolate, class_class.id()); |
| 811 filter.set_enable_embedder_ticks(true); |
| 812 profile.Build(&filter, Profile::kNoTags); |
| 813 // We should have one allocation sample. |
| 814 EXPECT_EQ(1, profile.sample_count()); |
| 815 ProfileTrieWalker walker(&profile); |
| 816 |
| 817 walker.Reset(Profile::kExclusiveCode); |
| 818 EXPECT(walker.Down()); |
| 819 EXPECT_SUBSTRING("dart::Profiler::RecordAllocation", walker.CurrentName()); |
| 820 EXPECT(!walker.Down()); |
| 821 } |
| 822 |
| 823 // Disable allocation tracing for Class. |
| 824 class_class.SetTraceAllocation(false); |
| 825 |
| 826 // Invoke "bar" which during compilation, triggers a closure class allocation. |
| 827 result = Dart_Invoke(lib, NewString("bar"), 0, NULL); |
| 828 EXPECT_VALID(result); |
| 829 |
| 830 { |
| 831 StackZone zone(isolate); |
| 832 HANDLESCOPE(isolate); |
| 833 Profile profile(isolate); |
| 834 AllocationFilter filter(isolate, class_class.id()); |
| 835 filter.set_enable_embedder_ticks(true); |
| 836 profile.Build(&filter, Profile::kNoTags); |
| 837 // We should still only have one allocation sample. |
| 838 EXPECT_EQ(1, profile.sample_count()); |
| 839 } |
| 840 } |
| 841 |
| 842 |
696 TEST_CASE(Profiler_TypedArrayAllocation) { | 843 TEST_CASE(Profiler_TypedArrayAllocation) { |
697 DisableNativeProfileScope dnps; | 844 DisableNativeProfileScope dnps; |
698 const char* kScript = | 845 const char* kScript = |
699 "import 'dart:typed_data';\n" | 846 "import 'dart:typed_data';\n" |
700 "List foo() => new Float32List(4);\n"; | 847 "List foo() => new Float32List(4);\n"; |
701 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | 848 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
702 EXPECT_VALID(lib); | 849 EXPECT_VALID(lib); |
703 Library& root_library = Library::Handle(); | 850 Library& root_library = Library::Handle(); |
704 root_library ^= Api::UnwrapHandle(lib); | 851 root_library ^= Api::UnwrapHandle(lib); |
705 Isolate* isolate = Isolate::Current(); | 852 Isolate* isolate = Isolate::Current(); |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 EXPECT(walker.Down()); | 1328 EXPECT(walker.Down()); |
1182 EXPECT_STREQ("B.choo", walker.CurrentName()); | 1329 EXPECT_STREQ("B.choo", walker.CurrentName()); |
1183 EXPECT(walker.Down()); | 1330 EXPECT(walker.Down()); |
1184 EXPECT_STREQ("[Inline End]", walker.CurrentName()); | 1331 EXPECT_STREQ("[Inline End]", walker.CurrentName()); |
1185 EXPECT(!walker.Down()); | 1332 EXPECT(!walker.Down()); |
1186 } | 1333 } |
1187 } | 1334 } |
1188 | 1335 |
1189 } // namespace dart | 1336 } // namespace dart |
1190 | 1337 |
OLD | NEW |