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

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

Issue 2680213002: Updated MallocHooks to collect stack traces when memory is allocated. (Closed)
Patch Set: Rebased and performed refactoring Created 3 years, 10 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
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/malloc_hooks.h"
10 #include "vm/profiler.h" 11 #include "vm/profiler.h"
11 #include "vm/profiler_service.h" 12 #include "vm/profiler_service.h"
12 #include "vm/source_report.h" 13 #include "vm/source_report.h"
13 #include "vm/unit_test.h" 14 #include "vm/unit_test.h"
14 15
15 namespace dart { 16 namespace dart {
16 17
17 #ifndef PRODUCT 18 #ifndef PRODUCT
18 19
19 DECLARE_FLAG(bool, profile_vm); 20 DECLARE_FLAG(bool, profile_vm);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 62
62 ~MaxProfileDepthScope() { Profiler::SetSampleDepth(FLAG_max_profile_depth_); } 63 ~MaxProfileDepthScope() { Profiler::SetSampleDepth(FLAG_max_profile_depth_); }
63 64
64 private: 65 private:
65 const intptr_t FLAG_max_profile_depth_; 66 const intptr_t FLAG_max_profile_depth_;
66 }; 67 };
67 68
68 69
69 class ProfileSampleBufferTestHelper { 70 class ProfileSampleBufferTestHelper {
70 public: 71 public:
71 static intptr_t IterateCount(const Isolate* isolate, 72 static intptr_t IterateCount(const Dart_Port port,
72 const SampleBuffer& sample_buffer) { 73 const SampleBuffer& sample_buffer) {
73 intptr_t c = 0; 74 intptr_t c = 0;
74 for (intptr_t i = 0; i < sample_buffer.capacity(); i++) { 75 for (intptr_t i = 0; i < sample_buffer.capacity(); i++) {
75 Sample* sample = sample_buffer.At(i); 76 Sample* sample = sample_buffer.At(i);
76 if (sample->isolate() != isolate) { 77 if (sample->port() != port) {
77 continue; 78 continue;
78 } 79 }
79 c++; 80 c++;
80 } 81 }
81 return c; 82 return c;
82 } 83 }
83 84
84 85
85 static intptr_t IterateSumPC(const Isolate* isolate, 86 static intptr_t IterateSumPC(const Dart_Port port,
86 const SampleBuffer& sample_buffer) { 87 const SampleBuffer& sample_buffer) {
87 intptr_t c = 0; 88 intptr_t c = 0;
88 for (intptr_t i = 0; i < sample_buffer.capacity(); i++) { 89 for (intptr_t i = 0; i < sample_buffer.capacity(); i++) {
89 Sample* sample = sample_buffer.At(i); 90 Sample* sample = sample_buffer.At(i);
90 if (sample->isolate() != isolate) { 91 if (sample->port() != port) {
91 continue; 92 continue;
92 } 93 }
93 c += sample->At(0); 94 c += sample->At(0);
94 } 95 }
95 return c; 96 return c;
96 } 97 }
97 }; 98 };
98 99
99 100
100 TEST_CASE(Profiler_SampleBufferWrapTest) { 101 TEST_CASE(Profiler_SampleBufferWrapTest) {
101 SampleBuffer* sample_buffer = new SampleBuffer(3); 102 SampleBuffer* sample_buffer = new SampleBuffer(3);
102 Isolate* i = reinterpret_cast<Isolate*>(0x1); 103 Dart_Port i = 123;
103 EXPECT_EQ(0, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer)); 104 EXPECT_EQ(0, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
104 Sample* s; 105 Sample* s;
105 s = sample_buffer->ReserveSample(); 106 s = sample_buffer->ReserveSample();
106 s->Init(i, 0, 0); 107 s->Init(i, 0, 0);
107 s->SetAt(0, 2); 108 s->SetAt(0, 2);
108 EXPECT_EQ(2, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer)); 109 EXPECT_EQ(2, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
109 s = sample_buffer->ReserveSample(); 110 s = sample_buffer->ReserveSample();
110 s->Init(i, 0, 0); 111 s->Init(i, 0, 0);
111 s->SetAt(0, 4); 112 s->SetAt(0, 4);
112 EXPECT_EQ(6, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer)); 113 EXPECT_EQ(6, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
113 s = sample_buffer->ReserveSample(); 114 s = sample_buffer->ReserveSample();
114 s->Init(i, 0, 0); 115 s->Init(i, 0, 0);
115 s->SetAt(0, 6); 116 s->SetAt(0, 6);
116 EXPECT_EQ(12, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer)); 117 EXPECT_EQ(12, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
117 s = sample_buffer->ReserveSample(); 118 s = sample_buffer->ReserveSample();
118 s->Init(i, 0, 0); 119 s->Init(i, 0, 0);
119 s->SetAt(0, 8); 120 s->SetAt(0, 8);
120 EXPECT_EQ(18, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer)); 121 EXPECT_EQ(18, ProfileSampleBufferTestHelper::IterateSumPC(i, *sample_buffer));
121 delete sample_buffer; 122 delete sample_buffer;
122 } 123 }
123 124
124 125
125 TEST_CASE(Profiler_SampleBufferIterateTest) { 126 TEST_CASE(Profiler_SampleBufferIterateTest) {
126 SampleBuffer* sample_buffer = new SampleBuffer(3); 127 SampleBuffer* sample_buffer = new SampleBuffer(3);
127 Isolate* i = reinterpret_cast<Isolate*>(0x1); 128 Dart_Port i = 123;
128 EXPECT_EQ(0, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer)); 129 EXPECT_EQ(0, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
129 Sample* s; 130 Sample* s;
130 s = sample_buffer->ReserveSample(); 131 s = sample_buffer->ReserveSample();
131 s->Init(i, 0, 0); 132 s->Init(i, 0, 0);
132 EXPECT_EQ(1, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer)); 133 EXPECT_EQ(1, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
133 s = sample_buffer->ReserveSample(); 134 s = sample_buffer->ReserveSample();
134 s->Init(i, 0, 0); 135 s->Init(i, 0, 0);
135 EXPECT_EQ(2, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer)); 136 EXPECT_EQ(2, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
136 s = sample_buffer->ReserveSample(); 137 s = sample_buffer->ReserveSample();
137 s->Init(i, 0, 0); 138 s->Init(i, 0, 0);
138 EXPECT_EQ(3, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer)); 139 EXPECT_EQ(3, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
139 s = sample_buffer->ReserveSample(); 140 s = sample_buffer->ReserveSample();
140 s->Init(i, 0, 0); 141 s->Init(i, 0, 0);
141 EXPECT_EQ(3, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer)); 142 EXPECT_EQ(3, ProfileSampleBufferTestHelper::IterateCount(i, *sample_buffer));
142 delete sample_buffer; 143 delete sample_buffer;
143 } 144 }
144 145
145 146
146 TEST_CASE(Profiler_AllocationSampleTest) { 147 TEST_CASE(Profiler_AllocationSampleTest) {
147 Isolate* isolate = Isolate::Current(); 148 Isolate* isolate = Isolate::Current();
148 SampleBuffer* sample_buffer = new SampleBuffer(3); 149 SampleBuffer* sample_buffer = new SampleBuffer(3);
149 Sample* sample = sample_buffer->ReserveSample(); 150 Sample* sample = sample_buffer->ReserveSample();
150 sample->Init(isolate, 0, 0); 151 sample->Init(isolate->main_port(), 0, 0);
151 sample->set_metadata(99); 152 sample->set_metadata(99);
152 sample->set_is_allocation_sample(true); 153 sample->set_is_allocation_sample(true);
153 EXPECT_EQ(99, sample->allocation_cid()); 154 EXPECT_EQ(99, sample->allocation_cid());
154 delete sample_buffer; 155 delete sample_buffer;
155 } 156 }
156 157
157 158
158 static RawClass* GetClass(const Library& lib, const char* name) { 159 static RawClass* GetClass(const Library& lib, const char* name) {
159 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate( 160 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(
160 String::Handle(Symbols::New(Thread::Current(), name)))); 161 String::Handle(Symbols::New(Thread::Current(), name))));
161 EXPECT(!cls.IsNull()); // No ambiguity error expected. 162 EXPECT(!cls.IsNull()); // No ambiguity error expected.
162 return cls.raw(); 163 return cls.raw();
163 } 164 }
164 165
165 166
166 static RawFunction* GetFunction(const Library& lib, const char* name) { 167 static RawFunction* GetFunction(const Library& lib, const char* name) {
167 const Function& func = Function::Handle(lib.LookupFunctionAllowPrivate( 168 const Function& func = Function::Handle(lib.LookupFunctionAllowPrivate(
168 String::Handle(Symbols::New(Thread::Current(), name)))); 169 String::Handle(Symbols::New(Thread::Current(), name))));
169 EXPECT(!func.IsNull()); // No ambiguity error expected. 170 EXPECT(!func.IsNull()); // No ambiguity error expected.
170 return func.raw(); 171 return func.raw();
171 } 172 }
172 173
173 174
174 class AllocationFilter : public SampleFilter { 175 class AllocationFilter : public SampleFilter {
175 public: 176 public:
176 AllocationFilter(Isolate* isolate, 177 AllocationFilter(Dart_Port port,
177 intptr_t cid, 178 intptr_t cid,
178 int64_t time_origin_micros = -1, 179 int64_t time_origin_micros = -1,
179 int64_t time_extent_micros = -1) 180 int64_t time_extent_micros = -1)
180 : SampleFilter(isolate, 181 : SampleFilter(port,
181 Thread::kMutatorTask, 182 Thread::kMutatorTask,
182 time_origin_micros, 183 time_origin_micros,
183 time_extent_micros), 184 time_extent_micros),
184 cid_(cid), 185 cid_(cid),
185 enable_vm_ticks_(false) {} 186 enable_vm_ticks_(false) {}
186 187
187 bool FilterSample(Sample* sample) { 188 bool FilterSample(Sample* sample) {
188 if (!enable_vm_ticks_ && (sample->vm_tag() == VMTag::kVMTagId)) { 189 if (!enable_vm_ticks_ && (sample->vm_tag() == VMTag::kVMTagId)) {
189 // We don't want to see embedder ticks in the test. 190 // We don't want to see embedder ticks in the test.
190 return false; 191 return false;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 const int64_t after_allocations_micros = Dart_TimelineGetMicros(); 233 const int64_t after_allocations_micros = Dart_TimelineGetMicros();
233 const int64_t allocation_extent_micros = 234 const int64_t allocation_extent_micros =
234 after_allocations_micros - before_allocations_micros; 235 after_allocations_micros - before_allocations_micros;
235 { 236 {
236 Thread* thread = Thread::Current(); 237 Thread* thread = Thread::Current();
237 Isolate* isolate = thread->isolate(); 238 Isolate* isolate = thread->isolate();
238 StackZone zone(thread); 239 StackZone zone(thread);
239 HANDLESCOPE(thread); 240 HANDLESCOPE(thread);
240 Profile profile(isolate); 241 Profile profile(isolate);
241 // Filter for the class in the time range. 242 // Filter for the class in the time range.
242 AllocationFilter filter(isolate, class_a.id(), before_allocations_micros, 243 AllocationFilter filter(isolate->main_port(), class_a.id(),
244 before_allocations_micros,
243 allocation_extent_micros); 245 allocation_extent_micros);
244 profile.Build(thread, &filter, Profile::kNoTags); 246 profile.Build(thread, &filter, Profile::kNoTags);
245 // We should have 1 allocation sample. 247 // We should have 1 allocation sample.
246 EXPECT_EQ(1, profile.sample_count()); 248 EXPECT_EQ(1, profile.sample_count());
247 ProfileTrieWalker walker(&profile); 249 ProfileTrieWalker walker(&profile);
248 250
249 // Exclusive code: B.boo -> main. 251 // Exclusive code: B.boo -> main.
250 walker.Reset(Profile::kExclusiveCode); 252 walker.Reset(Profile::kExclusiveCode);
251 // Move down from the root. 253 // Move down from the root.
252 EXPECT(walker.Down()); 254 EXPECT(walker.Down());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 EXPECT(!walker.Down()); 301 EXPECT(!walker.Down());
300 } 302 }
301 303
302 // Query with a time filter where no allocations occurred. 304 // Query with a time filter where no allocations occurred.
303 { 305 {
304 Thread* thread = Thread::Current(); 306 Thread* thread = Thread::Current();
305 Isolate* isolate = thread->isolate(); 307 Isolate* isolate = thread->isolate();
306 StackZone zone(thread); 308 StackZone zone(thread);
307 HANDLESCOPE(thread); 309 HANDLESCOPE(thread);
308 Profile profile(isolate); 310 Profile profile(isolate);
309 AllocationFilter filter(isolate, class_a.id(), Dart_TimelineGetMicros(), 311 AllocationFilter filter(isolate->main_port(), class_a.id(),
310 16000); 312 Dart_TimelineGetMicros(), 16000);
311 profile.Build(thread, &filter, Profile::kNoTags); 313 profile.Build(thread, &filter, Profile::kNoTags);
312 // We should have no allocation samples because none occured within 314 // We should have no allocation samples because none occured within
313 // the specified time range. 315 // the specified time range.
314 EXPECT_EQ(0, profile.sample_count()); 316 EXPECT_EQ(0, profile.sample_count());
315 } 317 }
316 } 318 }
317 319
318 320
319 TEST_CASE(Profiler_ToggleRecordAllocation) { 321 TEST_CASE(Profiler_ToggleRecordAllocation) {
320 DisableNativeProfileScope dnps; 322 DisableNativeProfileScope dnps;
(...skipping 22 matching lines...) Expand all
343 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); 345 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
344 EXPECT_VALID(result); 346 EXPECT_VALID(result);
345 347
346 348
347 { 349 {
348 Thread* thread = Thread::Current(); 350 Thread* thread = Thread::Current();
349 Isolate* isolate = thread->isolate(); 351 Isolate* isolate = thread->isolate();
350 StackZone zone(thread); 352 StackZone zone(thread);
351 HANDLESCOPE(thread); 353 HANDLESCOPE(thread);
352 Profile profile(isolate); 354 Profile profile(isolate);
353 AllocationFilter filter(isolate, class_a.id()); 355 AllocationFilter filter(isolate->main_port(), class_a.id());
354 profile.Build(thread, &filter, Profile::kNoTags); 356 profile.Build(thread, &filter, Profile::kNoTags);
355 // We should have no allocation samples. 357 // We should have no allocation samples.
356 EXPECT_EQ(0, profile.sample_count()); 358 EXPECT_EQ(0, profile.sample_count());
357 } 359 }
358 360
359 // Turn on allocation tracing for A. 361 // Turn on allocation tracing for A.
360 class_a.SetTraceAllocation(true); 362 class_a.SetTraceAllocation(true);
361 363
362 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 364 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
363 EXPECT_VALID(result); 365 EXPECT_VALID(result);
364 366
365 { 367 {
366 Thread* thread = Thread::Current(); 368 Thread* thread = Thread::Current();
367 Isolate* isolate = thread->isolate(); 369 Isolate* isolate = thread->isolate();
368 StackZone zone(thread); 370 StackZone zone(thread);
369 HANDLESCOPE(thread); 371 HANDLESCOPE(thread);
370 Profile profile(isolate); 372 Profile profile(isolate);
371 AllocationFilter filter(isolate, class_a.id()); 373 AllocationFilter filter(isolate->main_port(), class_a.id());
372 profile.Build(thread, &filter, Profile::kNoTags); 374 profile.Build(thread, &filter, Profile::kNoTags);
373 // We should have one allocation sample. 375 // We should have one allocation sample.
374 EXPECT_EQ(1, profile.sample_count()); 376 EXPECT_EQ(1, profile.sample_count());
375 ProfileTrieWalker walker(&profile); 377 ProfileTrieWalker walker(&profile);
376 378
377 // Exclusive code: B.boo -> main. 379 // Exclusive code: B.boo -> main.
378 walker.Reset(Profile::kExclusiveCode); 380 walker.Reset(Profile::kExclusiveCode);
379 // Move down from the root. 381 // Move down from the root.
380 EXPECT(walker.Down()); 382 EXPECT(walker.Down());
381 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 383 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 434
433 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 435 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
434 EXPECT_VALID(result); 436 EXPECT_VALID(result);
435 437
436 { 438 {
437 Thread* thread = Thread::Current(); 439 Thread* thread = Thread::Current();
438 Isolate* isolate = thread->isolate(); 440 Isolate* isolate = thread->isolate();
439 StackZone zone(thread); 441 StackZone zone(thread);
440 HANDLESCOPE(thread); 442 HANDLESCOPE(thread);
441 Profile profile(isolate); 443 Profile profile(isolate);
442 AllocationFilter filter(isolate, class_a.id()); 444 AllocationFilter filter(isolate->main_port(), class_a.id());
443 profile.Build(thread, &filter, Profile::kNoTags); 445 profile.Build(thread, &filter, Profile::kNoTags);
444 // We should still only have one allocation sample. 446 // We should still only have one allocation sample.
445 EXPECT_EQ(1, profile.sample_count()); 447 EXPECT_EQ(1, profile.sample_count());
446 } 448 }
447 } 449 }
448 450
449 451
450 TEST_CASE(Profiler_CodeTicks) { 452 TEST_CASE(Profiler_CodeTicks) {
451 DisableNativeProfileScope dnps; 453 DisableNativeProfileScope dnps;
452 const char* kScript = 454 const char* kScript =
(...skipping 20 matching lines...) Expand all
473 475
474 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); 476 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
475 EXPECT_VALID(result); 477 EXPECT_VALID(result);
476 478
477 { 479 {
478 Thread* thread = Thread::Current(); 480 Thread* thread = Thread::Current();
479 Isolate* isolate = thread->isolate(); 481 Isolate* isolate = thread->isolate();
480 StackZone zone(thread); 482 StackZone zone(thread);
481 HANDLESCOPE(thread); 483 HANDLESCOPE(thread);
482 Profile profile(isolate); 484 Profile profile(isolate);
483 AllocationFilter filter(isolate, class_a.id()); 485 AllocationFilter filter(isolate->main_port(), class_a.id());
484 profile.Build(thread, &filter, Profile::kNoTags); 486 profile.Build(thread, &filter, Profile::kNoTags);
485 // We should have no allocation samples. 487 // We should have no allocation samples.
486 EXPECT_EQ(0, profile.sample_count()); 488 EXPECT_EQ(0, profile.sample_count());
487 } 489 }
488 490
489 // Turn on allocation tracing for A. 491 // Turn on allocation tracing for A.
490 class_a.SetTraceAllocation(true); 492 class_a.SetTraceAllocation(true);
491 493
492 // Allocate three times. 494 // Allocate three times.
493 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 495 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
494 EXPECT_VALID(result); 496 EXPECT_VALID(result);
495 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 497 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
496 EXPECT_VALID(result); 498 EXPECT_VALID(result);
497 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 499 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
498 EXPECT_VALID(result); 500 EXPECT_VALID(result);
499 501
500 { 502 {
501 Thread* thread = Thread::Current(); 503 Thread* thread = Thread::Current();
502 Isolate* isolate = thread->isolate(); 504 Isolate* isolate = thread->isolate();
503 StackZone zone(thread); 505 StackZone zone(thread);
504 HANDLESCOPE(thread); 506 HANDLESCOPE(thread);
505 Profile profile(isolate); 507 Profile profile(isolate);
506 AllocationFilter filter(isolate, class_a.id()); 508 AllocationFilter filter(isolate->main_port(), class_a.id());
507 profile.Build(thread, &filter, Profile::kNoTags); 509 profile.Build(thread, &filter, Profile::kNoTags);
508 // We should have three allocation samples. 510 // We should have three allocation samples.
509 EXPECT_EQ(3, profile.sample_count()); 511 EXPECT_EQ(3, profile.sample_count());
510 ProfileTrieWalker walker(&profile); 512 ProfileTrieWalker walker(&profile);
511 513
512 // Exclusive code: B.boo -> main. 514 // Exclusive code: B.boo -> main.
513 walker.Reset(Profile::kExclusiveCode); 515 walker.Reset(Profile::kExclusiveCode);
514 // Move down from the root. 516 // Move down from the root.
515 EXPECT(walker.Down()); 517 EXPECT(walker.Down());
516 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 518 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 578
577 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); 579 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
578 EXPECT_VALID(result); 580 EXPECT_VALID(result);
579 581
580 { 582 {
581 Thread* thread = Thread::Current(); 583 Thread* thread = Thread::Current();
582 Isolate* isolate = thread->isolate(); 584 Isolate* isolate = thread->isolate();
583 StackZone zone(thread); 585 StackZone zone(thread);
584 HANDLESCOPE(thread); 586 HANDLESCOPE(thread);
585 Profile profile(isolate); 587 Profile profile(isolate);
586 AllocationFilter filter(isolate, class_a.id()); 588 AllocationFilter filter(isolate->main_port(), class_a.id());
587 profile.Build(thread, &filter, Profile::kNoTags); 589 profile.Build(thread, &filter, Profile::kNoTags);
588 // We should have no allocation samples. 590 // We should have no allocation samples.
589 EXPECT_EQ(0, profile.sample_count()); 591 EXPECT_EQ(0, profile.sample_count());
590 } 592 }
591 593
592 // Turn on allocation tracing for A. 594 // Turn on allocation tracing for A.
593 class_a.SetTraceAllocation(true); 595 class_a.SetTraceAllocation(true);
594 596
595 // Allocate three times. 597 // Allocate three times.
596 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 598 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
597 EXPECT_VALID(result); 599 EXPECT_VALID(result);
598 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 600 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
599 EXPECT_VALID(result); 601 EXPECT_VALID(result);
600 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 602 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
601 EXPECT_VALID(result); 603 EXPECT_VALID(result);
602 604
603 { 605 {
604 Thread* thread = Thread::Current(); 606 Thread* thread = Thread::Current();
605 Isolate* isolate = thread->isolate(); 607 Isolate* isolate = thread->isolate();
606 StackZone zone(thread); 608 StackZone zone(thread);
607 HANDLESCOPE(thread); 609 HANDLESCOPE(thread);
608 Profile profile(isolate); 610 Profile profile(isolate);
609 AllocationFilter filter(isolate, class_a.id()); 611 AllocationFilter filter(isolate->main_port(), class_a.id());
610 profile.Build(thread, &filter, Profile::kNoTags); 612 profile.Build(thread, &filter, Profile::kNoTags);
611 // We should have three allocation samples. 613 // We should have three allocation samples.
612 EXPECT_EQ(3, profile.sample_count()); 614 EXPECT_EQ(3, profile.sample_count());
613 ProfileTrieWalker walker(&profile); 615 ProfileTrieWalker walker(&profile);
614 616
615 // Exclusive function: B.boo -> main. 617 // Exclusive function: B.boo -> main.
616 walker.Reset(Profile::kExclusiveFunction); 618 walker.Reset(Profile::kExclusiveFunction);
617 // Move down from the root. 619 // Move down from the root.
618 EXPECT(walker.Down()); 620 EXPECT(walker.Down());
619 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 621 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 Dart_NewDouble(1.0), Dart_NewDouble(2.0), 672 Dart_NewDouble(1.0), Dart_NewDouble(2.0),
671 }; 673 };
672 674
673 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 675 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
674 EXPECT_VALID(result); 676 EXPECT_VALID(result);
675 677
676 { 678 {
677 StackZone zone(thread); 679 StackZone zone(thread);
678 HANDLESCOPE(thread); 680 HANDLESCOPE(thread);
679 Profile profile(isolate); 681 Profile profile(isolate);
680 AllocationFilter filter(isolate, double_class.id()); 682 AllocationFilter filter(isolate->main_port(), double_class.id());
681 profile.Build(thread, &filter, Profile::kNoTags); 683 profile.Build(thread, &filter, Profile::kNoTags);
682 // We should have no allocation samples. 684 // We should have no allocation samples.
683 EXPECT_EQ(0, profile.sample_count()); 685 EXPECT_EQ(0, profile.sample_count());
684 } 686 }
685 687
686 double_class.SetTraceAllocation(true); 688 double_class.SetTraceAllocation(true);
687 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 689 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
688 EXPECT_VALID(result); 690 EXPECT_VALID(result);
689 691
690 { 692 {
691 StackZone zone(thread); 693 StackZone zone(thread);
692 HANDLESCOPE(thread); 694 HANDLESCOPE(thread);
693 Profile profile(isolate); 695 Profile profile(isolate);
694 AllocationFilter filter(isolate, double_class.id()); 696 AllocationFilter filter(isolate->main_port(), double_class.id());
695 profile.Build(thread, &filter, Profile::kNoTags); 697 profile.Build(thread, &filter, Profile::kNoTags);
696 // We should have one allocation sample. 698 // We should have one allocation sample.
697 EXPECT_EQ(1, profile.sample_count()); 699 EXPECT_EQ(1, profile.sample_count());
698 ProfileTrieWalker walker(&profile); 700 ProfileTrieWalker walker(&profile);
699 701
700 walker.Reset(Profile::kExclusiveCode); 702 walker.Reset(Profile::kExclusiveCode);
701 EXPECT(walker.Down()); 703 EXPECT(walker.Down());
702 EXPECT_STREQ("Double_add", walker.CurrentName()); 704 EXPECT_STREQ("Double_add", walker.CurrentName());
703 EXPECT(walker.Down()); 705 EXPECT(walker.Down());
704 EXPECT_STREQ("_Double._add", walker.CurrentName()); 706 EXPECT_STREQ("_Double._add", walker.CurrentName());
705 EXPECT(walker.Down()); 707 EXPECT(walker.Down());
706 EXPECT_STREQ("_Double.+", walker.CurrentName()); 708 EXPECT_STREQ("_Double.+", walker.CurrentName());
707 EXPECT(walker.Down()); 709 EXPECT(walker.Down());
708 EXPECT_STREQ("foo", walker.CurrentName()); 710 EXPECT_STREQ("foo", walker.CurrentName());
709 EXPECT(!walker.Down()); 711 EXPECT(!walker.Down());
710 } 712 }
711 713
712 double_class.SetTraceAllocation(false); 714 double_class.SetTraceAllocation(false);
713 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 715 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
714 EXPECT_VALID(result); 716 EXPECT_VALID(result);
715 717
716 { 718 {
717 StackZone zone(thread); 719 StackZone zone(thread);
718 HANDLESCOPE(thread); 720 HANDLESCOPE(thread);
719 Profile profile(isolate); 721 Profile profile(isolate);
720 AllocationFilter filter(isolate, double_class.id()); 722 AllocationFilter filter(isolate->main_port(), double_class.id());
721 profile.Build(thread, &filter, Profile::kNoTags); 723 profile.Build(thread, &filter, Profile::kNoTags);
722 // We should still only have one allocation sample. 724 // We should still only have one allocation sample.
723 EXPECT_EQ(1, profile.sample_count()); 725 EXPECT_EQ(1, profile.sample_count());
724 } 726 }
725 } 727 }
726 728
727 729
728 TEST_CASE(Profiler_ArrayAllocation) { 730 TEST_CASE(Profiler_ArrayAllocation) {
729 DisableNativeProfileScope dnps; 731 DisableNativeProfileScope dnps;
730 const char* kScript = 732 const char* kScript =
731 "List foo() => new List(4);\n" 733 "List foo() => new List(4);\n"
732 "List bar() => new List();\n"; 734 "List bar() => new List();\n";
733 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); 735 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
734 EXPECT_VALID(lib); 736 EXPECT_VALID(lib);
735 Library& root_library = Library::Handle(); 737 Library& root_library = Library::Handle();
736 root_library ^= Api::UnwrapHandle(lib); 738 root_library ^= Api::UnwrapHandle(lib);
737 Isolate* isolate = thread->isolate(); 739 Isolate* isolate = thread->isolate();
738 740
739 const Class& array_class = 741 const Class& array_class =
740 Class::Handle(isolate->object_store()->array_class()); 742 Class::Handle(isolate->object_store()->array_class());
741 EXPECT(!array_class.IsNull()); 743 EXPECT(!array_class.IsNull());
742 744
743 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 745 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
744 EXPECT_VALID(result); 746 EXPECT_VALID(result);
745 747
746 { 748 {
747 StackZone zone(thread); 749 StackZone zone(thread);
748 HANDLESCOPE(thread); 750 HANDLESCOPE(thread);
749 Profile profile(isolate); 751 Profile profile(isolate);
750 AllocationFilter filter(isolate, array_class.id()); 752 AllocationFilter filter(isolate->main_port(), array_class.id());
751 profile.Build(thread, &filter, Profile::kNoTags); 753 profile.Build(thread, &filter, Profile::kNoTags);
752 // We should have no allocation samples. 754 // We should have no allocation samples.
753 EXPECT_EQ(0, profile.sample_count()); 755 EXPECT_EQ(0, profile.sample_count());
754 } 756 }
755 757
756 array_class.SetTraceAllocation(true); 758 array_class.SetTraceAllocation(true);
757 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 759 result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
758 EXPECT_VALID(result); 760 EXPECT_VALID(result);
759 761
760 { 762 {
761 StackZone zone(thread); 763 StackZone zone(thread);
762 HANDLESCOPE(thread); 764 HANDLESCOPE(thread);
763 Profile profile(isolate); 765 Profile profile(isolate);
764 AllocationFilter filter(isolate, array_class.id()); 766 AllocationFilter filter(isolate->main_port(), array_class.id());
765 profile.Build(thread, &filter, Profile::kNoTags); 767 profile.Build(thread, &filter, Profile::kNoTags);
766 // We should have one allocation sample. 768 // We should have one allocation sample.
767 EXPECT_EQ(1, profile.sample_count()); 769 EXPECT_EQ(1, profile.sample_count());
768 ProfileTrieWalker walker(&profile); 770 ProfileTrieWalker walker(&profile);
769 771
770 walker.Reset(Profile::kExclusiveCode); 772 walker.Reset(Profile::kExclusiveCode);
771 EXPECT(walker.Down()); 773 EXPECT(walker.Down());
772 EXPECT_STREQ("DRT_AllocateArray", walker.CurrentName()); 774 EXPECT_STREQ("DRT_AllocateArray", walker.CurrentName());
773 EXPECT(walker.Down()); 775 EXPECT(walker.Down());
774 EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName()); 776 EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName());
775 EXPECT(walker.Down()); 777 EXPECT(walker.Down());
776 EXPECT_STREQ("_List._List", walker.CurrentName()); 778 EXPECT_STREQ("_List._List", walker.CurrentName());
777 EXPECT(walker.Down()); 779 EXPECT(walker.Down());
778 EXPECT_STREQ("List.List._internal", walker.CurrentName()); 780 EXPECT_STREQ("List.List._internal", walker.CurrentName());
779 EXPECT(walker.Down()); 781 EXPECT(walker.Down());
780 EXPECT_STREQ("foo", walker.CurrentName()); 782 EXPECT_STREQ("foo", walker.CurrentName());
781 EXPECT(!walker.Down()); 783 EXPECT(!walker.Down());
782 } 784 }
783 785
784 array_class.SetTraceAllocation(false); 786 array_class.SetTraceAllocation(false);
785 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 787 result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
786 EXPECT_VALID(result); 788 EXPECT_VALID(result);
787 789
788 { 790 {
789 StackZone zone(thread); 791 StackZone zone(thread);
790 HANDLESCOPE(thread); 792 HANDLESCOPE(thread);
791 Profile profile(isolate); 793 Profile profile(isolate);
792 AllocationFilter filter(isolate, array_class.id()); 794 AllocationFilter filter(isolate->main_port(), array_class.id());
793 profile.Build(thread, &filter, Profile::kNoTags); 795 profile.Build(thread, &filter, Profile::kNoTags);
794 // We should still only have one allocation sample. 796 // We should still only have one allocation sample.
795 EXPECT_EQ(1, profile.sample_count()); 797 EXPECT_EQ(1, profile.sample_count());
796 } 798 }
797 799
798 // Clear the samples. 800 // Clear the samples.
799 ProfilerService::ClearSamples(); 801 ProfilerService::ClearSamples();
800 802
801 // Compile bar (many List objects allocated). 803 // Compile bar (many List objects allocated).
802 result = Dart_Invoke(lib, NewString("bar"), 0, NULL); 804 result = Dart_Invoke(lib, NewString("bar"), 0, NULL);
803 EXPECT_VALID(result); 805 EXPECT_VALID(result);
804 806
805 // Enable again. 807 // Enable again.
806 array_class.SetTraceAllocation(true); 808 array_class.SetTraceAllocation(true);
807 809
808 // Run bar. 810 // Run bar.
809 result = Dart_Invoke(lib, NewString("bar"), 0, NULL); 811 result = Dart_Invoke(lib, NewString("bar"), 0, NULL);
810 EXPECT_VALID(result); 812 EXPECT_VALID(result);
811 813
812 { 814 {
813 StackZone zone(thread); 815 StackZone zone(thread);
814 HANDLESCOPE(thread); 816 HANDLESCOPE(thread);
815 Profile profile(isolate); 817 Profile profile(isolate);
816 AllocationFilter filter(isolate, array_class.id()); 818 AllocationFilter filter(isolate->main_port(), array_class.id());
817 profile.Build(thread, &filter, Profile::kNoTags); 819 profile.Build(thread, &filter, Profile::kNoTags);
818 // We should still only have one allocation sample. 820 // We should still only have one allocation sample.
819 EXPECT_EQ(1, profile.sample_count()); 821 EXPECT_EQ(1, profile.sample_count());
820 ProfileTrieWalker walker(&profile); 822 ProfileTrieWalker walker(&profile);
821 823
822 walker.Reset(Profile::kExclusiveCode); 824 walker.Reset(Profile::kExclusiveCode);
823 EXPECT(walker.Down()); 825 EXPECT(walker.Down());
824 EXPECT_STREQ("DRT_AllocateArray", walker.CurrentName()); 826 EXPECT_STREQ("DRT_AllocateArray", walker.CurrentName());
825 EXPECT(walker.Down()); 827 EXPECT(walker.Down());
826 EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName()); 828 EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName());
(...skipping 27 matching lines...) Expand all
854 const Class& context_class = Class::Handle(Object::context_class()); 856 const Class& context_class = Class::Handle(Object::context_class());
855 EXPECT(!context_class.IsNull()); 857 EXPECT(!context_class.IsNull());
856 858
857 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 859 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
858 EXPECT_VALID(result); 860 EXPECT_VALID(result);
859 861
860 { 862 {
861 StackZone zone(thread); 863 StackZone zone(thread);
862 HANDLESCOPE(thread); 864 HANDLESCOPE(thread);
863 Profile profile(isolate); 865 Profile profile(isolate);
864 AllocationFilter filter(isolate, context_class.id()); 866 AllocationFilter filter(isolate->main_port(), context_class.id());
865 profile.Build(thread, &filter, Profile::kNoTags); 867 profile.Build(thread, &filter, Profile::kNoTags);
866 // We should have no allocation samples. 868 // We should have no allocation samples.
867 EXPECT_EQ(0, profile.sample_count()); 869 EXPECT_EQ(0, profile.sample_count());
868 } 870 }
869 871
870 context_class.SetTraceAllocation(true); 872 context_class.SetTraceAllocation(true);
871 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 873 result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
872 EXPECT_VALID(result); 874 EXPECT_VALID(result);
873 875
874 { 876 {
875 StackZone zone(thread); 877 StackZone zone(thread);
876 HANDLESCOPE(thread); 878 HANDLESCOPE(thread);
877 Profile profile(isolate); 879 Profile profile(isolate);
878 AllocationFilter filter(isolate, context_class.id()); 880 AllocationFilter filter(isolate->main_port(), context_class.id());
879 profile.Build(thread, &filter, Profile::kNoTags); 881 profile.Build(thread, &filter, Profile::kNoTags);
880 // We should have one allocation sample. 882 // We should have one allocation sample.
881 EXPECT_EQ(1, profile.sample_count()); 883 EXPECT_EQ(1, profile.sample_count());
882 ProfileTrieWalker walker(&profile); 884 ProfileTrieWalker walker(&profile);
883 885
884 walker.Reset(Profile::kExclusiveCode); 886 walker.Reset(Profile::kExclusiveCode);
885 EXPECT(walker.Down()); 887 EXPECT(walker.Down());
886 EXPECT_STREQ("DRT_AllocateContext", walker.CurrentName()); 888 EXPECT_STREQ("DRT_AllocateContext", walker.CurrentName());
887 EXPECT(walker.Down()); 889 EXPECT(walker.Down());
888 EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName()); 890 EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName());
889 EXPECT(walker.Down()); 891 EXPECT(walker.Down());
890 EXPECT_STREQ("foo", walker.CurrentName()); 892 EXPECT_STREQ("foo", walker.CurrentName());
891 EXPECT(!walker.Down()); 893 EXPECT(!walker.Down());
892 } 894 }
893 895
894 context_class.SetTraceAllocation(false); 896 context_class.SetTraceAllocation(false);
895 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 897 result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
896 EXPECT_VALID(result); 898 EXPECT_VALID(result);
897 899
898 { 900 {
899 StackZone zone(thread); 901 StackZone zone(thread);
900 HANDLESCOPE(thread); 902 HANDLESCOPE(thread);
901 Profile profile(isolate); 903 Profile profile(isolate);
902 AllocationFilter filter(isolate, context_class.id()); 904 AllocationFilter filter(isolate->main_port(), context_class.id());
903 profile.Build(thread, &filter, Profile::kNoTags); 905 profile.Build(thread, &filter, Profile::kNoTags);
904 // We should still only have one allocation sample. 906 // We should still only have one allocation sample.
905 EXPECT_EQ(1, profile.sample_count()); 907 EXPECT_EQ(1, profile.sample_count());
906 } 908 }
907 } 909 }
908 910
909 911
910 TEST_CASE(Profiler_ClosureAllocation) { 912 TEST_CASE(Profiler_ClosureAllocation) {
911 DisableNativeProfileScope dnps; 913 DisableNativeProfileScope dnps;
912 const char* kScript = 914 const char* kScript =
(...skipping 22 matching lines...) Expand all
935 closure_class.SetTraceAllocation(true); 937 closure_class.SetTraceAllocation(true);
936 938
937 // Invoke "foo" which during compilation, triggers a closure allocation. 939 // Invoke "foo" which during compilation, triggers a closure allocation.
938 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 940 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
939 EXPECT_VALID(result); 941 EXPECT_VALID(result);
940 942
941 { 943 {
942 StackZone zone(thread); 944 StackZone zone(thread);
943 HANDLESCOPE(thread); 945 HANDLESCOPE(thread);
944 Profile profile(isolate); 946 Profile profile(isolate);
945 AllocationFilter filter(isolate, closure_class.id()); 947 AllocationFilter filter(isolate->main_port(), closure_class.id());
946 filter.set_enable_vm_ticks(true); 948 filter.set_enable_vm_ticks(true);
947 profile.Build(thread, &filter, Profile::kNoTags); 949 profile.Build(thread, &filter, Profile::kNoTags);
948 // We should have one allocation sample. 950 // We should have one allocation sample.
949 EXPECT_EQ(1, profile.sample_count()); 951 EXPECT_EQ(1, profile.sample_count());
950 ProfileTrieWalker walker(&profile); 952 ProfileTrieWalker walker(&profile);
951 953
952 walker.Reset(Profile::kExclusiveCode); 954 walker.Reset(Profile::kExclusiveCode);
953 EXPECT(walker.Down()); 955 EXPECT(walker.Down());
954 EXPECT_SUBSTRING("DRT_AllocateObject", walker.CurrentName()); 956 EXPECT_SUBSTRING("DRT_AllocateObject", walker.CurrentName());
955 EXPECT(walker.Down()); 957 EXPECT(walker.Down());
956 EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName()); 958 EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName());
957 EXPECT(walker.Down()); 959 EXPECT(walker.Down());
958 EXPECT_SUBSTRING("foo", walker.CurrentName()); 960 EXPECT_SUBSTRING("foo", walker.CurrentName());
959 EXPECT(!walker.Down()); 961 EXPECT(!walker.Down());
960 } 962 }
961 963
962 // Disable allocation tracing for Closure. 964 // Disable allocation tracing for Closure.
963 closure_class.SetTraceAllocation(false); 965 closure_class.SetTraceAllocation(false);
964 966
965 // Invoke "bar" which during compilation, triggers a closure allocation. 967 // Invoke "bar" which during compilation, triggers a closure allocation.
966 result = Dart_Invoke(lib, NewString("bar"), 0, NULL); 968 result = Dart_Invoke(lib, NewString("bar"), 0, NULL);
967 EXPECT_VALID(result); 969 EXPECT_VALID(result);
968 970
969 { 971 {
970 StackZone zone(thread); 972 StackZone zone(thread);
971 HANDLESCOPE(thread); 973 HANDLESCOPE(thread);
972 Profile profile(isolate); 974 Profile profile(isolate);
973 AllocationFilter filter(isolate, closure_class.id()); 975 AllocationFilter filter(isolate->main_port(), closure_class.id());
974 filter.set_enable_vm_ticks(true); 976 filter.set_enable_vm_ticks(true);
975 profile.Build(thread, &filter, Profile::kNoTags); 977 profile.Build(thread, &filter, Profile::kNoTags);
976 // We should still only have one allocation sample. 978 // We should still only have one allocation sample.
977 EXPECT_EQ(1, profile.sample_count()); 979 EXPECT_EQ(1, profile.sample_count());
978 } 980 }
979 } 981 }
980 982
981 983
982 TEST_CASE(Profiler_TypedArrayAllocation) { 984 TEST_CASE(Profiler_TypedArrayAllocation) {
983 DisableNativeProfileScope dnps; 985 DisableNativeProfileScope dnps;
(...skipping 13 matching lines...) Expand all
997 Class::Handle(GetClass(typed_data_library, "_Float32List")); 999 Class::Handle(GetClass(typed_data_library, "_Float32List"));
998 EXPECT(!float32_list_class.IsNull()); 1000 EXPECT(!float32_list_class.IsNull());
999 1001
1000 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 1002 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
1001 EXPECT_VALID(result); 1003 EXPECT_VALID(result);
1002 1004
1003 { 1005 {
1004 StackZone zone(thread); 1006 StackZone zone(thread);
1005 HANDLESCOPE(thread); 1007 HANDLESCOPE(thread);
1006 Profile profile(isolate); 1008 Profile profile(isolate);
1007 AllocationFilter filter(isolate, float32_list_class.id()); 1009 AllocationFilter filter(isolate->main_port(), float32_list_class.id());
1008 profile.Build(thread, &filter, Profile::kNoTags); 1010 profile.Build(thread, &filter, Profile::kNoTags);
1009 // We should have no allocation samples. 1011 // We should have no allocation samples.
1010 EXPECT_EQ(0, profile.sample_count()); 1012 EXPECT_EQ(0, profile.sample_count());
1011 } 1013 }
1012 1014
1013 float32_list_class.SetTraceAllocation(true); 1015 float32_list_class.SetTraceAllocation(true);
1014 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 1016 result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
1015 EXPECT_VALID(result); 1017 EXPECT_VALID(result);
1016 1018
1017 { 1019 {
1018 StackZone zone(thread); 1020 StackZone zone(thread);
1019 HANDLESCOPE(thread); 1021 HANDLESCOPE(thread);
1020 Profile profile(isolate); 1022 Profile profile(isolate);
1021 AllocationFilter filter(isolate, float32_list_class.id()); 1023 AllocationFilter filter(isolate->main_port(), float32_list_class.id());
1022 profile.Build(thread, &filter, Profile::kNoTags); 1024 profile.Build(thread, &filter, Profile::kNoTags);
1023 // We should have one allocation sample. 1025 // We should have one allocation sample.
1024 EXPECT_EQ(1, profile.sample_count()); 1026 EXPECT_EQ(1, profile.sample_count());
1025 ProfileTrieWalker walker(&profile); 1027 ProfileTrieWalker walker(&profile);
1026 1028
1027 walker.Reset(Profile::kExclusiveCode); 1029 walker.Reset(Profile::kExclusiveCode);
1028 EXPECT(walker.Down()); 1030 EXPECT(walker.Down());
1029 EXPECT_STREQ("TypedData_Float32Array_new", walker.CurrentName()); 1031 EXPECT_STREQ("TypedData_Float32Array_new", walker.CurrentName());
1030 EXPECT(walker.Down()); 1032 EXPECT(walker.Down());
1031 EXPECT_STREQ("Float32List.Float32List", walker.CurrentName()); 1033 EXPECT_STREQ("Float32List.Float32List", walker.CurrentName());
1032 EXPECT(walker.Down()); 1034 EXPECT(walker.Down());
1033 EXPECT_STREQ("foo", walker.CurrentName()); 1035 EXPECT_STREQ("foo", walker.CurrentName());
1034 EXPECT(!walker.Down()); 1036 EXPECT(!walker.Down());
1035 } 1037 }
1036 1038
1037 float32_list_class.SetTraceAllocation(false); 1039 float32_list_class.SetTraceAllocation(false);
1038 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 1040 result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
1039 EXPECT_VALID(result); 1041 EXPECT_VALID(result);
1040 1042
1041 { 1043 {
1042 StackZone zone(thread); 1044 StackZone zone(thread);
1043 HANDLESCOPE(thread); 1045 HANDLESCOPE(thread);
1044 Profile profile(isolate); 1046 Profile profile(isolate);
1045 AllocationFilter filter(isolate, float32_list_class.id()); 1047 AllocationFilter filter(isolate->main_port(), float32_list_class.id());
1046 profile.Build(thread, &filter, Profile::kNoTags); 1048 profile.Build(thread, &filter, Profile::kNoTags);
1047 // We should still only have one allocation sample. 1049 // We should still only have one allocation sample.
1048 EXPECT_EQ(1, profile.sample_count()); 1050 EXPECT_EQ(1, profile.sample_count());
1049 } 1051 }
1050 1052
1051 float32_list_class.SetTraceAllocation(true); 1053 float32_list_class.SetTraceAllocation(true);
1052 result = Dart_Invoke(lib, NewString("foo"), 0, NULL); 1054 result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
1053 EXPECT_VALID(result); 1055 EXPECT_VALID(result);
1054 1056
1055 { 1057 {
1056 StackZone zone(thread); 1058 StackZone zone(thread);
1057 HANDLESCOPE(thread); 1059 HANDLESCOPE(thread);
1058 Profile profile(isolate); 1060 Profile profile(isolate);
1059 AllocationFilter filter(isolate, float32_list_class.id()); 1061 AllocationFilter filter(isolate->main_port(), float32_list_class.id());
1060 profile.Build(thread, &filter, Profile::kNoTags); 1062 profile.Build(thread, &filter, Profile::kNoTags);
1061 // We should now have two allocation samples. 1063 // We should now have two allocation samples.
1062 EXPECT_EQ(2, profile.sample_count()); 1064 EXPECT_EQ(2, profile.sample_count());
1063 } 1065 }
1064 } 1066 }
1065 1067
1066 1068
1067 TEST_CASE(Profiler_StringAllocation) { 1069 TEST_CASE(Profiler_StringAllocation) {
1068 DisableNativeProfileScope dnps; 1070 DisableNativeProfileScope dnps;
1069 const char* kScript = "String foo(String a, String b) => a + b;"; 1071 const char* kScript = "String foo(String a, String b) => a + b;";
(...skipping 11 matching lines...) Expand all
1081 NewString("a"), NewString("b"), 1083 NewString("a"), NewString("b"),
1082 }; 1084 };
1083 1085
1084 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1086 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1085 EXPECT_VALID(result); 1087 EXPECT_VALID(result);
1086 1088
1087 { 1089 {
1088 StackZone zone(thread); 1090 StackZone zone(thread);
1089 HANDLESCOPE(thread); 1091 HANDLESCOPE(thread);
1090 Profile profile(isolate); 1092 Profile profile(isolate);
1091 AllocationFilter filter(isolate, one_byte_string_class.id()); 1093 AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
1092 profile.Build(thread, &filter, Profile::kNoTags); 1094 profile.Build(thread, &filter, Profile::kNoTags);
1093 // We should have no allocation samples. 1095 // We should have no allocation samples.
1094 EXPECT_EQ(0, profile.sample_count()); 1096 EXPECT_EQ(0, profile.sample_count());
1095 } 1097 }
1096 1098
1097 one_byte_string_class.SetTraceAllocation(true); 1099 one_byte_string_class.SetTraceAllocation(true);
1098 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1100 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1099 EXPECT_VALID(result); 1101 EXPECT_VALID(result);
1100 1102
1101 { 1103 {
1102 StackZone zone(thread); 1104 StackZone zone(thread);
1103 HANDLESCOPE(thread); 1105 HANDLESCOPE(thread);
1104 Profile profile(isolate); 1106 Profile profile(isolate);
1105 AllocationFilter filter(isolate, one_byte_string_class.id()); 1107 AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
1106 profile.Build(thread, &filter, Profile::kNoTags); 1108 profile.Build(thread, &filter, Profile::kNoTags);
1107 // We should still only have one allocation sample. 1109 // We should still only have one allocation sample.
1108 EXPECT_EQ(1, profile.sample_count()); 1110 EXPECT_EQ(1, profile.sample_count());
1109 ProfileTrieWalker walker(&profile); 1111 ProfileTrieWalker walker(&profile);
1110 1112
1111 walker.Reset(Profile::kExclusiveCode); 1113 walker.Reset(Profile::kExclusiveCode);
1112 EXPECT(walker.Down()); 1114 EXPECT(walker.Down());
1113 EXPECT_STREQ("String_concat", walker.CurrentName()); 1115 EXPECT_STREQ("String_concat", walker.CurrentName());
1114 EXPECT(walker.Down()); 1116 EXPECT(walker.Down());
1115 #if 1 1117 #if 1
1116 EXPECT_STREQ("_StringBase.+", walker.CurrentName()); 1118 EXPECT_STREQ("_StringBase.+", walker.CurrentName());
1117 EXPECT(walker.Down()); 1119 EXPECT(walker.Down());
1118 #endif 1120 #endif
1119 EXPECT_STREQ("foo", walker.CurrentName()); 1121 EXPECT_STREQ("foo", walker.CurrentName());
1120 EXPECT(!walker.Down()); 1122 EXPECT(!walker.Down());
1121 } 1123 }
1122 1124
1123 one_byte_string_class.SetTraceAllocation(false); 1125 one_byte_string_class.SetTraceAllocation(false);
1124 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1126 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1125 EXPECT_VALID(result); 1127 EXPECT_VALID(result);
1126 1128
1127 { 1129 {
1128 StackZone zone(thread); 1130 StackZone zone(thread);
1129 HANDLESCOPE(thread); 1131 HANDLESCOPE(thread);
1130 Profile profile(isolate); 1132 Profile profile(isolate);
1131 AllocationFilter filter(isolate, one_byte_string_class.id()); 1133 AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
1132 profile.Build(thread, &filter, Profile::kNoTags); 1134 profile.Build(thread, &filter, Profile::kNoTags);
1133 // We should still only have one allocation sample. 1135 // We should still only have one allocation sample.
1134 EXPECT_EQ(1, profile.sample_count()); 1136 EXPECT_EQ(1, profile.sample_count());
1135 } 1137 }
1136 1138
1137 one_byte_string_class.SetTraceAllocation(true); 1139 one_byte_string_class.SetTraceAllocation(true);
1138 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1140 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1139 EXPECT_VALID(result); 1141 EXPECT_VALID(result);
1140 1142
1141 { 1143 {
1142 StackZone zone(thread); 1144 StackZone zone(thread);
1143 HANDLESCOPE(thread); 1145 HANDLESCOPE(thread);
1144 Profile profile(isolate); 1146 Profile profile(isolate);
1145 AllocationFilter filter(isolate, one_byte_string_class.id()); 1147 AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
1146 profile.Build(thread, &filter, Profile::kNoTags); 1148 profile.Build(thread, &filter, Profile::kNoTags);
1147 // We should now have two allocation samples. 1149 // We should now have two allocation samples.
1148 EXPECT_EQ(2, profile.sample_count()); 1150 EXPECT_EQ(2, profile.sample_count());
1149 } 1151 }
1150 } 1152 }
1151 1153
1152 1154
1153 TEST_CASE(Profiler_StringInterpolation) { 1155 TEST_CASE(Profiler_StringInterpolation) {
1154 DisableNativeProfileScope dnps; 1156 DisableNativeProfileScope dnps;
1155 DisableBackgroundCompilationScope dbcs; 1157 DisableBackgroundCompilationScope dbcs;
(...skipping 12 matching lines...) Expand all
1168 NewString("a"), NewString("b"), 1170 NewString("a"), NewString("b"),
1169 }; 1171 };
1170 1172
1171 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1173 Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1172 EXPECT_VALID(result); 1174 EXPECT_VALID(result);
1173 1175
1174 { 1176 {
1175 StackZone zone(thread); 1177 StackZone zone(thread);
1176 HANDLESCOPE(thread); 1178 HANDLESCOPE(thread);
1177 Profile profile(isolate); 1179 Profile profile(isolate);
1178 AllocationFilter filter(isolate, one_byte_string_class.id()); 1180 AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
1179 profile.Build(thread, &filter, Profile::kNoTags); 1181 profile.Build(thread, &filter, Profile::kNoTags);
1180 // We should have no allocation samples. 1182 // We should have no allocation samples.
1181 EXPECT_EQ(0, profile.sample_count()); 1183 EXPECT_EQ(0, profile.sample_count());
1182 } 1184 }
1183 1185
1184 one_byte_string_class.SetTraceAllocation(true); 1186 one_byte_string_class.SetTraceAllocation(true);
1185 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1187 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1186 EXPECT_VALID(result); 1188 EXPECT_VALID(result);
1187 1189
1188 { 1190 {
1189 StackZone zone(thread); 1191 StackZone zone(thread);
1190 HANDLESCOPE(thread); 1192 HANDLESCOPE(thread);
1191 Profile profile(isolate); 1193 Profile profile(isolate);
1192 AllocationFilter filter(isolate, one_byte_string_class.id()); 1194 AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
1193 profile.Build(thread, &filter, Profile::kNoTags); 1195 profile.Build(thread, &filter, Profile::kNoTags);
1194 // We should still only have one allocation sample. 1196 // We should still only have one allocation sample.
1195 EXPECT_EQ(1, profile.sample_count()); 1197 EXPECT_EQ(1, profile.sample_count());
1196 ProfileTrieWalker walker(&profile); 1198 ProfileTrieWalker walker(&profile);
1197 1199
1198 walker.Reset(Profile::kExclusiveCode); 1200 walker.Reset(Profile::kExclusiveCode);
1199 EXPECT(walker.Down()); 1201 EXPECT(walker.Down());
1200 EXPECT_STREQ("OneByteString_allocate", walker.CurrentName()); 1202 EXPECT_STREQ("OneByteString_allocate", walker.CurrentName());
1201 EXPECT(walker.Down()); 1203 EXPECT(walker.Down());
1202 EXPECT_STREQ("_OneByteString._allocate", walker.CurrentName()); 1204 EXPECT_STREQ("_OneByteString._allocate", walker.CurrentName());
1203 EXPECT(walker.Down()); 1205 EXPECT(walker.Down());
1204 EXPECT_STREQ("_OneByteString._concatAll", walker.CurrentName()); 1206 EXPECT_STREQ("_OneByteString._concatAll", walker.CurrentName());
1205 EXPECT(walker.Down()); 1207 EXPECT(walker.Down());
1206 EXPECT_STREQ("_StringBase._interpolate", walker.CurrentName()); 1208 EXPECT_STREQ("_StringBase._interpolate", walker.CurrentName());
1207 EXPECT(walker.Down()); 1209 EXPECT(walker.Down());
1208 EXPECT_STREQ("foo", walker.CurrentName()); 1210 EXPECT_STREQ("foo", walker.CurrentName());
1209 EXPECT(!walker.Down()); 1211 EXPECT(!walker.Down());
1210 } 1212 }
1211 1213
1212 one_byte_string_class.SetTraceAllocation(false); 1214 one_byte_string_class.SetTraceAllocation(false);
1213 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1215 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1214 EXPECT_VALID(result); 1216 EXPECT_VALID(result);
1215 1217
1216 { 1218 {
1217 StackZone zone(thread); 1219 StackZone zone(thread);
1218 HANDLESCOPE(thread); 1220 HANDLESCOPE(thread);
1219 Profile profile(isolate); 1221 Profile profile(isolate);
1220 AllocationFilter filter(isolate, one_byte_string_class.id()); 1222 AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
1221 profile.Build(thread, &filter, Profile::kNoTags); 1223 profile.Build(thread, &filter, Profile::kNoTags);
1222 // We should still only have one allocation sample. 1224 // We should still only have one allocation sample.
1223 EXPECT_EQ(1, profile.sample_count()); 1225 EXPECT_EQ(1, profile.sample_count());
1224 } 1226 }
1225 1227
1226 one_byte_string_class.SetTraceAllocation(true); 1228 one_byte_string_class.SetTraceAllocation(true);
1227 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]); 1229 result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
1228 EXPECT_VALID(result); 1230 EXPECT_VALID(result);
1229 1231
1230 { 1232 {
1231 StackZone zone(thread); 1233 StackZone zone(thread);
1232 HANDLESCOPE(thread); 1234 HANDLESCOPE(thread);
1233 Profile profile(isolate); 1235 Profile profile(isolate);
1234 AllocationFilter filter(isolate, one_byte_string_class.id()); 1236 AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
1235 profile.Build(thread, &filter, Profile::kNoTags); 1237 profile.Build(thread, &filter, Profile::kNoTags);
1236 // We should now have two allocation samples. 1238 // We should now have two allocation samples.
1237 EXPECT_EQ(2, profile.sample_count()); 1239 EXPECT_EQ(2, profile.sample_count());
1238 } 1240 }
1239 } 1241 }
1240 1242
1241 1243
1242 TEST_CASE(Profiler_FunctionInline) { 1244 TEST_CASE(Profiler_FunctionInline) {
1243 DisableNativeProfileScope dnps; 1245 DisableNativeProfileScope dnps;
1244 DisableBackgroundCompilationScope dbcs; 1246 DisableBackgroundCompilationScope dbcs;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 result = Dart_Invoke(lib, NewString("mainA"), 0, NULL); 1286 result = Dart_Invoke(lib, NewString("mainA"), 0, NULL);
1285 EXPECT_VALID(result); 1287 EXPECT_VALID(result);
1286 // At this point B.boo should be optimized and inlined B.foo and B.choo. 1288 // At this point B.boo should be optimized and inlined B.foo and B.choo.
1287 1289
1288 { 1290 {
1289 Thread* thread = Thread::Current(); 1291 Thread* thread = Thread::Current();
1290 Isolate* isolate = thread->isolate(); 1292 Isolate* isolate = thread->isolate();
1291 StackZone zone(thread); 1293 StackZone zone(thread);
1292 HANDLESCOPE(thread); 1294 HANDLESCOPE(thread);
1293 Profile profile(isolate); 1295 Profile profile(isolate);
1294 AllocationFilter filter(isolate, class_a.id()); 1296 AllocationFilter filter(isolate->main_port(), class_a.id());
1295 profile.Build(thread, &filter, Profile::kNoTags); 1297 profile.Build(thread, &filter, Profile::kNoTags);
1296 // We should have no allocation samples. 1298 // We should have no allocation samples.
1297 EXPECT_EQ(0, profile.sample_count()); 1299 EXPECT_EQ(0, profile.sample_count());
1298 } 1300 }
1299 1301
1300 // Turn on allocation tracing for A. 1302 // Turn on allocation tracing for A.
1301 class_a.SetTraceAllocation(true); 1303 class_a.SetTraceAllocation(true);
1302 1304
1303 // Allocate 50,000 instances of A. 1305 // Allocate 50,000 instances of A.
1304 result = Dart_Invoke(lib, NewString("mainA"), 0, NULL); 1306 result = Dart_Invoke(lib, NewString("mainA"), 0, NULL);
1305 EXPECT_VALID(result); 1307 EXPECT_VALID(result);
1306 1308
1307 { 1309 {
1308 Thread* thread = Thread::Current(); 1310 Thread* thread = Thread::Current();
1309 Isolate* isolate = thread->isolate(); 1311 Isolate* isolate = thread->isolate();
1310 StackZone zone(thread); 1312 StackZone zone(thread);
1311 HANDLESCOPE(thread); 1313 HANDLESCOPE(thread);
1312 Profile profile(isolate); 1314 Profile profile(isolate);
1313 AllocationFilter filter(isolate, class_a.id()); 1315 AllocationFilter filter(isolate->main_port(), class_a.id());
1314 profile.Build(thread, &filter, Profile::kNoTags); 1316 profile.Build(thread, &filter, Profile::kNoTags);
1315 // We should have 50,000 allocation samples. 1317 // We should have 50,000 allocation samples.
1316 EXPECT_EQ(50000, profile.sample_count()); 1318 EXPECT_EQ(50000, profile.sample_count());
1317 ProfileTrieWalker walker(&profile); 1319 ProfileTrieWalker walker(&profile);
1318 // We have two code objects: mainA and B.boo. 1320 // We have two code objects: mainA and B.boo.
1319 walker.Reset(Profile::kExclusiveCode); 1321 walker.Reset(Profile::kExclusiveCode);
1320 EXPECT(walker.Down()); 1322 EXPECT(walker.Down());
1321 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 1323 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
1322 EXPECT(walker.Down()); 1324 EXPECT(walker.Down());
1323 EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); 1325 EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 EXPECT(!walker.Down()); 1423 EXPECT(!walker.Down());
1422 } 1424 }
1423 1425
1424 // Test code transition tags. 1426 // Test code transition tags.
1425 { 1427 {
1426 Thread* thread = Thread::Current(); 1428 Thread* thread = Thread::Current();
1427 Isolate* isolate = thread->isolate(); 1429 Isolate* isolate = thread->isolate();
1428 StackZone zone(thread); 1430 StackZone zone(thread);
1429 HANDLESCOPE(thread); 1431 HANDLESCOPE(thread);
1430 Profile profile(isolate); 1432 Profile profile(isolate);
1431 AllocationFilter filter(isolate, class_a.id()); 1433 AllocationFilter filter(isolate->main_port(), class_a.id());
1432 profile.Build(thread, &filter, Profile::kNoTags, 1434 profile.Build(thread, &filter, Profile::kNoTags,
1433 ProfilerService::kCodeTransitionTagsBit); 1435 ProfilerService::kCodeTransitionTagsBit);
1434 // We should have 50,000 allocation samples. 1436 // We should have 50,000 allocation samples.
1435 EXPECT_EQ(50000, profile.sample_count()); 1437 EXPECT_EQ(50000, profile.sample_count());
1436 ProfileTrieWalker walker(&profile); 1438 ProfileTrieWalker walker(&profile);
1437 // We have two code objects: mainA and B.boo. 1439 // We have two code objects: mainA and B.boo.
1438 walker.Reset(Profile::kExclusiveCode); 1440 walker.Reset(Profile::kExclusiveCode);
1439 EXPECT(walker.Down()); 1441 EXPECT(walker.Down());
1440 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 1442 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
1441 EXPECT(walker.Down()); 1443 EXPECT(walker.Down());
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 EXPECT(!func.is_inlinable()); 1596 EXPECT(!func.is_inlinable());
1595 func = GetFunction(root_library, "maybeAlloc"); 1597 func = GetFunction(root_library, "maybeAlloc");
1596 EXPECT(!func.is_inlinable()); 1598 EXPECT(!func.is_inlinable());
1597 1599
1598 { 1600 {
1599 Thread* thread = Thread::Current(); 1601 Thread* thread = Thread::Current();
1600 Isolate* isolate = thread->isolate(); 1602 Isolate* isolate = thread->isolate();
1601 StackZone zone(thread); 1603 StackZone zone(thread);
1602 HANDLESCOPE(thread); 1604 HANDLESCOPE(thread);
1603 Profile profile(isolate); 1605 Profile profile(isolate);
1604 AllocationFilter filter(isolate, class_a.id()); 1606 AllocationFilter filter(isolate->main_port(), class_a.id());
1605 profile.Build(thread, &filter, Profile::kNoTags); 1607 profile.Build(thread, &filter, Profile::kNoTags);
1606 // We should have no allocation samples. 1608 // We should have no allocation samples.
1607 EXPECT_EQ(0, profile.sample_count()); 1609 EXPECT_EQ(0, profile.sample_count());
1608 } 1610 }
1609 1611
1610 // Turn on allocation tracing for A. 1612 // Turn on allocation tracing for A.
1611 class_a.SetTraceAllocation(true); 1613 class_a.SetTraceAllocation(true);
1612 1614
1613 result = Dart_Invoke(lib, NewString("mainAlloc"), 0, NULL); 1615 result = Dart_Invoke(lib, NewString("mainAlloc"), 0, NULL);
1614 EXPECT_VALID(result); 1616 EXPECT_VALID(result);
1615 1617
1616 { 1618 {
1617 Thread* thread = Thread::Current(); 1619 Thread* thread = Thread::Current();
1618 Isolate* isolate = thread->isolate(); 1620 Isolate* isolate = thread->isolate();
1619 StackZone zone(thread); 1621 StackZone zone(thread);
1620 HANDLESCOPE(thread); 1622 HANDLESCOPE(thread);
1621 Profile profile(isolate); 1623 Profile profile(isolate);
1622 AllocationFilter filter(isolate, class_a.id()); 1624 AllocationFilter filter(isolate->main_port(), class_a.id());
1623 profile.Build(thread, &filter, Profile::kNoTags); 1625 profile.Build(thread, &filter, Profile::kNoTags);
1624 EXPECT_EQ(1, profile.sample_count()); 1626 EXPECT_EQ(1, profile.sample_count());
1625 ProfileTrieWalker walker(&profile); 1627 ProfileTrieWalker walker(&profile);
1626 1628
1627 // Inline expansion should show us the complete call chain: 1629 // Inline expansion should show us the complete call chain:
1628 walker.Reset(Profile::kExclusiveFunction); 1630 walker.Reset(Profile::kExclusiveFunction);
1629 EXPECT(walker.Down()); 1631 EXPECT(walker.Down());
1630 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 1632 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
1631 EXPECT(walker.Down()); 1633 EXPECT(walker.Down());
1632 EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); 1634 EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); 1713 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
1712 EXPECT_VALID(result); 1714 EXPECT_VALID(result);
1713 1715
1714 1716
1715 { 1717 {
1716 Thread* thread = Thread::Current(); 1718 Thread* thread = Thread::Current();
1717 Isolate* isolate = thread->isolate(); 1719 Isolate* isolate = thread->isolate();
1718 StackZone zone(thread); 1720 StackZone zone(thread);
1719 HANDLESCOPE(thread); 1721 HANDLESCOPE(thread);
1720 Profile profile(isolate); 1722 Profile profile(isolate);
1721 AllocationFilter filter(isolate, class_a.id()); 1723 AllocationFilter filter(isolate->main_port(), class_a.id());
1722 profile.Build(thread, &filter, Profile::kNoTags); 1724 profile.Build(thread, &filter, Profile::kNoTags);
1723 // We should have 1 allocation sample. 1725 // We should have 1 allocation sample.
1724 EXPECT_EQ(1, profile.sample_count()); 1726 EXPECT_EQ(1, profile.sample_count());
1725 ProfileTrieWalker walker(&profile); 1727 ProfileTrieWalker walker(&profile);
1726 1728
1727 walker.Reset(Profile::kExclusiveCode); 1729 walker.Reset(Profile::kExclusiveCode);
1728 // Move down from the root. 1730 // Move down from the root.
1729 EXPECT(walker.Down()); 1731 EXPECT(walker.Down());
1730 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 1732 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
1731 EXPECT(walker.Down()); 1733 EXPECT(walker.Down());
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1813 // Allocate one time. 1815 // Allocate one time.
1814 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 1816 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
1815 EXPECT_VALID(result); 1817 EXPECT_VALID(result);
1816 1818
1817 { 1819 {
1818 Thread* thread = Thread::Current(); 1820 Thread* thread = Thread::Current();
1819 Isolate* isolate = thread->isolate(); 1821 Isolate* isolate = thread->isolate();
1820 StackZone zone(thread); 1822 StackZone zone(thread);
1821 HANDLESCOPE(thread); 1823 HANDLESCOPE(thread);
1822 Profile profile(isolate); 1824 Profile profile(isolate);
1823 AllocationFilter filter(isolate, class_a.id()); 1825 AllocationFilter filter(isolate->main_port(), class_a.id());
1824 profile.Build(thread, &filter, Profile::kNoTags); 1826 profile.Build(thread, &filter, Profile::kNoTags);
1825 // We should have one allocation samples. 1827 // We should have one allocation samples.
1826 EXPECT_EQ(1, profile.sample_count()); 1828 EXPECT_EQ(1, profile.sample_count());
1827 ProfileTrieWalker walker(&profile); 1829 ProfileTrieWalker walker(&profile);
1828 1830
1829 // Exclusive function: B.boo -> main. 1831 // Exclusive function: B.boo -> main.
1830 walker.Reset(Profile::kExclusiveFunction); 1832 walker.Reset(Profile::kExclusiveFunction);
1831 // Move down from the root. 1833 // Move down from the root.
1832 EXPECT(walker.Down()); 1834 EXPECT(walker.Down());
1833 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 1835 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 // Still optimized. 1909 // Still optimized.
1908 const Code& code = Code::Handle(main.CurrentCode()); 1910 const Code& code = Code::Handle(main.CurrentCode());
1909 EXPECT(code.is_optimized()); 1911 EXPECT(code.is_optimized());
1910 1912
1911 { 1913 {
1912 Thread* thread = Thread::Current(); 1914 Thread* thread = Thread::Current();
1913 Isolate* isolate = thread->isolate(); 1915 Isolate* isolate = thread->isolate();
1914 StackZone zone(thread); 1916 StackZone zone(thread);
1915 HANDLESCOPE(thread); 1917 HANDLESCOPE(thread);
1916 Profile profile(isolate); 1918 Profile profile(isolate);
1917 AllocationFilter filter(isolate, class_a.id()); 1919 AllocationFilter filter(isolate->main_port(), class_a.id());
1918 profile.Build(thread, &filter, Profile::kNoTags); 1920 profile.Build(thread, &filter, Profile::kNoTags);
1919 // We should have one allocation samples. 1921 // We should have one allocation samples.
1920 EXPECT_EQ(1, profile.sample_count()); 1922 EXPECT_EQ(1, profile.sample_count());
1921 ProfileTrieWalker walker(&profile); 1923 ProfileTrieWalker walker(&profile);
1922 1924
1923 // Exclusive function: B.boo -> main. 1925 // Exclusive function: B.boo -> main.
1924 walker.Reset(Profile::kExclusiveFunction); 1926 walker.Reset(Profile::kExclusiveFunction);
1925 // Move down from the root. 1927 // Move down from the root.
1926 EXPECT(walker.Down()); 1928 EXPECT(walker.Down());
1927 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 1929 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 // Allocate one time. 1996 // Allocate one time.
1995 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 1997 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
1996 EXPECT_VALID(result); 1998 EXPECT_VALID(result);
1997 1999
1998 { 2000 {
1999 Thread* thread = Thread::Current(); 2001 Thread* thread = Thread::Current();
2000 Isolate* isolate = thread->isolate(); 2002 Isolate* isolate = thread->isolate();
2001 StackZone zone(thread); 2003 StackZone zone(thread);
2002 HANDLESCOPE(thread); 2004 HANDLESCOPE(thread);
2003 Profile profile(isolate); 2005 Profile profile(isolate);
2004 AllocationFilter filter(isolate, class_a.id()); 2006 AllocationFilter filter(isolate->main_port(), class_a.id());
2005 profile.Build(thread, &filter, Profile::kNoTags); 2007 profile.Build(thread, &filter, Profile::kNoTags);
2006 // We should have one allocation samples. 2008 // We should have one allocation samples.
2007 EXPECT_EQ(1, profile.sample_count()); 2009 EXPECT_EQ(1, profile.sample_count());
2008 ProfileTrieWalker walker(&profile); 2010 ProfileTrieWalker walker(&profile);
2009 2011
2010 // Exclusive function: B.boo -> main. 2012 // Exclusive function: B.boo -> main.
2011 walker.Reset(Profile::kExclusiveFunction); 2013 walker.Reset(Profile::kExclusiveFunction);
2012 // Move down from the root. 2014 // Move down from the root.
2013 EXPECT(walker.Down()); 2015 EXPECT(walker.Down());
2014 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 2016 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 // Still optimized. 2121 // Still optimized.
2120 const Code& code = Code::Handle(main.CurrentCode()); 2122 const Code& code = Code::Handle(main.CurrentCode());
2121 EXPECT(code.is_optimized()); 2123 EXPECT(code.is_optimized());
2122 2124
2123 { 2125 {
2124 Thread* thread = Thread::Current(); 2126 Thread* thread = Thread::Current();
2125 Isolate* isolate = thread->isolate(); 2127 Isolate* isolate = thread->isolate();
2126 StackZone zone(thread); 2128 StackZone zone(thread);
2127 HANDLESCOPE(thread); 2129 HANDLESCOPE(thread);
2128 Profile profile(isolate); 2130 Profile profile(isolate);
2129 AllocationFilter filter(isolate, class_a.id()); 2131 AllocationFilter filter(isolate->main_port(), class_a.id());
2130 profile.Build(thread, &filter, Profile::kNoTags); 2132 profile.Build(thread, &filter, Profile::kNoTags);
2131 // We should have one allocation samples. 2133 // We should have one allocation samples.
2132 EXPECT_EQ(1, profile.sample_count()); 2134 EXPECT_EQ(1, profile.sample_count());
2133 ProfileTrieWalker walker(&profile); 2135 ProfileTrieWalker walker(&profile);
2134 2136
2135 // Exclusive function: B.boo -> main. 2137 // Exclusive function: B.boo -> main.
2136 walker.Reset(Profile::kExclusiveFunction); 2138 walker.Reset(Profile::kExclusiveFunction);
2137 // Move down from the root. 2139 // Move down from the root.
2138 EXPECT(walker.Down()); 2140 EXPECT(walker.Down());
2139 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 2141 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2227 // Allocate one time. 2229 // Allocate one time.
2228 result = Dart_Invoke(lib, NewString("main"), 0, NULL); 2230 result = Dart_Invoke(lib, NewString("main"), 0, NULL);
2229 EXPECT_VALID(result); 2231 EXPECT_VALID(result);
2230 2232
2231 { 2233 {
2232 Thread* thread = Thread::Current(); 2234 Thread* thread = Thread::Current();
2233 Isolate* isolate = thread->isolate(); 2235 Isolate* isolate = thread->isolate();
2234 StackZone zone(thread); 2236 StackZone zone(thread);
2235 HANDLESCOPE(thread); 2237 HANDLESCOPE(thread);
2236 Profile profile(isolate); 2238 Profile profile(isolate);
2237 AllocationFilter filter(isolate, class_a.id()); 2239 AllocationFilter filter(isolate->main_port(), class_a.id());
2238 profile.Build(thread, &filter, Profile::kNoTags); 2240 profile.Build(thread, &filter, Profile::kNoTags);
2239 // We should have one allocation samples. 2241 // We should have one allocation samples.
2240 EXPECT_EQ(1, profile.sample_count()); 2242 EXPECT_EQ(1, profile.sample_count());
2241 ProfileTrieWalker walker(&profile); 2243 ProfileTrieWalker walker(&profile);
2242 2244
2243 // Exclusive function: B.boo -> main. 2245 // Exclusive function: B.boo -> main.
2244 walker.Reset(Profile::kExclusiveFunction); 2246 walker.Reset(Profile::kExclusiveFunction);
2245 // Move down from the root. 2247 // Move down from the root.
2246 EXPECT(walker.Down()); 2248 EXPECT(walker.Down());
2247 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 2249 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2361 // Still optimized. 2363 // Still optimized.
2362 const Code& code = Code::Handle(main.CurrentCode()); 2364 const Code& code = Code::Handle(main.CurrentCode());
2363 EXPECT(code.is_optimized()); 2365 EXPECT(code.is_optimized());
2364 2366
2365 { 2367 {
2366 Thread* thread = Thread::Current(); 2368 Thread* thread = Thread::Current();
2367 Isolate* isolate = thread->isolate(); 2369 Isolate* isolate = thread->isolate();
2368 StackZone zone(thread); 2370 StackZone zone(thread);
2369 HANDLESCOPE(thread); 2371 HANDLESCOPE(thread);
2370 Profile profile(isolate); 2372 Profile profile(isolate);
2371 AllocationFilter filter(isolate, class_a.id()); 2373 AllocationFilter filter(isolate->main_port(), class_a.id());
2372 profile.Build(thread, &filter, Profile::kNoTags); 2374 profile.Build(thread, &filter, Profile::kNoTags);
2373 // We should have one allocation samples. 2375 // We should have one allocation samples.
2374 EXPECT_EQ(1, profile.sample_count()); 2376 EXPECT_EQ(1, profile.sample_count());
2375 ProfileTrieWalker walker(&profile); 2377 ProfileTrieWalker walker(&profile);
2376 2378
2377 // Exclusive function: B.boo -> main. 2379 // Exclusive function: B.boo -> main.
2378 walker.Reset(Profile::kExclusiveFunction); 2380 walker.Reset(Profile::kExclusiveFunction);
2379 // Move down from the root. 2381 // Move down from the root.
2380 EXPECT(walker.Down()); 2382 EXPECT(walker.Down());
2381 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName()); 2383 EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2420 EXPECT(!walker.Down()); 2422 EXPECT(!walker.Down());
2421 } 2423 }
2422 } 2424 }
2423 2425
2424 2426
2425 static void InsertFakeSample(SampleBuffer* sample_buffer, uword* pc_offsets) { 2427 static void InsertFakeSample(SampleBuffer* sample_buffer, uword* pc_offsets) {
2426 ASSERT(sample_buffer != NULL); 2428 ASSERT(sample_buffer != NULL);
2427 Isolate* isolate = Isolate::Current(); 2429 Isolate* isolate = Isolate::Current();
2428 Sample* sample = sample_buffer->ReserveSample(); 2430 Sample* sample = sample_buffer->ReserveSample();
2429 ASSERT(sample != NULL); 2431 ASSERT(sample != NULL);
2430 sample->Init(isolate, OS::GetCurrentMonotonicMicros(), 2432 sample->Init(isolate->main_port(), OS::GetCurrentMonotonicMicros(),
2431 OSThread::Current()->trace_id()); 2433 OSThread::Current()->trace_id());
2432 sample->set_thread_task(Thread::kMutatorTask); 2434 sample->set_thread_task(Thread::kMutatorTask);
2433 2435
2434 intptr_t i = 0; 2436 intptr_t i = 0;
2435 while (pc_offsets[i] != 0) { 2437 while (pc_offsets[i] != 0) {
2436 // When we collect a real stack trace, all PCs collected aside from the 2438 // When we collect a real stack trace, all PCs collected aside from the
2437 // executing one (i == 0) are actually return addresses. Return addresses 2439 // executing one (i == 0) are actually return addresses. Return addresses
2438 // are one byte beyond the call instruction that is executing. The profiler 2440 // are one byte beyond the call instruction that is executing. The profiler
2439 // accounts for this and subtracts one from these addresses when querying 2441 // accounts for this and subtracts one from these addresses when querying
2440 // inline and token position ranges. To be consistent with real stack 2442 // inline and token position ranges. To be consistent with real stack
(...skipping 17 matching lines...) Expand all
2458 if (token_positions[0] == tp) { 2460 if (token_positions[0] == tp) {
2459 return code.PayloadStart() + pc_offset; 2461 return code.PayloadStart() + pc_offset;
2460 } 2462 }
2461 } 2463 }
2462 2464
2463 return 0; 2465 return 0;
2464 } 2466 }
2465 2467
2466 2468
2467 TEST_CASE(Profiler_GetSourceReport) { 2469 TEST_CASE(Profiler_GetSourceReport) {
2470 // The malloc hooks change the original behaviour of this test, so disable
zra 2017/02/16 21:45:27 It might be worthwhile to add some more detail to
bkonyi 2017/02/16 22:55:06 Apparently this test works now with MallocHooks en
2471 // them.
2472 bool reinit_hooks = false;
2473 if (MallocHooks::Active()) {
2474 MallocHooks::TearDown();
2475 reinit_hooks = true;
2476 }
2477
2468 const char* kScript = 2478 const char* kScript =
2469 "doWork(i) => i * i;\n" 2479 "doWork(i) => i * i;\n"
2470 "main() {\n" 2480 "main() {\n"
2471 " var sum = 0;\n" 2481 " var sum = 0;\n"
2472 " for (var i = 0; i < 100; i++) {\n" 2482 " for (var i = 0; i < 100; i++) {\n"
2473 " sum += doWork(i);\n" 2483 " sum += doWork(i);\n"
2474 " }\n" 2484 " }\n"
2475 " return sum;\n" 2485 " return sum;\n"
2476 "}\n"; 2486 "}\n";
2477 2487
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,2]", js.ToCString()); 2598 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,2]", js.ToCString());
2589 // Verify inclusive ticks in do_work. 2599 // Verify inclusive ticks in do_work.
2590 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString()); 2600 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
2591 2601
2592 // Verify positions in main. 2602 // Verify positions in main.
2593 EXPECT_SUBSTRING("\"positions\":[\"TempMove\",39]", js.ToCString()); 2603 EXPECT_SUBSTRING("\"positions\":[\"TempMove\",39]", js.ToCString());
2594 // Verify exclusive ticks in main. 2604 // Verify exclusive ticks in main.
2595 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,0]", js.ToCString()); 2605 EXPECT_SUBSTRING("\"exclusiveTicks\":[1,0]", js.ToCString());
2596 // Verify inclusive ticks in main. 2606 // Verify inclusive ticks in main.
2597 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString()); 2607 EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
2608
2609 if (reinit_hooks) {
2610 MallocHooks::InitOnce();
2611 }
2598 } 2612 }
2599 2613
2600 #endif // !PRODUCT 2614 #endif // !PRODUCT
2601 2615
2602 } // namespace dart 2616 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698