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

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

Issue 168833005: Add callers and callees to profiler output (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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/utils.h" 5 #include "platform/utils.h"
6 6
7 #include "vm/allocation.h" 7 #include "vm/allocation.h"
8 #include "vm/atomic.h" 8 #include "vm/atomic.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 if (!FLAG_profile) { 155 if (!FLAG_profile) {
156 return; 156 return;
157 } 157 }
158 ASSERT(initialized_); 158 ASSERT(initialized_);
159 ThreadInterrupter::Unregister(); 159 ThreadInterrupter::Unregister();
160 } 160 }
161 161
162 162
163 struct AddressEntry { 163 struct AddressEntry {
164 uword pc; 164 uword pc;
165 intptr_t ticks; 165 intptr_t exclusive_ticks;
166 intptr_t inclusive_ticks;
167
168 void tick(bool exclusive) {
169 if (exclusive) {
170 exclusive_ticks++;
171 } else {
172 inclusive_ticks++;
173 }
174 }
175 };
176
177 struct CallEntry {
178 intptr_t code_table_index;
179 intptr_t count;
166 }; 180 };
167 181
168 typedef bool (*RegionCompare)(uword pc, uword region_start, uword region_end); 182 typedef bool (*RegionCompare)(uword pc, uword region_start, uword region_end);
169 183
170 // A region of code. Each region is a kind of code (Dart, Collected, or Native). 184 // A region of code. Each region is a kind of code (Dart, Collected, or Native).
171 class CodeRegion : public ZoneAllocated { 185 class CodeRegion : public ZoneAllocated {
172 public: 186 public:
173 enum Kind { 187 enum Kind {
174 kDartCode, 188 kDartCode,
175 kCollectedCode, 189 kCollectedCode,
176 kNativeCode 190 kNativeCode
177 }; 191 };
178 192
179 CodeRegion(Kind kind, uword start, uword end) : 193 CodeRegion(Kind kind, uword start, uword end) :
180 kind_(kind), 194 kind_(kind),
181 start_(start), 195 start_(start),
182 end_(end), 196 end_(end),
183 inclusive_ticks_(0), 197 inclusive_ticks_(0),
184 exclusive_ticks_(0), 198 exclusive_ticks_(0),
185 name_(NULL), 199 name_(NULL),
186 address_table_(new ZoneGrowableArray<AddressEntry>()) { 200 address_table_(new ZoneGrowableArray<AddressEntry>()),
201 callers_table_(new ZoneGrowableArray<CallEntry>()),
202 callees_table_(new ZoneGrowableArray<CallEntry>()) {
187 ASSERT(start_ < end_); 203 ASSERT(start_ < end_);
188 } 204 }
189 205
190 ~CodeRegion() { 206 ~CodeRegion() {
191 } 207 }
192 208
193 uword start() const { return start_; } 209 uword start() const { return start_; }
194 void set_start(uword start) { 210 void set_start(uword start) {
195 start_ = start; 211 start_ = start;
196 } 212 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 return "Dart"; 267 return "Dart";
252 case kCollectedCode: 268 case kCollectedCode:
253 return "Collected"; 269 return "Collected";
254 case kNativeCode: 270 case kNativeCode:
255 return "Native"; 271 return "Native";
256 } 272 }
257 UNREACHABLE(); 273 UNREACHABLE();
258 return NULL; 274 return NULL;
259 } 275 }
260 276
261 void AddTick(bool exclusive) {
262 if (exclusive) {
263 exclusive_ticks_++;
264 } else {
265 inclusive_ticks_++;
266 }
267 }
268
269 void DebugPrint() const { 277 void DebugPrint() const {
270 printf("%s [%" Px ", %" Px ") %s\n", KindToCString(kind_), start(), end(), 278 printf("%s [%" Px ", %" Px ") %s\n", KindToCString(kind_), start(), end(),
271 name_); 279 name_);
272 } 280 }
273 281
274 void AddTickAtAddress(uword pc) { 282 void AddTickAtAddress(uword pc, bool exclusive, intptr_t serial) {
283 // Assert that exclusive ticks are never passed a valid serial number.
284 ASSERT((exclusive && (serial == -1)) || (!exclusive && (serial != -1)));
285 if (!exclusive && (inclusive_tick_serial_ == serial)) {
286 // We've already given this code object an inclusive tick for this sample.
287 return;
288 }
289 // Tick the code object.
290 if (exclusive) {
291 exclusive_ticks_++;
292 } else {
293 // Mark the last serial we ticked the inclusive count.
294 inclusive_tick_serial_ = serial;
295 inclusive_ticks_++;
296 }
297 // Tick the address entry.
275 const intptr_t length = address_table_->length(); 298 const intptr_t length = address_table_->length();
276 intptr_t i = 0; 299 intptr_t i = 0;
277 for (; i < length; i++) { 300 for (; i < length; i++) {
278 AddressEntry& entry = (*address_table_)[i]; 301 AddressEntry& entry = (*address_table_)[i];
279 if (entry.pc == pc) { 302 if (entry.pc == pc) {
280 entry.ticks++; 303 entry.tick(exclusive);
281 return; 304 return;
282 } 305 }
283 if (entry.pc > pc) { 306 if (entry.pc > pc) {
284 break; 307 break;
285 } 308 }
286 } 309 }
287 AddressEntry entry; 310 AddressEntry entry;
288 entry.pc = pc; 311 entry.pc = pc;
289 entry.ticks = 1; 312 entry.tick(exclusive);
290 if (i < length) { 313 if (i < length) {
291 // Insert at i. 314 // Insert at i.
292 address_table_->InsertAt(i, entry); 315 address_table_->InsertAt(i, entry);
293 } else { 316 } else {
294 // Add to end. 317 // Add to end.
295 address_table_->Add(entry); 318 address_table_->Add(entry);
296 } 319 }
297 } 320 }
298 321
322 void AddCaller(intptr_t index) {
323 AddCallEntry(callers_table_, index);
324 }
325
326 void AddCallee(intptr_t index) {
327 AddCallEntry(callees_table_, index);
328 }
299 329
300 void PrintToJSONArray(JSONArray* events, bool full) { 330 void PrintToJSONArray(JSONArray* events, bool full) {
301 JSONObject obj(events); 331 JSONObject obj(events);
302 obj.AddProperty("type", "ProfileCode"); 332 obj.AddProperty("type", "ProfileCode");
303 obj.AddProperty("kind", KindToCString(kind())); 333 obj.AddProperty("kind", KindToCString(kind()));
304 obj.AddPropertyF("inclusive_ticks", "%" Pd "", inclusive_ticks()); 334 obj.AddPropertyF("inclusive_ticks", "%" Pd "", inclusive_ticks());
305 obj.AddPropertyF("exclusive_ticks", "%" Pd "", exclusive_ticks()); 335 obj.AddPropertyF("exclusive_ticks", "%" Pd "", exclusive_ticks());
306 if (kind() == kDartCode) { 336 if (kind() == kDartCode) {
307 // Look up code in Dart heap. 337 // Look up code in Dart heap.
308 Code& code = Code::Handle(Code::LookupCode(start())); 338 Code& code = Code::Handle(Code::LookupCode(start()));
(...skipping 24 matching lines...) Expand all
333 } 363 }
334 obj.AddPropertyF("start", "%" Px "", start()); 364 obj.AddPropertyF("start", "%" Px "", start());
335 obj.AddPropertyF("end", "%" Px "", end()); 365 obj.AddPropertyF("end", "%" Px "", end());
336 obj.AddProperty("name", name()); 366 obj.AddProperty("name", name());
337 } 367 }
338 { 368 {
339 JSONArray ticks(&obj, "ticks"); 369 JSONArray ticks(&obj, "ticks");
340 for (intptr_t i = 0; i < address_table_->length(); i++) { 370 for (intptr_t i = 0; i < address_table_->length(); i++) {
341 const AddressEntry& entry = (*address_table_)[i]; 371 const AddressEntry& entry = (*address_table_)[i];
342 ticks.AddValueF("%" Px "", entry.pc); 372 ticks.AddValueF("%" Px "", entry.pc);
343 ticks.AddValueF("%" Pd "", entry.ticks); 373 ticks.AddValueF("%" Pd "", entry.exclusive_ticks);
374 ticks.AddValueF("%" Pd "", entry.inclusive_ticks);
375 }
376 }
377 {
378 JSONArray callers(&obj, "callers");
379 for (intptr_t i = 0; i < callers_table_->length(); i++) {
380 const CallEntry& entry = (*callers_table_)[i];
381 callers.AddValueF("%" Pd "", entry.code_table_index);
382 callers.AddValueF("%" Pd "", entry.count);
383 }
384 }
385 {
386 JSONArray callees(&obj, "callees");
387 for (intptr_t i = 0; i < callees_table_->length(); i++) {
388 const CallEntry& entry = (*callees_table_)[i];
389 callees.AddValueF("%" Pd "", entry.code_table_index);
390 callees.AddValueF("%" Pd "", entry.count);
344 } 391 }
345 } 392 }
346 } 393 }
347 394
348 private: 395 private:
396 void AddCallEntry(ZoneGrowableArray<CallEntry>* table, intptr_t index) {
397 const intptr_t length = table->length();
398 intptr_t i = 0;
399 for (; i < length; i++) {
400 CallEntry& entry = (*table)[i];
401 if (entry.code_table_index == index) {
402 entry.count++;
403 return;
404 }
405 if (entry.code_table_index > index) {
406 break;
407 }
408 }
409 CallEntry entry;
410 entry.code_table_index = index;
411 entry.count = 1;
412 if (i < length) {
413 table->InsertAt(i, entry);
414 } else {
415 table->Add(entry);
416 }
417 }
418
349 void GenerateAndSetSymbolName(const char* prefix) { 419 void GenerateAndSetSymbolName(const char* prefix) {
350 const intptr_t kBuffSize = 512; 420 const intptr_t kBuffSize = 512;
351 char buff[kBuffSize]; 421 char buff[kBuffSize];
352 OS::SNPrint(&buff[0], kBuffSize-1, "%s [%" Px ", %" Px ")", 422 OS::SNPrint(&buff[0], kBuffSize-1, "%s [%" Px ", %" Px ")",
353 prefix, start(), end()); 423 prefix, start(), end());
354 SetName(buff); 424 SetName(buff);
355 } 425 }
356 426
357 Kind kind_; 427 Kind kind_;
358 uword start_; 428 uword start_;
359 uword end_; 429 uword end_;
360 intptr_t inclusive_ticks_; 430 intptr_t inclusive_ticks_;
361 intptr_t exclusive_ticks_; 431 intptr_t exclusive_ticks_;
432 intptr_t inclusive_tick_serial_;
362 const char* name_; 433 const char* name_;
363 ZoneGrowableArray<AddressEntry>* address_table_; 434 ZoneGrowableArray<AddressEntry>* address_table_;
364 435 ZoneGrowableArray<CallEntry>* callers_table_;
436 ZoneGrowableArray<CallEntry>* callees_table_;
365 DISALLOW_COPY_AND_ASSIGN(CodeRegion); 437 DISALLOW_COPY_AND_ASSIGN(CodeRegion);
366 }; 438 };
367 439
368 440
369 class ScopeStopwatch : public ValueObject { 441 class ScopeStopwatch : public ValueObject {
370 public: 442 public:
371 explicit ScopeStopwatch(const char* name) : name_(name) { 443 explicit ScopeStopwatch(const char* name) : name_(name) {
372 start_ = OS::GetCurrentTimeMillis(); 444 start_ = OS::GetCurrentTimeMillis();
373 } 445 }
374 446
(...skipping 21 matching lines...) Expand all
396 class ProfilerCodeRegionTable : public ValueObject { 468 class ProfilerCodeRegionTable : public ValueObject {
397 public: 469 public:
398 explicit ProfilerCodeRegionTable(Isolate* isolate) : 470 explicit ProfilerCodeRegionTable(Isolate* isolate) :
399 heap_(isolate->heap()), 471 heap_(isolate->heap()),
400 code_region_table_(new ZoneGrowableArray<CodeRegion*>(64)) { 472 code_region_table_(new ZoneGrowableArray<CodeRegion*>(64)) {
401 } 473 }
402 474
403 ~ProfilerCodeRegionTable() { 475 ~ProfilerCodeRegionTable() {
404 } 476 }
405 477
406 void AddTick(uword pc, bool exclusive, bool tick_address) { 478 void AddTick(uword pc, bool exclusive, intptr_t serial) {
407 intptr_t index = FindIndex(pc); 479 intptr_t index = FindIndex(pc);
408 if (index < 0) { 480 if (index < 0) {
409 CodeRegion* code_region = CreateCodeRegion(pc); 481 CodeRegion* code_region = CreateCodeRegion(pc);
410 ASSERT(code_region != NULL); 482 ASSERT(code_region != NULL);
411 index = InsertCodeRegion(code_region); 483 index = InsertCodeRegion(code_region);
412 } 484 }
413 ASSERT(index >= 0); 485 ASSERT(index >= 0);
414 ASSERT(index < code_region_table_->length()); 486 ASSERT(index < code_region_table_->length());
415 (*code_region_table_)[index]->AddTick(exclusive); 487
416 if (tick_address) { 488 // Update code object counters.
417 (*code_region_table_)[index]->AddTickAtAddress(pc); 489 (*code_region_table_)[index]->AddTickAtAddress(pc, exclusive, serial);
418 }
419 } 490 }
420 491
421 intptr_t Length() const { return code_region_table_->length(); } 492 intptr_t Length() const { return code_region_table_->length(); }
422 493
423 CodeRegion* At(intptr_t idx) { 494 CodeRegion* At(intptr_t idx) {
424 return (*code_region_table_)[idx]; 495 return (*code_region_table_)[idx];
425 } 496 }
426 497
498 intptr_t FindIndex(uword pc) const {
499 intptr_t index = FindRegionIndex(pc, &CompareLowerBound);
500 const CodeRegion* code_region = NULL;
501 if (index == code_region_table_->length()) {
502 // Not present.
503 return -1;
504 }
505 code_region = (*code_region_table_)[index];
506 if (code_region->contains(pc)) {
507 // Found at index.
508 return index;
509 }
510 return -1;
511 }
512
427 #if defined(DEBUG) 513 #if defined(DEBUG)
428 void Verify() { 514 void Verify() {
429 VerifyOrder(); 515 VerifyOrder();
430 VerifyOverlap(); 516 VerifyOverlap();
431 } 517 }
432 #endif 518 #endif
433 519
434 private: 520 private:
435 intptr_t FindRegionIndex(uword pc, RegionCompare comparator) { 521 intptr_t FindRegionIndex(uword pc, RegionCompare comparator) const {
436 ASSERT(comparator != NULL); 522 ASSERT(comparator != NULL);
437 intptr_t count = code_region_table_->length(); 523 intptr_t count = code_region_table_->length();
438 intptr_t first = 0; 524 intptr_t first = 0;
439 while (count > 0) { 525 while (count > 0) {
440 intptr_t it = first; 526 intptr_t it = first;
441 intptr_t step = count / 2; 527 intptr_t step = count / 2;
442 it += step; 528 it += step;
443 const CodeRegion* code_region = (*code_region_table_)[it]; 529 const CodeRegion* code_region = (*code_region_table_)[it];
444 if (comparator(pc, code_region->start(), code_region->end())) { 530 if (comparator(pc, code_region->start(), code_region->end())) {
445 first = ++it; 531 first = ++it;
446 count -= (step + 1); 532 count -= (step + 1);
447 } else { 533 } else {
448 count = step; 534 count = step;
449 } 535 }
450 } 536 }
451 return first; 537 return first;
452 } 538 }
453 539
454 static bool CompareUpperBound(uword pc, uword start, uword end) { 540 static bool CompareUpperBound(uword pc, uword start, uword end) {
455 return pc >= end; 541 return pc >= end;
456 } 542 }
457 543
458 static bool CompareLowerBound(uword pc, uword start, uword end) { 544 static bool CompareLowerBound(uword pc, uword start, uword end) {
459 return end <= pc; 545 return end <= pc;
460 } 546 }
461 547
462 intptr_t FindIndex(uword pc) {
463 intptr_t index = FindRegionIndex(pc, &CompareLowerBound);
464 const CodeRegion* code_region = NULL;
465 if (index == code_region_table_->length()) {
466 // Not present.
467 return -1;
468 }
469 code_region = (*code_region_table_)[index];
470 if (code_region->contains(pc)) {
471 // Found at index.
472 return index;
473 }
474 return -1;
475 }
476
477 CodeRegion* CreateCodeRegion(uword pc) { 548 CodeRegion* CreateCodeRegion(uword pc) {
478 Code& code = Code::Handle(Code::LookupCode(pc)); 549 Code& code = Code::Handle(Code::LookupCode(pc));
479 if (!code.IsNull()) { 550 if (!code.IsNull()) {
480 return new CodeRegion(CodeRegion::kDartCode, code.EntryPoint(), 551 return new CodeRegion(CodeRegion::kDartCode, code.EntryPoint(),
481 code.EntryPoint() + code.Size()); 552 code.EntryPoint() + code.Size());
482 } 553 }
483 if (heap_->CodeContains(pc)) { 554 if (heap_->CodeContains(pc)) {
484 const intptr_t kDartCodeAlignment = 0x10; 555 const intptr_t kDartCodeAlignment = 0x10;
485 const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1); 556 const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
486 return new CodeRegion(CodeRegion::kCollectedCode, pc, 557 return new CodeRegion(CodeRegion::kCollectedCode, pc,
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 671
601 class CodeRegionTableBuilder : public SampleVisitor { 672 class CodeRegionTableBuilder : public SampleVisitor {
602 public: 673 public:
603 CodeRegionTableBuilder(Isolate* isolate, 674 CodeRegionTableBuilder(Isolate* isolate,
604 ProfilerCodeRegionTable* code_region_table) 675 ProfilerCodeRegionTable* code_region_table)
605 : SampleVisitor(isolate), code_region_table_(code_region_table) { 676 : SampleVisitor(isolate), code_region_table_(code_region_table) {
606 frames_ = 0; 677 frames_ = 0;
607 } 678 }
608 679
609 void VisitSample(Sample* sample) { 680 void VisitSample(Sample* sample) {
610 code_region_table_->AddTick(sample->At(0), true, false); 681 // Give the bottom frame an exclusive tick.
611 // Give all frames an inclusive tick and tick the address. 682 code_region_table_->AddTick(sample->At(0), true, -1);
683 // Give all frames (including the bottom) an inclusive tick.
612 for (intptr_t i = 0; i < FLAG_profile_depth; i++) { 684 for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
613 if (sample->At(i) == 0) { 685 if (sample->At(i) == 0) {
614 break; 686 break;
615 } 687 }
616 frames_++; 688 frames_++;
617 code_region_table_->AddTick(sample->At(i), false, true); 689 code_region_table_->AddTick(sample->At(i), false, visited());
618 } 690 }
619 } 691 }
620 692
621 intptr_t frames() const { return frames_; } 693 intptr_t frames() const { return frames_; }
694
622 private: 695 private:
623 intptr_t frames_; 696 intptr_t frames_;
624 ProfilerCodeRegionTable* code_region_table_; 697 ProfilerCodeRegionTable* code_region_table_;
625 }; 698 };
626 699
627 700
701 class CodeRegionTableCallersBuilder : public SampleVisitor {
702 public:
703 CodeRegionTableCallersBuilder(Isolate* isolate,
704 ProfilerCodeRegionTable* code_region_table)
705 : SampleVisitor(isolate), code_region_table_(code_region_table) {
706 ASSERT(code_region_table_ != NULL);
707 }
708
709 void VisitSample(Sample* sample) {
710 intptr_t current_index = code_region_table_->FindIndex(sample->At(0));
711 ASSERT(current_index != -1);
712 CodeRegion* current = code_region_table_->At(current_index);
713 intptr_t caller_index = -1;
714 CodeRegion* caller = NULL;
715 intptr_t callee_index = -1;
716 CodeRegion* callee = NULL;
717 for (intptr_t i = 1; i < FLAG_profile_depth; i++) {
718 if (sample->At(i) == 0) {
719 break;
720 }
721 caller_index = code_region_table_->FindIndex(sample->At(i));
722 ASSERT(caller_index != -1);
723 caller = code_region_table_->At(caller_index);
724 current->AddCaller(caller_index);
725 if (callee != NULL) {
726 current->AddCallee(callee_index);
727 }
728 // Move cursors.
729 callee_index = current_index;
730 callee = current;
731 current_index = caller_index;
732 current = caller;
733 }
734 }
735
736 private:
737 ProfilerCodeRegionTable* code_region_table_;
738 };
739
628 void Profiler::PrintToJSONStream(Isolate* isolate, JSONStream* stream, 740 void Profiler::PrintToJSONStream(Isolate* isolate, JSONStream* stream,
629 bool full) { 741 bool full) {
630 ASSERT(isolate == Isolate::Current()); 742 ASSERT(isolate == Isolate::Current());
631 // Disable profile interrupts while processing the buffer. 743 // Disable profile interrupts while processing the buffer.
632 EndExecution(isolate); 744 EndExecution(isolate);
633 MutexLocker profiler_data_lock(isolate->profiler_data_mutex()); 745 MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
634 IsolateProfilerData* profiler_data = isolate->profiler_data(); 746 IsolateProfilerData* profiler_data = isolate->profiler_data();
635 if (profiler_data == NULL) { 747 if (profiler_data == NULL) {
636 JSONObject error(stream); 748 JSONObject error(stream);
637 error.AddProperty("type", "Error"); 749 error.AddProperty("type", "Error");
638 error.AddProperty("text", "Isolate does not have profiling enabled."); 750 error.AddProperty("text", "Isolate does not have profiling enabled.");
639 return; 751 return;
640 } 752 }
641 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); 753 SampleBuffer* sample_buffer = profiler_data->sample_buffer();
642 ASSERT(sample_buffer != NULL); 754 ASSERT(sample_buffer != NULL);
643 { 755 {
644 StackZone zone(isolate); 756 StackZone zone(isolate);
645 { 757 {
646 // Build code region table. 758 // Build code region table.
647 ProfilerCodeRegionTable code_region_table(isolate); 759 ProfilerCodeRegionTable code_region_table(isolate);
648 CodeRegionTableBuilder builder(isolate, &code_region_table); 760 CodeRegionTableBuilder builder(isolate, &code_region_table);
761 CodeRegionTableCallersBuilder build_callers(isolate, &code_region_table);
649 { 762 {
650 ScopeStopwatch sw("CodeTableBuild"); 763 ScopeStopwatch sw("CodeTableBuild");
651 sample_buffer->VisitSamples(&builder); 764 sample_buffer->VisitSamples(&builder);
652 } 765 }
653 #if defined(DEBUG) 766 #if defined(DEBUG)
654 code_region_table.Verify(); 767 code_region_table.Verify();
655 #endif 768 #endif
769 {
770 ScopeStopwatch sw("CodeTableCallersBuild");
771 sample_buffer->VisitSamples(&build_callers);
772 }
656 // Number of samples we processed. 773 // Number of samples we processed.
657 intptr_t samples = builder.visited(); 774 intptr_t samples = builder.visited();
658 intptr_t frames = builder.frames(); 775 intptr_t frames = builder.frames();
659 if (FLAG_trace_profiled_isolates) { 776 if (FLAG_trace_profiled_isolates) {
660 OS::Print("%" Pd " frames produced %" Pd " code objects.\n", 777 OS::Print("%" Pd " frames produced %" Pd " code objects.\n",
661 frames, code_region_table.Length()); 778 frames, code_region_table.Length());
662 } 779 }
663 { 780 {
664 ScopeStopwatch sw("CodeTableStream"); 781 ScopeStopwatch sw("CodeTableStream");
665 // Serialize to JSON. 782 // Serialize to JSON.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 stack_lower = 0; 990 stack_lower = 0;
874 stack_upper = 0; 991 stack_upper = 0;
875 } 992 }
876 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper, 993 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
877 state.pc, state.fp, state.sp); 994 state.pc, state.fp, state.sp);
878 stackWalker.walk(); 995 stackWalker.walk();
879 } 996 }
880 997
881 998
882 } // namespace dart 999 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698