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

Side by Side Diff: runtime/vm/profiler_test.cc

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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
« no previous file with comments | « runtime/vm/profiler_service.cc ('k') | runtime/vm/random.h » ('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 (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"
11 #include "vm/profiler_service.h" 11 #include "vm/profiler_service.h"
12 #include "vm/source_report.h" 12 #include "vm/source_report.h"
13 #include "vm/unit_test.h" 13 #include "vm/unit_test.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 #ifndef PRODUCT 17 #ifndef PRODUCT
18 18
19 DECLARE_FLAG(bool, profile_vm); 19 DECLARE_FLAG(bool, profile_vm);
20 DECLARE_FLAG(int, max_profile_depth); 20 DECLARE_FLAG(int, max_profile_depth);
21 DECLARE_FLAG(bool, enable_inlining_annotations); 21 DECLARE_FLAG(bool, enable_inlining_annotations);
22 DECLARE_FLAG(int, optimization_counter_threshold); 22 DECLARE_FLAG(int, optimization_counter_threshold);
23 23
24 // Some tests are written assuming native stack trace profiling is disabled. 24 // Some tests are written assuming native stack trace profiling is disabled.
25 class DisableNativeProfileScope : public ValueObject { 25 class DisableNativeProfileScope : public ValueObject {
26 public: 26 public:
27 DisableNativeProfileScope() 27 DisableNativeProfileScope() : FLAG_profile_vm_(FLAG_profile_vm) {
28 : FLAG_profile_vm_(FLAG_profile_vm) {
29 FLAG_profile_vm = false; 28 FLAG_profile_vm = false;
30 } 29 }
31 30
32 ~DisableNativeProfileScope() { 31 ~DisableNativeProfileScope() { FLAG_profile_vm = FLAG_profile_vm_; }
33 FLAG_profile_vm = FLAG_profile_vm_;
34 }
35 32
36 private: 33 private:
37 const bool FLAG_profile_vm_; 34 const bool FLAG_profile_vm_;
38 }; 35 };
39 36
40 37
41 class DisableBackgroundCompilationScope : public ValueObject { 38 class DisableBackgroundCompilationScope : public ValueObject {
42 public: 39 public:
43 DisableBackgroundCompilationScope() 40 DisableBackgroundCompilationScope()
44 : FLAG_background_compilation_(FLAG_background_compilation) { 41 : FLAG_background_compilation_(FLAG_background_compilation) {
(...skipping 10 matching lines...) Expand all
55 52
56 53
57 // Temporarily adjust the maximum profile depth. 54 // Temporarily adjust the maximum profile depth.
58 class MaxProfileDepthScope : public ValueObject { 55 class MaxProfileDepthScope : public ValueObject {
59 public: 56 public:
60 explicit MaxProfileDepthScope(intptr_t new_max_depth) 57 explicit MaxProfileDepthScope(intptr_t new_max_depth)
61 : FLAG_max_profile_depth_(FLAG_max_profile_depth) { 58 : FLAG_max_profile_depth_(FLAG_max_profile_depth) {
62 Profiler::SetSampleDepth(new_max_depth); 59 Profiler::SetSampleDepth(new_max_depth);
63 } 60 }
64 61
65 ~MaxProfileDepthScope() { 62 ~MaxProfileDepthScope() { Profiler::SetSampleDepth(FLAG_max_profile_depth_); }
66 Profiler::SetSampleDepth(FLAG_max_profile_depth_);
67 }
68 63
69 private: 64 private:
70 const intptr_t FLAG_max_profile_depth_; 65 const intptr_t FLAG_max_profile_depth_;
71 }; 66 };
72 67
73 68
74 class ProfileSampleBufferTestHelper { 69 class ProfileSampleBufferTestHelper {
75 public: 70 public:
76 static intptr_t IterateCount(const Isolate* isolate, 71 static intptr_t IterateCount(const Isolate* isolate,
77 const SampleBuffer& sample_buffer) { 72 const SampleBuffer& sample_buffer) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 Sample* sample = sample_buffer->ReserveSample(); 149 Sample* sample = sample_buffer->ReserveSample();
155 sample->Init(isolate, 0, 0); 150 sample->Init(isolate, 0, 0);
156 sample->set_metadata(99); 151 sample->set_metadata(99);
157 sample->set_is_allocation_sample(true); 152 sample->set_is_allocation_sample(true);
158 EXPECT_EQ(99, sample->allocation_cid()); 153 EXPECT_EQ(99, sample->allocation_cid());
159 delete sample_buffer; 154 delete sample_buffer;
160 } 155 }
161 156
162 157
163 static RawClass* GetClass(const Library& lib, const char* name) { 158 static RawClass* GetClass(const Library& lib, const char* name) {
164 const Class& cls = Class::Handle( 159 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(
165 lib.LookupClassAllowPrivate(String::Handle(Symbols::New(Thread::Current(), 160 String::Handle(Symbols::New(Thread::Current(), name))));
166 name))));
167 EXPECT(!cls.IsNull()); // No ambiguity error expected. 161 EXPECT(!cls.IsNull()); // No ambiguity error expected.
168 return cls.raw(); 162 return cls.raw();
169 } 163 }
170 164
171 165
172 static RawFunction* GetFunction(const Library& lib, const char* name) { 166 static RawFunction* GetFunction(const Library& lib, const char* name) {
173 const Function& func = Function::Handle(lib.LookupFunctionAllowPrivate( 167 const Function& func = Function::Handle(lib.LookupFunctionAllowPrivate(
174 String::Handle(Symbols::New(Thread::Current(), name)))); 168 String::Handle(Symbols::New(Thread::Current(), name))));
175 EXPECT(!func.IsNull()); // No ambiguity error expected. 169 EXPECT(!func.IsNull()); // No ambiguity error expected.
176 return func.raw(); 170 return func.raw();
177 } 171 }
178 172
179 173
180 class AllocationFilter : public SampleFilter { 174 class AllocationFilter : public SampleFilter {
181 public: 175 public:
182 AllocationFilter(Isolate* isolate, 176 AllocationFilter(Isolate* isolate,
183 intptr_t cid, 177 intptr_t cid,
184 int64_t time_origin_micros = -1, 178 int64_t time_origin_micros = -1,
185 int64_t time_extent_micros = -1) 179 int64_t time_extent_micros = -1)
186 : SampleFilter(isolate, 180 : SampleFilter(isolate,
187 Thread::kMutatorTask, 181 Thread::kMutatorTask,
188 time_origin_micros, 182 time_origin_micros,
189 time_extent_micros), 183 time_extent_micros),
190 cid_(cid), 184 cid_(cid),
191 enable_vm_ticks_(false) { 185 enable_vm_ticks_(false) {}
192 }
193 186
194 bool FilterSample(Sample* sample) { 187 bool FilterSample(Sample* sample) {
195 if (!enable_vm_ticks_ && 188 if (!enable_vm_ticks_ && (sample->vm_tag() == VMTag::kVMTagId)) {
196 (sample->vm_tag() == VMTag::kVMTagId)) {
197 // We don't want to see embedder ticks in the test. 189 // We don't want to see embedder ticks in the test.
198 return false; 190 return false;
199 } 191 }
200 return sample->is_allocation_sample() && 192 return sample->is_allocation_sample() && (sample->allocation_cid() == cid_);
201 (sample->allocation_cid() == cid_);
202 } 193 }
203 194
204 void set_enable_vm_ticks(bool enable) { 195 void set_enable_vm_ticks(bool enable) { enable_vm_ticks_ = enable; }
205 enable_vm_ticks_ = enable;
206 }
207 196
208 private: 197 private:
209 intptr_t cid_; 198 intptr_t cid_;
210 bool enable_vm_ticks_; 199 bool enable_vm_ticks_;
211 }; 200 };
212 201
213 202
214 TEST_CASE(Profiler_TrivialRecordAllocation) { 203 TEST_CASE(Profiler_TrivialRecordAllocation) {
215 DisableNativeProfileScope dnps; 204 DisableNativeProfileScope dnps;
216 const char* kScript = 205 const char* kScript =
(...skipping 26 matching lines...) Expand all
243 const int64_t after_allocations_micros = Dart_TimelineGetMicros(); 232 const int64_t after_allocations_micros = Dart_TimelineGetMicros();
244 const int64_t allocation_extent_micros = 233 const int64_t allocation_extent_micros =
245 after_allocations_micros - before_allocations_micros; 234 after_allocations_micros - before_allocations_micros;
246 { 235 {
247 Thread* thread = Thread::Current(); 236 Thread* thread = Thread::Current();
248 Isolate* isolate = thread->isolate(); 237 Isolate* isolate = thread->isolate();
249 StackZone zone(thread); 238 StackZone zone(thread);
250 HANDLESCOPE(thread); 239 HANDLESCOPE(thread);
251 Profile profile(isolate); 240 Profile profile(isolate);
252 // Filter for the class in the time range. 241 // Filter for the class in the time range.
253 AllocationFilter filter(isolate, 242 AllocationFilter filter(isolate, class_a.id(), before_allocations_micros,
254 class_a.id(),
255 before_allocations_micros,
256 allocation_extent_micros); 243 allocation_extent_micros);
257 profile.Build(thread, &filter, Profile::kNoTags); 244 profile.Build(thread, &filter, Profile::kNoTags);
258 // We should have 1 allocation sample. 245 // We should have 1 allocation sample.
259 EXPECT_EQ(1, profile.sample_count()); 246 EXPECT_EQ(1, profile.sample_count());
260 ProfileTrieWalker walker(&profile); 247 ProfileTrieWalker walker(&profile);
261 248
262 // Exclusive code: B.boo -> main. 249 // Exclusive code: B.boo -> main.
263 walker.Reset(Profile::kExclusiveCode); 250 walker.Reset(Profile::kExclusiveCode);
264 // Move down from the root. 251 // Move down from the root.
265 EXPECT(walker.Down()); 252 EXPECT(walker.Down());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 EXPECT(!walker.Down()); 291 EXPECT(!walker.Down());
305 } 292 }
306 293
307 // Query with a time filter where no allocations occurred. 294 // Query with a time filter where no allocations occurred.
308 { 295 {
309 Thread* thread = Thread::Current(); 296 Thread* thread = Thread::Current();
310 Isolate* isolate = thread->isolate(); 297 Isolate* isolate = thread->isolate();
311 StackZone zone(thread); 298 StackZone zone(thread);
312 HANDLESCOPE(thread); 299 HANDLESCOPE(thread);
313 Profile profile(isolate); 300 Profile profile(isolate);
314 AllocationFilter filter(isolate, 301 AllocationFilter filter(isolate, class_a.id(), Dart_TimelineGetMicros(),
315 class_a.id(),
316 Dart_TimelineGetMicros(),
317 16000); 302 16000);
318 profile.Build(thread, &filter, Profile::kNoTags); 303 profile.Build(thread, &filter, Profile::kNoTags);
319 // We should have no allocation samples because none occured within 304 // We should have no allocation samples because none occured within
320 // the specified time range. 305 // the specified time range.
321 EXPECT_EQ(0, profile.sample_count()); 306 EXPECT_EQ(0, profile.sample_count());
322 } 307 }
323 } 308 }
324 309
325 310
326 TEST_CASE(Profiler_ToggleRecordAllocation) { 311 TEST_CASE(Profiler_ToggleRecordAllocation) {
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); 635 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
651 EXPECT_VALID(lib); 636 EXPECT_VALID(lib);
652 Library& root_library = Library::Handle(); 637 Library& root_library = Library::Handle();
653 root_library ^= Api::UnwrapHandle(lib); 638 root_library ^= Api::UnwrapHandle(lib);
654 Isolate* isolate = thread->isolate(); 639 Isolate* isolate = thread->isolate();
655 640
656 const Class& double_class = 641 const Class& double_class =
657 Class::Handle(isolate->object_store()->double_class()); 642 Class::Handle(isolate->object_store()->double_class());
658 EXPECT(!double_class.IsNull()); 643 EXPECT(!double_class.IsNull());
659 644
660 Dart_Handle args[2] = { Dart_NewDouble(1.0), Dart_NewDouble(2.0), }; 645 Dart_Handle args[2] = {
646 Dart_NewDouble(1.0), Dart_NewDouble(2.0),
647 };
661 648
662 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 649 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
663 EXPECT_VALID(result); 650 EXPECT_VALID(result);
664 651
665 { 652 {
666 StackZone zone(thread); 653 StackZone zone(thread);
667 HANDLESCOPE(thread); 654 HANDLESCOPE(thread);
668 Profile profile(isolate); 655 Profile profile(isolate);
669 AllocationFilter filter(isolate, double_class.id()); 656 AllocationFilter filter(isolate, double_class.id());
670 profile.Build(thread, &filter, Profile::kNoTags); 657 profile.Build(thread, &filter, Profile::kNoTags);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 "foo() {\n" 816 "foo() {\n"
830 " var msg = msg1 + msg1;\n" 817 " var msg = msg1 + msg1;\n"
831 " return (x) { return '$msg + $msg'; }(msg);\n" 818 " return (x) { return '$msg + $msg'; }(msg);\n"
832 "}\n"; 819 "}\n";
833 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); 820 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
834 EXPECT_VALID(lib); 821 EXPECT_VALID(lib);
835 Library& root_library = Library::Handle(); 822 Library& root_library = Library::Handle();
836 root_library ^= Api::UnwrapHandle(lib); 823 root_library ^= Api::UnwrapHandle(lib);
837 Isolate* isolate = thread->isolate(); 824 Isolate* isolate = thread->isolate();
838 825
839 const Class& context_class = 826 const Class& context_class = Class::Handle(Object::context_class());
840 Class::Handle(Object::context_class());
841 EXPECT(!context_class.IsNull()); 827 EXPECT(!context_class.IsNull());
842 828
843 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 829 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
844 EXPECT_VALID(result); 830 EXPECT_VALID(result);
845 831
846 { 832 {
847 StackZone zone(thread); 833 StackZone zone(thread);
848 HANDLESCOPE(thread); 834 HANDLESCOPE(thread);
849 Profile profile(isolate); 835 Profile profile(isolate);
850 AllocationFilter filter(isolate, context_class.id()); 836 AllocationFilter filter(isolate, context_class.id());
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); 1038 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
1053 EXPECT_VALID(lib); 1039 EXPECT_VALID(lib);
1054 Library& root_library = Library::Handle(); 1040 Library& root_library = Library::Handle();
1055 root_library ^= Api::UnwrapHandle(lib); 1041 root_library ^= Api::UnwrapHandle(lib);
1056 Isolate* isolate = thread->isolate(); 1042 Isolate* isolate = thread->isolate();
1057 1043
1058 const Class& one_byte_string_class = 1044 const Class& one_byte_string_class =
1059 Class::Handle(isolate->object_store()->one_byte_string_class()); 1045 Class::Handle(isolate->object_store()->one_byte_string_class());
1060 EXPECT(!one_byte_string_class.IsNull()); 1046 EXPECT(!one_byte_string_class.IsNull());
1061 1047
1062 Dart_Handle args[2] = { NewString("a"), NewString("b"), }; 1048 Dart_Handle args[2] = {
1049 NewString("a"), NewString("b"),
1050 };
1063 1051
1064 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1052 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1065 EXPECT_VALID(result); 1053 EXPECT_VALID(result);
1066 1054
1067 { 1055 {
1068 StackZone zone(thread); 1056 StackZone zone(thread);
1069 HANDLESCOPE(thread); 1057 HANDLESCOPE(thread);
1070 Profile profile(isolate); 1058 Profile profile(isolate);
1071 AllocationFilter filter(isolate, one_byte_string_class.id()); 1059 AllocationFilter filter(isolate, one_byte_string_class.id());
1072 profile.Build(thread, &filter, Profile::kNoTags); 1060 profile.Build(thread, &filter, Profile::kNoTags);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); 1123 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
1136 EXPECT_VALID(lib); 1124 EXPECT_VALID(lib);
1137 Library& root_library = Library::Handle(); 1125 Library& root_library = Library::Handle();
1138 root_library ^= Api::UnwrapHandle(lib); 1126 root_library ^= Api::UnwrapHandle(lib);
1139 Isolate* isolate = thread->isolate(); 1127 Isolate* isolate = thread->isolate();
1140 1128
1141 const Class& one_byte_string_class = 1129 const Class& one_byte_string_class =
1142 Class::Handle(isolate->object_store()->one_byte_string_class()); 1130 Class::Handle(isolate->object_store()->one_byte_string_class());
1143 EXPECT(!one_byte_string_class.IsNull()); 1131 EXPECT(!one_byte_string_class.IsNull());
1144 1132
1145 Dart_Handle args[2] = { NewString("a"), NewString("b"), }; 1133 Dart_Handle args[2] = {
1134 NewString("a"), NewString("b"),
1135 };
1146 1136
1147 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1137 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1148 EXPECT_VALID(result); 1138 EXPECT_VALID(result);
1149 1139
1150 { 1140 {
1151 StackZone zone(thread); 1141 StackZone zone(thread);
1152 HANDLESCOPE(thread); 1142 HANDLESCOPE(thread);
1153 Profile profile(isolate); 1143 Profile profile(isolate);
1154 AllocationFilter filter(isolate, one_byte_string_class.id()); 1144 AllocationFilter filter(isolate, one_byte_string_class.id());
1155 profile.Build(thread, &filter, Profile::kNoTags); 1145 profile.Build(thread, &filter, Profile::kNoTags);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 } 1380 }
1391 1381
1392 // Test code transition tags. 1382 // Test code transition tags.
1393 { 1383 {
1394 Thread* thread = Thread::Current(); 1384 Thread* thread = Thread::Current();
1395 Isolate* isolate = thread->isolate(); 1385 Isolate* isolate = thread->isolate();
1396 StackZone zone(thread); 1386 StackZone zone(thread);
1397 HANDLESCOPE(thread); 1387 HANDLESCOPE(thread);
1398 Profile profile(isolate); 1388 Profile profile(isolate);
1399 AllocationFilter filter(isolate, class_a.id()); 1389 AllocationFilter filter(isolate, class_a.id());
1400 profile.Build(thread, 1390 profile.Build(thread, &filter, Profile::kNoTags,
1401 &filter,
1402 Profile::kNoTags,
1403 ProfilerService::kCodeTransitionTagsBit); 1391 ProfilerService::kCodeTransitionTagsBit);
1404 // We should have 50,000 allocation samples. 1392 // We should have 50,000 allocation samples.
1405 EXPECT_EQ(50000, profile.sample_count()); 1393 EXPECT_EQ(50000, profile.sample_count());
1406 ProfileTrieWalker walker(&profile); 1394 ProfileTrieWalker walker(&profile);
1407 // We have two code objects: mainA and B.boo. 1395 // We have two code objects: mainA and B.boo.
1408 walker.Reset(Profile::kExclusiveCode); 1396 walker.Reset(Profile::kExclusiveCode);
1409 EXPECT(walker.Down()); 1397 EXPECT(walker.Down());
1410 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 1398 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
1411 EXPECT(walker.Down()); 1399 EXPECT(walker.Down());
1412 EXPECT_STREQ("B.boo", walker.CurrentName()); 1400 EXPECT_STREQ("B.boo", walker.CurrentName());
(...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after
2351 EXPECT_STREQ("main", walker.CurrentName()); 2339 EXPECT_STREQ("main", walker.CurrentName());
2352 EXPECT_EQ(1, walker.CurrentNodeTickCount()); 2340 EXPECT_EQ(1, walker.CurrentNodeTickCount());
2353 EXPECT_EQ(1, walker.CurrentInclusiveTicks()); 2341 EXPECT_EQ(1, walker.CurrentInclusiveTicks());
2354 EXPECT_EQ(0, walker.CurrentExclusiveTicks()); 2342 EXPECT_EQ(0, walker.CurrentExclusiveTicks());
2355 EXPECT_STREQ("bacon", walker.CurrentToken()); 2343 EXPECT_STREQ("bacon", walker.CurrentToken());
2356 EXPECT(!walker.Down()); 2344 EXPECT(!walker.Down());
2357 } 2345 }
2358 } 2346 }
2359 2347
2360 2348
2361 static void InsertFakeSample(SampleBuffer* sample_buffer, 2349 static void InsertFakeSample(SampleBuffer* sample_buffer, uword* pc_offsets) {
2362 uword* pc_offsets) {
2363 ASSERT(sample_buffer != NULL); 2350 ASSERT(sample_buffer != NULL);
2364 Isolate* isolate = Isolate::Current(); 2351 Isolate* isolate = Isolate::Current();
2365 Sample* sample = sample_buffer->ReserveSample(); 2352 Sample* sample = sample_buffer->ReserveSample();
2366 ASSERT(sample != NULL); 2353 ASSERT(sample != NULL);
2367 sample->Init(isolate, 2354 sample->Init(isolate, OS::GetCurrentMonotonicMicros(),
2368 OS::GetCurrentMonotonicMicros(),
2369 OSThread::Current()->trace_id()); 2355 OSThread::Current()->trace_id());
2370 sample->set_thread_task(Thread::kMutatorTask); 2356 sample->set_thread_task(Thread::kMutatorTask);
2371 2357
2372 intptr_t i = 0; 2358 intptr_t i = 0;
2373 while (pc_offsets[i] != 0) { 2359 while (pc_offsets[i] != 0) {
2374 // When we collect a real stack trace, all PCs collected aside from the 2360 // When we collect a real stack trace, all PCs collected aside from the
2375 // executing one (i == 0) are actually return addresses. Return addresses 2361 // executing one (i == 0) are actually return addresses. Return addresses
2376 // are one byte beyond the call instruction that is executing. The profiler 2362 // are one byte beyond the call instruction that is executing. The profiler
2377 // accounts for this and subtracts one from these addresses when querying 2363 // accounts for this and subtracts one from these addresses when querying
2378 // inline and token position ranges. To be consistent with real stack 2364 // inline and token position ranges. To be consistent with real stack
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2466 2452
2467 const CodeSourceMap& do_work_code_source_map = 2453 const CodeSourceMap& do_work_code_source_map =
2468 CodeSourceMap::Handle(do_work_code.code_source_map()); 2454 CodeSourceMap::Handle(do_work_code.code_source_map());
2469 EXPECT(!do_work_code_source_map.IsNull()); 2455 EXPECT(!do_work_code_source_map.IsNull());
2470 2456
2471 // Dump code source map. 2457 // Dump code source map.
2472 CodeSourceMap::Dump(do_work_code_source_map, do_work_code, main); 2458 CodeSourceMap::Dump(do_work_code_source_map, do_work_code, main);
2473 CodeSourceMap::Dump(main_code_source_map, main_code, main); 2459 CodeSourceMap::Dump(main_code_source_map, main_code, main);
2474 2460
2475 // Look up some source token position's pc. 2461 // Look up some source token position's pc.
2476 uword squarePositionPc = 2462 uword squarePositionPc = FindPCForTokenPosition(
2477 FindPCForTokenPosition(do_work_code, 2463 do_work_code, do_work_code_source_map, squarePosition);
2478 do_work_code_source_map,
2479 squarePosition);
2480 EXPECT(squarePositionPc != 0); 2464 EXPECT(squarePositionPc != 0);
2481 2465
2482 uword callPositionPc = 2466 uword callPositionPc =
2483 FindPCForTokenPosition(main_code, main_code_source_map, callPosition); 2467 FindPCForTokenPosition(main_code, main_code_source_map, callPosition);
2484 EXPECT(callPositionPc != 0); 2468 EXPECT(callPositionPc != 0);
2485 2469
2486 // Look up some classifying token position's pc. 2470 // Look up some classifying token position's pc.
2487 uword controlFlowPc = 2471 uword controlFlowPc = FindPCForTokenPosition(
2488 FindPCForTokenPosition(do_work_code, 2472 do_work_code, do_work_code_source_map, TokenPosition::kControlFlow);
2489 do_work_code_source_map,
2490 TokenPosition::kControlFlow);
2491 EXPECT(controlFlowPc != 0); 2473 EXPECT(controlFlowPc != 0);
2492 2474
2493 uword tempMovePc = 2475 uword tempMovePc = FindPCForTokenPosition(main_code, main_code_source_map,
2494 FindPCForTokenPosition(main_code, 2476 TokenPosition::kTempMove);
2495 main_code_source_map,
2496 TokenPosition::kTempMove);
2497 EXPECT(tempMovePc != 0); 2477 EXPECT(tempMovePc != 0);
2498 2478
2499 // Insert fake samples. 2479 // Insert fake samples.
2500 2480
2501 // Sample 1: 2481 // Sample 1:
2502 // squarePositionPc exclusive. 2482 // squarePositionPc exclusive.
2503 // callPositionPc inclusive. 2483 // callPositionPc inclusive.
2504 uword sample1[] = { 2484 uword sample1[] = {squarePositionPc, // doWork.
2505 squarePositionPc, // doWork. 2485 callPositionPc, // main.
2506 callPositionPc, // main. 2486 0};
2507 0
2508 };
2509 2487
2510 // Sample 2: 2488 // Sample 2:
2511 // squarePositionPc exclusive. 2489 // squarePositionPc exclusive.
2512 uword sample2[] = { 2490 uword sample2[] = {
2513 squarePositionPc, // doWork. 2491 squarePositionPc, // doWork.
2514 0, 2492 0,
2515 }; 2493 };
2516 2494
2517 // Sample 3: 2495 // Sample 3:
2518 // controlFlowPc exclusive. 2496 // controlFlowPc exclusive.
2519 // callPositionPc inclusive. 2497 // callPositionPc inclusive.
2520 uword sample3[] = { 2498 uword sample3[] = {controlFlowPc, // doWork.
2521 controlFlowPc, // doWork. 2499 callPositionPc, // main.
2522 callPositionPc, // main. 2500 0};
2523 0
2524 };
2525 2501
2526 // Sample 4: 2502 // Sample 4:
2527 // tempMovePc exclusive. 2503 // tempMovePc exclusive.
2528 uword sample4[] = { 2504 uword sample4[] = {tempMovePc, // main.
2529 tempMovePc, // main. 2505 0};
2530 0
2531 };
2532 2506
2533 InsertFakeSample(sample_buffer, &sample1[0]); 2507 InsertFakeSample(sample_buffer, &sample1[0]);
2534 InsertFakeSample(sample_buffer, &sample2[0]); 2508 InsertFakeSample(sample_buffer, &sample2[0]);
2535 InsertFakeSample(sample_buffer, &sample3[0]); 2509 InsertFakeSample(sample_buffer, &sample3[0]);
2536 InsertFakeSample(sample_buffer, &sample4[0]); 2510 InsertFakeSample(sample_buffer, &sample4[0]);
2537 2511
2538 // Generate source report for main. 2512 // Generate source report for main.
2539 SourceReport sourceReport(SourceReport::kProfile); 2513 SourceReport sourceReport(SourceReport::kProfile);
2540 JSONStream js; 2514 JSONStream js;
2541 sourceReport.PrintJSON(&js, 2515 sourceReport.PrintJSON(&js, script, do_work.token_pos(),
2542 script,
2543 do_work.token_pos(),
2544 main.end_token_pos()); 2516 main.end_token_pos());
2545 2517
2546 // Verify positions in do_work. 2518 // Verify positions in do_work.
2547 EXPECT_SUBSTRING("\"positions\":[\"ControlFlow\",6]", js.ToCString()); 2519 EXPECT_SUBSTRING("\"positions\":[\"ControlFlow\",6]", js.ToCString());
2548 // Verify exclusive ticks in do_work. 2520 // Verify exclusive ticks in do_work.
2549 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,2]", js.ToCString()); 2521 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,2]", js.ToCString());
2550 // Verify inclusive ticks in do_work. 2522 // Verify inclusive ticks in do_work.
2551 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString()); 2523 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
2552 2524
2553 // Verify positions in main. 2525 // Verify positions in main.
2554 EXPECT_SUBSTRING("\"positions\":[\"TempMove\",39]", js.ToCString()); 2526 EXPECT_SUBSTRING("\"positions\":[\"TempMove\",39]", js.ToCString());
2555 // Verify exclusive ticks in main. 2527 // Verify exclusive ticks in main.
2556 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,0]", js.ToCString()); 2528 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,0]", js.ToCString());
2557 // Verify inclusive ticks in main. 2529 // Verify inclusive ticks in main.
2558 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString()); 2530 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
2559 } 2531 }
2560 2532
2561 #endif // !PRODUCT 2533 #endif // !PRODUCT
2562 2534
2563 } // namespace dart 2535 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler_service.cc ('k') | runtime/vm/random.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698