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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/profiler.h ('k') | runtime/vm/profiler_service.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/address_sanitizer.h" 5 #include "platform/address_sanitizer.h"
6 #include "platform/memory_sanitizer.h" 6 #include "platform/memory_sanitizer.h"
7 #include "platform/utils.h" 7 #include "platform/utils.h"
8 8
9 #include "vm/allocation.h" 9 #include "vm/allocation.h"
10 #include "vm/atomic.h" 10 #include "vm/atomic.h"
(...skipping 15 matching lines...) Expand all
26 26
27 namespace dart { 27 namespace dart {
28 28
29 static const intptr_t kSampleSize = 8; 29 static const intptr_t kSampleSize = 8;
30 static const intptr_t kMaxSamplesPerTick = 4; 30 static const intptr_t kMaxSamplesPerTick = 4;
31 31
32 DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates."); 32 DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates.");
33 33
34 #if defined(TARGET_OS_ANDROID) || defined(TARGET_ARCH_ARM64) || \ 34 #if defined(TARGET_OS_ANDROID) || defined(TARGET_ARCH_ARM64) || \
35 defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS) 35 defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
36 DEFINE_FLAG(int, profile_period, 10000, 36 DEFINE_FLAG(int,
37 "Time between profiler samples in microseconds. Minimum 50."); 37 profile_period,
38 10000,
39 "Time between profiler samples in microseconds. Minimum 50.");
38 #else 40 #else
39 DEFINE_FLAG(int, profile_period, 1000, 41 DEFINE_FLAG(int,
40 "Time between profiler samples in microseconds. Minimum 50."); 42 profile_period,
43 1000,
44 "Time between profiler samples in microseconds. Minimum 50.");
41 #endif 45 #endif
42 DEFINE_FLAG(int, max_profile_depth, kSampleSize * kMaxSamplesPerTick, 46 DEFINE_FLAG(int,
47 max_profile_depth,
48 kSampleSize* kMaxSamplesPerTick,
43 "Maximum number stack frames walked. Minimum 1. Maximum 255."); 49 "Maximum number stack frames walked. Minimum 1. Maximum 255.");
44 #if defined(USING_SIMULATOR) 50 #if defined(USING_SIMULATOR)
45 DEFINE_FLAG(bool, profile_vm, true, 51 DEFINE_FLAG(bool, profile_vm, true, "Always collect native stack traces.");
46 "Always collect native stack traces.");
47 #else 52 #else
48 DEFINE_FLAG(bool, profile_vm, false, 53 DEFINE_FLAG(bool, profile_vm, false, "Always collect native stack traces.");
49 "Always collect native stack traces.");
50 #endif 54 #endif
51 55
52 #ifndef PRODUCT 56 #ifndef PRODUCT
53 57
54 bool Profiler::initialized_ = false; 58 bool Profiler::initialized_ = false;
55 SampleBuffer* Profiler::sample_buffer_ = NULL; 59 SampleBuffer* Profiler::sample_buffer_ = NULL;
56 ProfilerCounters Profiler::counters_; 60 ProfilerCounters Profiler::counters_;
57 61
58 void Profiler::InitOnce() { 62 void Profiler::InitOnce() {
59 // Place some sane restrictions on user controlled flags. 63 // Place some sane restrictions on user controlled flags.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 } 110 }
107 } 111 }
108 112
109 113
110 intptr_t Sample::pcs_length_ = 0; 114 intptr_t Sample::pcs_length_ = 0;
111 intptr_t Sample::instance_size_ = 0; 115 intptr_t Sample::instance_size_ = 0;
112 116
113 117
114 void Sample::InitOnce() { 118 void Sample::InitOnce() {
115 pcs_length_ = kSampleSize; 119 pcs_length_ = kSampleSize;
116 instance_size_ = 120 instance_size_ = sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT.
117 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT.
118 } 121 }
119 122
120 123
121 uword* Sample::GetPCArray() const { 124 uword* Sample::GetPCArray() const {
122 return reinterpret_cast<uword*>( 125 return reinterpret_cast<uword*>(reinterpret_cast<uintptr_t>(this) +
123 reinterpret_cast<uintptr_t>(this) + sizeof(*this)); 126 sizeof(*this));
124 } 127 }
125 128
126 129
127 SampleBuffer::SampleBuffer(intptr_t capacity) { 130 SampleBuffer::SampleBuffer(intptr_t capacity) {
128 ASSERT(Sample::instance_size() > 0); 131 ASSERT(Sample::instance_size() > 0);
129 samples_ = reinterpret_cast<Sample*>( 132 samples_ =
130 calloc(capacity, Sample::instance_size())); 133 reinterpret_cast<Sample*>(calloc(capacity, Sample::instance_size()));
131 if (FLAG_trace_profiler) { 134 if (FLAG_trace_profiler) {
132 OS::Print("Profiler holds %" Pd " samples\n", capacity); 135 OS::Print("Profiler holds %" Pd " samples\n", capacity);
133 OS::Print("Profiler sample is %" Pd " bytes\n", Sample::instance_size()); 136 OS::Print("Profiler sample is %" Pd " bytes\n", Sample::instance_size());
134 OS::Print("Profiler memory usage = %" Pd " bytes\n", 137 OS::Print("Profiler memory usage = %" Pd " bytes\n",
135 capacity * Sample::instance_size()); 138 capacity * Sample::instance_size());
136 } 139 }
137 capacity_ = capacity; 140 capacity_ = capacity;
138 cursor_ = 0; 141 cursor_ = 0;
139 } 142 }
140 143
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 } 190 }
188 191
189 ReturnAddressLocator(uword pc, uword* stack_buffer, const Code& code) 192 ReturnAddressLocator(uword pc, uword* stack_buffer, const Code& code)
190 : stack_buffer_(stack_buffer), 193 : stack_buffer_(stack_buffer),
191 pc_(pc), 194 pc_(pc),
192 code_(Code::ZoneHandle(code.raw())) { 195 code_(Code::ZoneHandle(code.raw())) {
193 ASSERT(!code_.IsNull()); 196 ASSERT(!code_.IsNull());
194 ASSERT(code_.ContainsInstructionAt(pc_)); 197 ASSERT(code_.ContainsInstructionAt(pc_));
195 } 198 }
196 199
197 uword pc() { 200 uword pc() { return pc_; }
198 return pc_;
199 }
200 201
201 // Returns false on failure. 202 // Returns false on failure.
202 bool LocateReturnAddress(uword* return_address); 203 bool LocateReturnAddress(uword* return_address);
203 204
204 // Returns offset into code object. 205 // Returns offset into code object.
205 intptr_t RelativePC() { 206 intptr_t RelativePC() {
206 ASSERT(pc() >= code_.PayloadStart()); 207 ASSERT(pc() >= code_.PayloadStart());
207 return static_cast<intptr_t>(pc() - code_.PayloadStart()); 208 return static_cast<intptr_t>(pc() - code_.PayloadStart());
208 } 209 }
209 210
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 bool ReturnAddressLocator::LocateReturnAddress(uword* return_address) { 297 bool ReturnAddressLocator::LocateReturnAddress(uword* return_address) {
297 ASSERT(return_address != NULL); 298 ASSERT(return_address != NULL);
298 return false; 299 return false;
299 } 300 }
300 #else 301 #else
301 #error ReturnAddressLocator implementation missing for this architecture. 302 #error ReturnAddressLocator implementation missing for this architecture.
302 #endif 303 #endif
303 304
304 305
305 bool SampleFilter::TimeFilterSample(Sample* sample) { 306 bool SampleFilter::TimeFilterSample(Sample* sample) {
306 if ((time_origin_micros_ == -1) || 307 if ((time_origin_micros_ == -1) || (time_extent_micros_ == -1)) {
307 (time_extent_micros_ == -1)) {
308 // No time filter passed in, always pass. 308 // No time filter passed in, always pass.
309 return true; 309 return true;
310 } 310 }
311 const int64_t timestamp = sample->timestamp(); 311 const int64_t timestamp = sample->timestamp();
312 int64_t delta = timestamp - time_origin_micros_; 312 int64_t delta = timestamp - time_origin_micros_;
313 return (delta >= 0) && (delta <= time_extent_micros_); 313 return (delta >= 0) && (delta <= time_extent_micros_);
314 } 314 }
315 315
316 316
317 bool SampleFilter::TaskFilterSample(Sample* sample) { 317 bool SampleFilter::TaskFilterSample(Sample* sample) {
318 const intptr_t task = static_cast<intptr_t>(sample->thread_task()); 318 const intptr_t task = static_cast<intptr_t>(sample->thread_task());
319 return (task & thread_task_mask_) != 0; 319 return (task & thread_task_mask_) != 0;
320 } 320 }
321 321
322 322
323 ClearProfileVisitor::ClearProfileVisitor(Isolate* isolate) 323 ClearProfileVisitor::ClearProfileVisitor(Isolate* isolate)
324 : SampleVisitor(isolate) { 324 : SampleVisitor(isolate) {}
325 }
326 325
327 326
328 void ClearProfileVisitor::VisitSample(Sample* sample) { 327 void ClearProfileVisitor::VisitSample(Sample* sample) {
329 sample->Clear(); 328 sample->Clear();
330 } 329 }
331 330
332 331
333 static void DumpStackFrame(intptr_t frame_index, uword pc) { 332 static void DumpStackFrame(intptr_t frame_index, uword pc) {
334 uintptr_t start = 0; 333 uintptr_t start = 0;
335 char* native_symbol_name = 334 char* native_symbol_name = NativeSymbolResolver::LookupSymbolName(pc, &start);
336 NativeSymbolResolver::LookupSymbolName(pc, &start);
337 if (native_symbol_name == NULL) { 335 if (native_symbol_name == NULL) {
338 OS::PrintErr(" [0x%" Pp "] Unknown symbol\n", pc); 336 OS::PrintErr(" [0x%" Pp "] Unknown symbol\n", pc);
339 } else { 337 } else {
340 OS::PrintErr(" [0x%" Pp "] %s\n", pc, native_symbol_name); 338 OS::PrintErr(" [0x%" Pp "] %s\n", pc, native_symbol_name);
341 NativeSymbolResolver::FreeSymbolName(native_symbol_name); 339 NativeSymbolResolver::FreeSymbolName(native_symbol_name);
342 } 340 }
343 } 341 }
344 342
345 343
346 static void DumpStackFrame(intptr_t frame_index, 344 static void DumpStackFrame(intptr_t frame_index, uword pc, const Code& code) {
347 uword pc,
348 const Code& code) {
349 if (code.IsNull()) { 345 if (code.IsNull()) {
350 DumpStackFrame(frame_index, pc); 346 DumpStackFrame(frame_index, pc);
351 } else { 347 } else {
352 OS::PrintErr("Frame[%" Pd "] = Dart:`%s` [0x%" Px "]\n", 348 OS::PrintErr("Frame[%" Pd "] = Dart:`%s` [0x%" Px "]\n", frame_index,
353 frame_index, code.ToCString(), pc); 349 code.ToCString(), pc);
354 } 350 }
355 } 351 }
356 352
357 353
358 class ProfilerStackWalker : public ValueObject { 354 class ProfilerStackWalker : public ValueObject {
359 public: 355 public:
360 ProfilerStackWalker(Isolate* isolate, 356 ProfilerStackWalker(Isolate* isolate,
361 Sample* head_sample, 357 Sample* head_sample,
362 SampleBuffer* sample_buffer) 358 SampleBuffer* sample_buffer)
363 : isolate_(isolate), 359 : isolate_(isolate),
364 sample_(head_sample), 360 sample_(head_sample),
365 sample_buffer_(sample_buffer), 361 sample_buffer_(sample_buffer),
366 frame_index_(0), 362 frame_index_(0),
367 total_frames_(0) { 363 total_frames_(0) {
368 ASSERT(isolate_ != NULL); 364 ASSERT(isolate_ != NULL);
369 if (sample_ == NULL) { 365 if (sample_ == NULL) {
370 ASSERT(sample_buffer_ == NULL); 366 ASSERT(sample_buffer_ == NULL);
371 } else { 367 } else {
372 ASSERT(sample_buffer_ != NULL); 368 ASSERT(sample_buffer_ != NULL);
373 ASSERT(sample_->head_sample()); 369 ASSERT(sample_->head_sample());
374 } 370 }
375 } 371 }
376 372
377 bool Append(uword pc, const Code& code) { 373 bool Append(uword pc, const Code& code) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 419
424 420
425 // Given an exit frame, walk the Dart stack. 421 // Given an exit frame, walk the Dart stack.
426 class ProfilerDartExitStackWalker : public ProfilerStackWalker { 422 class ProfilerDartExitStackWalker : public ProfilerStackWalker {
427 public: 423 public:
428 ProfilerDartExitStackWalker(Thread* thread, 424 ProfilerDartExitStackWalker(Thread* thread,
429 Isolate* isolate, 425 Isolate* isolate,
430 Sample* sample, 426 Sample* sample,
431 SampleBuffer* sample_buffer) 427 SampleBuffer* sample_buffer)
432 : ProfilerStackWalker(isolate, sample, sample_buffer), 428 : ProfilerStackWalker(isolate, sample, sample_buffer),
433 frame_iterator_(thread) { 429 frame_iterator_(thread) {}
434 }
435 430
436 void walk() { 431 void walk() {
437 // Mark that this sample was collected from an exit frame. 432 // Mark that this sample was collected from an exit frame.
438 sample_->set_exit_frame_sample(true); 433 sample_->set_exit_frame_sample(true);
439 434
440 StackFrame* frame = frame_iterator_.NextFrame(); 435 StackFrame* frame = frame_iterator_.NextFrame();
441 if (sample_ == NULL) { 436 if (sample_ == NULL) {
442 // Only when we are dumping the stack trace for debug purposes. 437 // Only when we are dumping the stack trace for debug purposes.
443 Code& code = Code::Handle(); 438 Code& code = Code::Handle();
444 while (frame != NULL) { 439 while (frame != NULL) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 583
589 uword* ExitLink() const { 584 uword* ExitLink() const {
590 ASSERT(fp_ != NULL); 585 ASSERT(fp_ != NULL);
591 uword* exit_link_ptr = fp_ + kExitLinkSlotFromEntryFp; 586 uword* exit_link_ptr = fp_ + kExitLinkSlotFromEntryFp;
592 // MSan/ASan are unaware of frames initialized by generated code. 587 // MSan/ASan are unaware of frames initialized by generated code.
593 MSAN_UNPOISON(exit_link_ptr, kWordSize); 588 MSAN_UNPOISON(exit_link_ptr, kWordSize);
594 ASAN_UNPOISON(exit_link_ptr, kWordSize); 589 ASAN_UNPOISON(exit_link_ptr, kWordSize);
595 return reinterpret_cast<uword*>(*exit_link_ptr); 590 return reinterpret_cast<uword*>(*exit_link_ptr);
596 } 591 }
597 592
598 bool ValidFramePointer() const { 593 bool ValidFramePointer() const { return ValidFramePointer(fp_); }
599 return ValidFramePointer(fp_);
600 }
601 594
602 bool ValidFramePointer(uword* fp) const { 595 bool ValidFramePointer(uword* fp) const {
603 if (fp == NULL) { 596 if (fp == NULL) {
604 return false; 597 return false;
605 } 598 }
606 uword cursor = reinterpret_cast<uword>(fp); 599 uword cursor = reinterpret_cast<uword>(fp);
607 cursor += sizeof(fp); 600 cursor += sizeof(fp);
608 return (cursor >= stack_lower_) && (cursor < stack_upper_); 601 return (cursor >= stack_lower_) && (cursor < stack_upper_);
609 } 602 }
610 603
(...skipping 17 matching lines...) Expand all
628 uword stack_lower, 621 uword stack_lower,
629 uword stack_upper, 622 uword stack_upper,
630 uword pc, 623 uword pc,
631 uword fp, 624 uword fp,
632 uword sp) 625 uword sp)
633 : ProfilerStackWalker(isolate, sample, sample_buffer), 626 : ProfilerStackWalker(isolate, sample, sample_buffer),
634 stack_upper_(stack_upper), 627 stack_upper_(stack_upper),
635 original_pc_(pc), 628 original_pc_(pc),
636 original_fp_(fp), 629 original_fp_(fp),
637 original_sp_(sp), 630 original_sp_(sp),
638 lower_bound_(stack_lower) { 631 lower_bound_(stack_lower) {}
639 }
640 632
641 void walk() { 633 void walk() {
642 const uword kMaxStep = VirtualMemory::PageSize(); 634 const uword kMaxStep = VirtualMemory::PageSize();
643 Append(original_pc_); 635 Append(original_pc_);
644 636
645 uword* pc = reinterpret_cast<uword*>(original_pc_); 637 uword* pc = reinterpret_cast<uword*>(original_pc_);
646 uword* fp = reinterpret_cast<uword*>(original_fp_); 638 uword* fp = reinterpret_cast<uword*>(original_fp_);
647 uword* previous_fp = fp; 639 uword* previous_fp = fp;
648 640
649 uword gap = original_fp_ - original_sp_; 641 uword gap = original_fp_ - original_sp_;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 uword pc, 763 uword pc,
772 uword fp, 764 uword fp,
773 uword sp, 765 uword sp,
774 ProfilerCounters* counters) { 766 ProfilerCounters* counters) {
775 ASSERT(counters != NULL); 767 ASSERT(counters != NULL);
776 #if defined(TARGET_OS_WINDOWS) 768 #if defined(TARGET_OS_WINDOWS)
777 // Use structured exception handling to trap guard page access on Windows. 769 // Use structured exception handling to trap guard page access on Windows.
778 __try { 770 __try {
779 #endif 771 #endif
780 772
781 if (in_dart_code) { 773 if (in_dart_code) {
782 // We can only trust the stack pointer if we are executing Dart code. 774 // We can only trust the stack pointer if we are executing Dart code.
783 // See http://dartbug.com/20421 for details. 775 // See http://dartbug.com/20421 for details.
784 CopyStackBuffer(sample, sp); 776 CopyStackBuffer(sample, sp);
785 } 777 }
786 778
787 if (FLAG_profile_vm) { 779 if (FLAG_profile_vm) {
788 // Always walk the native stack collecting both native and Dart frames. 780 // Always walk the native stack collecting both native and Dart frames.
789 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1); 781 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1);
790 native_stack_walker->walk(); 782 native_stack_walker->walk();
791 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { 783 } else if (StubCode::HasBeenInitialized() && exited_dart_code) {
792 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1); 784 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1);
793 // We have a valid exit frame info, use the Dart stack walker. 785 // We have a valid exit frame info, use the Dart stack walker.
794 dart_exit_stack_walker->walk(); 786 dart_exit_stack_walker->walk();
795 } else if (StubCode::HasBeenInitialized() && in_dart_code) { 787 } else if (StubCode::HasBeenInitialized() && in_dart_code) {
796 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1); 788 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1);
797 // We are executing Dart code. We have frame pointers. 789 // We are executing Dart code. We have frame pointers.
798 dart_stack_walker->walk(); 790 dart_stack_walker->walk();
799 } else { 791 } else {
800 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1); 792 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1);
801 sample->SetAt(0, pc); 793 sample->SetAt(0, pc);
802 } 794 }
803 795
804 #if defined(TARGET_OS_WINDOWS) 796 #if defined(TARGET_OS_WINDOWS)
805 // Use structured exception handling to trap guard page access. 797 // Use structured exception handling to trap guard page access.
806 } __except(GuardPageExceptionFilter(GetExceptionInformation())) { 798 } __except (GuardPageExceptionFilter(GetExceptionInformation())) { // NOLINT
807 // Sample collection triggered a guard page fault: 799 // Sample collection triggered a guard page fault:
808 // 1) discard entire sample. 800 // 1) discard entire sample.
809 sample->set_ignore_sample(true); 801 sample->set_ignore_sample(true);
810 802
811 // 2) Reenable guard bit on page that triggered the fault. 803 // 2) Reenable guard bit on page that triggered the fault.
812 // https://goo.gl/5mCsXW 804 // https://goo.gl/5mCsXW
813 DWORD new_protect = PAGE_READWRITE | PAGE_GUARD; 805 DWORD new_protect = PAGE_READWRITE | PAGE_GUARD;
814 DWORD old_protect = 0; 806 DWORD old_protect = 0;
815 BOOL success = VirtualProtect(reinterpret_cast<void*>(fault_address), 807 BOOL success =
816 sizeof(fault_address), 808 VirtualProtect(reinterpret_cast<void*>(fault_address),
817 new_protect, 809 sizeof(fault_address), new_protect, &old_protect);
818 &old_protect);
819 USE(success); 810 USE(success);
820 ASSERT(success); 811 ASSERT(success);
821 ASSERT(old_protect == PAGE_READWRITE); 812 ASSERT(old_protect == PAGE_READWRITE);
822 } 813 }
823 #endif 814 #endif
824 } 815 }
825 816
826 817
827 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within 818 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within
828 // it. Return |false| if anything looks suspicious. 819 // it. Return |false| if anything looks suspicious.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 static bool CheckIsolate(Isolate* isolate) { 926 static bool CheckIsolate(Isolate* isolate) {
936 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { 927 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) {
937 // No isolate. 928 // No isolate.
938 return false; 929 return false;
939 } 930 }
940 return isolate != Dart::vm_isolate(); 931 return isolate != Dart::vm_isolate();
941 } 932 }
942 933
943 934
944 #if defined(TARGET_OS_WINDOWS) 935 #if defined(TARGET_OS_WINDOWS)
945 __declspec(noinline) 936 __declspec(noinline) static uintptr_t GetProgramCounter() {
946 static uintptr_t GetProgramCounter() {
947 return reinterpret_cast<uintptr_t>(_ReturnAddress()); 937 return reinterpret_cast<uintptr_t>(_ReturnAddress());
948 } 938 }
949 #else 939 #else
950 static uintptr_t __attribute__((noinline)) GetProgramCounter() { 940 static uintptr_t __attribute__((noinline)) GetProgramCounter() {
951 return reinterpret_cast<uintptr_t>( 941 return reinterpret_cast<uintptr_t>(
952 __builtin_extract_return_addr(__builtin_return_address(0))); 942 __builtin_extract_return_addr(__builtin_return_address(0)));
953 } 943 }
954 #endif 944 #endif
955 945
956 946
(...skipping 26 matching lines...) Expand all
983 uintptr_t sp = Thread::GetCurrentStackPointer(); 973 uintptr_t sp = Thread::GetCurrentStackPointer();
984 uintptr_t fp = 0; 974 uintptr_t fp = 0;
985 uintptr_t pc = GetProgramCounter(); 975 uintptr_t pc = GetProgramCounter();
986 976
987 COPY_FP_REGISTER(fp); 977 COPY_FP_REGISTER(fp);
988 978
989 uword stack_lower = 0; 979 uword stack_lower = 0;
990 uword stack_upper = 0; 980 uword stack_upper = 0;
991 981
992 if (!InitialRegisterCheck(pc, fp, sp)) { 982 if (!InitialRegisterCheck(pc, fp, sp)) {
993 OS::PrintErr( 983 OS::PrintErr("Stack dump aborted because InitialRegisterCheck.\n");
994 "Stack dump aborted because InitialRegisterCheck.\n");
995 return; 984 return;
996 } 985 }
997 986
998 if (!GetAndValidateIsolateStackBounds(thread, 987 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower,
999 fp,
1000 sp,
1001 &stack_lower,
1002 &stack_upper)) { 988 &stack_upper)) {
1003 OS::PrintErr( 989 OS::PrintErr(
1004 "Stack dump aborted because GetAndValidateIsolateStackBounds.\n"); 990 "Stack dump aborted because GetAndValidateIsolateStackBounds.\n");
1005 return; 991 return;
1006 } 992 }
1007 993
1008 if (native_stack_trace) { 994 if (native_stack_trace) {
1009 ProfilerNativeStackWalker native_stack_walker(isolate, 995 ProfilerNativeStackWalker native_stack_walker(
1010 NULL, 996 isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp);
1011 NULL,
1012 stack_lower,
1013 stack_upper,
1014 pc,
1015 fp,
1016 sp);
1017 native_stack_walker.walk(); 997 native_stack_walker.walk();
1018 } else if (exited_dart_code) { 998 } else if (exited_dart_code) {
1019 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, 999 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, NULL,
1020 isolate,
1021 NULL,
1022 NULL); 1000 NULL);
1023 dart_exit_stack_walker.walk(); 1001 dart_exit_stack_walker.walk();
1024 } else { 1002 } else {
1025 ProfilerDartStackWalker dart_stack_walker(isolate, 1003 ProfilerDartStackWalker dart_stack_walker(isolate, NULL, NULL, stack_lower,
1026 NULL, 1004 stack_upper, pc, fp, sp);
1027 NULL,
1028 stack_lower,
1029 stack_upper,
1030 pc,
1031 fp,
1032 sp);
1033 } 1005 }
1034 OS::PrintErr("-- End of DumpStackTrace\n"); 1006 OS::PrintErr("-- End of DumpStackTrace\n");
1035 } 1007 }
1036 1008
1037 1009
1038 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { 1010 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) {
1039 ASSERT(thread != NULL); 1011 ASSERT(thread != NULL);
1040 OSThread* os_thread = thread->os_thread(); 1012 OSThread* os_thread = thread->os_thread();
1041 ASSERT(os_thread != NULL); 1013 ASSERT(os_thread != NULL);
1042 Isolate* isolate = thread->isolate(); 1014 Isolate* isolate = thread->isolate();
(...skipping 16 matching lines...) Expand all
1059 1031
1060 COPY_FP_REGISTER(fp); 1032 COPY_FP_REGISTER(fp);
1061 1033
1062 uword stack_lower = 0; 1034 uword stack_lower = 0;
1063 uword stack_upper = 0; 1035 uword stack_upper = 0;
1064 1036
1065 if (!InitialRegisterCheck(pc, fp, sp)) { 1037 if (!InitialRegisterCheck(pc, fp, sp)) {
1066 return; 1038 return;
1067 } 1039 }
1068 1040
1069 if (!GetAndValidateIsolateStackBounds(thread, 1041 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower,
1070 fp,
1071 sp,
1072 &stack_lower,
1073 &stack_upper)) { 1042 &stack_upper)) {
1074 // Could not get stack boundary. 1043 // Could not get stack boundary.
1075 return; 1044 return;
1076 } 1045 }
1077 1046
1078 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1047 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1079 sample->SetAllocationCid(cid); 1048 sample->SetAllocationCid(cid);
1080 ProfilerNativeStackWalker native_stack_walker(isolate, 1049 ProfilerNativeStackWalker native_stack_walker(
1081 sample, 1050 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1082 sample_buffer,
1083 stack_lower,
1084 stack_upper,
1085 pc,
1086 fp,
1087 sp);
1088 native_stack_walker.walk(); 1051 native_stack_walker.walk();
1089 } else if (exited_dart_code) { 1052 } else if (exited_dart_code) {
1090 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1053 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1091 sample->SetAllocationCid(cid); 1054 sample->SetAllocationCid(cid);
1092 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, 1055 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, sample,
1093 isolate,
1094 sample,
1095 sample_buffer); 1056 sample_buffer);
1096 dart_exit_stack_walker.walk(); 1057 dart_exit_stack_walker.walk();
1097 } else { 1058 } else {
1098 // Fall back. 1059 // Fall back.
1099 uintptr_t pc = GetProgramCounter(); 1060 uintptr_t pc = GetProgramCounter();
1100 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1061 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1101 sample->SetAllocationCid(cid); 1062 sample->SetAllocationCid(cid);
1102 sample->SetAt(0, pc); 1063 sample->SetAt(0, pc);
1103 } 1064 }
1104 } 1065 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 const bool in_dart_code = thread->IsExecutingDartCode(); 1117 const bool in_dart_code = thread->IsExecutingDartCode();
1157 1118
1158 uintptr_t sp = 0; 1119 uintptr_t sp = 0;
1159 uintptr_t fp = state.fp; 1120 uintptr_t fp = state.fp;
1160 uintptr_t pc = state.pc; 1121 uintptr_t pc = state.pc;
1161 #if defined(USING_SIMULATOR) 1122 #if defined(USING_SIMULATOR)
1162 Simulator* simulator = NULL; 1123 Simulator* simulator = NULL;
1163 #endif 1124 #endif
1164 1125
1165 if (in_dart_code) { 1126 if (in_dart_code) {
1166 // If we're in Dart code, use the Dart stack pointer. 1127 // If we're in Dart code, use the Dart stack pointer.
1167 #if defined(TARGET_ARCH_DBC) 1128 #if defined(TARGET_ARCH_DBC)
1168 simulator = isolate->simulator(); 1129 simulator = isolate->simulator();
1169 sp = simulator->get_sp(); 1130 sp = simulator->get_sp();
1170 fp = simulator->get_fp(); 1131 fp = simulator->get_fp();
1171 pc = simulator->get_pc(); 1132 pc = simulator->get_pc();
1172 #elif defined(USING_SIMULATOR) 1133 #elif defined(USING_SIMULATOR)
1173 simulator = isolate->simulator(); 1134 simulator = isolate->simulator();
1174 sp = simulator->get_register(SPREG); 1135 sp = simulator->get_register(SPREG);
1175 fp = simulator->get_register(FPREG); 1136 fp = simulator->get_register(FPREG);
1176 pc = simulator->get_pc(); 1137 pc = simulator->get_pc();
(...skipping 19 matching lines...) Expand all
1196 1157
1197 if (!InitialRegisterCheck(pc, fp, sp)) { 1158 if (!InitialRegisterCheck(pc, fp, sp)) {
1198 AtomicOperations::IncrementInt64By( 1159 AtomicOperations::IncrementInt64By(
1199 &counters_.single_frame_sample_register_check, 1); 1160 &counters_.single_frame_sample_register_check, 1);
1200 SampleThreadSingleFrame(thread, pc); 1161 SampleThreadSingleFrame(thread, pc);
1201 return; 1162 return;
1202 } 1163 }
1203 1164
1204 uword stack_lower = 0; 1165 uword stack_lower = 0;
1205 uword stack_upper = 0; 1166 uword stack_upper = 0;
1206 if (!GetAndValidateIsolateStackBounds(thread, 1167 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower,
1207 fp,
1208 sp,
1209 &stack_lower,
1210 &stack_upper)) { 1168 &stack_upper)) {
1211 AtomicOperations::IncrementInt64By( 1169 AtomicOperations::IncrementInt64By(
1212 &counters_.single_frame_sample_get_and_validate_stack_bounds, 1); 1170 &counters_.single_frame_sample_get_and_validate_stack_bounds, 1);
1213 // Could not get stack boundary. 1171 // Could not get stack boundary.
1214 SampleThreadSingleFrame(thread, pc); 1172 SampleThreadSingleFrame(thread, pc);
1215 return; 1173 return;
1216 } 1174 }
1217 1175
1218 // At this point we have a valid stack boundary for this isolate and 1176 // At this point we have a valid stack boundary for this isolate and
1219 // know that our initial stack and frame pointers are within the boundary. 1177 // know that our initial stack and frame pointers are within the boundary.
1220 SampleBuffer* sample_buffer = Profiler::sample_buffer(); 1178 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1221 if (sample_buffer == NULL) { 1179 if (sample_buffer == NULL) {
1222 // Profiler not initialized. 1180 // Profiler not initialized.
1223 return; 1181 return;
1224 } 1182 }
1225 1183
1226 // Setup sample. 1184 // Setup sample.
1227 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1185 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1228 // Increment counter for vm tag. 1186 // Increment counter for vm tag.
1229 VMTagCounters* counters = isolate->vm_tag_counters(); 1187 VMTagCounters* counters = isolate->vm_tag_counters();
1230 ASSERT(counters != NULL); 1188 ASSERT(counters != NULL);
1231 if (thread->IsMutatorThread()) { 1189 if (thread->IsMutatorThread()) {
1232 counters->Increment(sample->vm_tag()); 1190 counters->Increment(sample->vm_tag());
1233 } 1191 }
1234 1192
1235 ProfilerNativeStackWalker native_stack_walker(isolate, 1193 ProfilerNativeStackWalker native_stack_walker(
1236 sample, 1194 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1237 sample_buffer,
1238 stack_lower,
1239 stack_upper,
1240 pc,
1241 fp,
1242 sp);
1243 1195
1244 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, 1196 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, sample,
1245 isolate,
1246 sample,
1247 sample_buffer); 1197 sample_buffer);
1248 1198
1249 ProfilerDartStackWalker dart_stack_walker(isolate, 1199 ProfilerDartStackWalker dart_stack_walker(
1250 sample, 1200 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1251 sample_buffer,
1252 stack_lower,
1253 stack_upper,
1254 pc,
1255 fp,
1256 sp);
1257 1201
1258 const bool exited_dart_code = thread->HasExitedDartCode(); 1202 const bool exited_dart_code = thread->HasExitedDartCode();
1259 1203
1260 // All memory access is done inside CollectSample. 1204 // All memory access is done inside CollectSample.
1261 CollectSample(isolate, 1205 CollectSample(isolate, exited_dart_code, in_dart_code, sample,
1262 exited_dart_code, 1206 &native_stack_walker, &dart_exit_stack_walker,
1263 in_dart_code, 1207 &dart_stack_walker, pc, fp, sp, &counters_);
1264 sample,
1265 &native_stack_walker,
1266 &dart_exit_stack_walker,
1267 &dart_stack_walker,
1268 pc,
1269 fp,
1270 sp,
1271 &counters_);
1272 } 1208 }
1273 1209
1274 1210
1275
1276 CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) { 1211 CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) {
1277 ASSERT(!code_.IsNull()); 1212 ASSERT(!code_.IsNull());
1278 } 1213 }
1279 1214
1280 1215
1281 uword CodeDescriptor::Start() const { 1216 uword CodeDescriptor::Start() const {
1282 return code_.PayloadStart(); 1217 return code_.PayloadStart();
1283 } 1218 }
1284 1219
1285 1220
(...skipping 11 matching lines...) Expand all
1297 Build(thread); 1232 Build(thread);
1298 } 1233 }
1299 1234
1300 1235
1301 class CodeLookupTableBuilder : public ObjectVisitor { 1236 class CodeLookupTableBuilder : public ObjectVisitor {
1302 public: 1237 public:
1303 explicit CodeLookupTableBuilder(CodeLookupTable* table) : table_(table) { 1238 explicit CodeLookupTableBuilder(CodeLookupTable* table) : table_(table) {
1304 ASSERT(table_ != NULL); 1239 ASSERT(table_ != NULL);
1305 } 1240 }
1306 1241
1307 ~CodeLookupTableBuilder() { 1242 ~CodeLookupTableBuilder() {}
1308 }
1309 1243
1310 void VisitObject(RawObject* raw_obj) { 1244 void VisitObject(RawObject* raw_obj) {
1311 uword tags = raw_obj->ptr()->tags_; 1245 uword tags = raw_obj->ptr()->tags_;
1312 if (RawObject::ClassIdTag::decode(tags) == kCodeCid) { 1246 if (RawObject::ClassIdTag::decode(tags) == kCodeCid) {
1313 RawCode* raw_code = reinterpret_cast<RawCode*>(raw_obj); 1247 RawCode* raw_code = reinterpret_cast<RawCode*>(raw_obj);
1314 const Code& code = Code::Handle(raw_code); 1248 const Code& code = Code::Handle(raw_code);
1315 ASSERT(!code.IsNull()); 1249 ASSERT(!code.IsNull());
1316 const Instructions& instructions = 1250 const Instructions& instructions =
1317 Instructions::Handle(code.instructions()); 1251 Instructions::Handle(code.instructions());
1318 ASSERT(!instructions.IsNull()); 1252 ASSERT(!instructions.IsNull());
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 return NULL; 1335 return NULL;
1402 } 1336 }
1403 1337
1404 1338
1405 ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer( 1339 ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer(
1406 SampleFilter* filter) { 1340 SampleFilter* filter) {
1407 ASSERT(filter != NULL); 1341 ASSERT(filter != NULL);
1408 Thread* thread = Thread::Current(); 1342 Thread* thread = Thread::Current();
1409 Zone* zone = thread->zone(); 1343 Zone* zone = thread->zone();
1410 1344
1411 ProcessedSampleBuffer* buffer = new(zone) ProcessedSampleBuffer(); 1345 ProcessedSampleBuffer* buffer = new (zone) ProcessedSampleBuffer();
1412 1346
1413 const intptr_t length = capacity(); 1347 const intptr_t length = capacity();
1414 for (intptr_t i = 0; i < length; i++) { 1348 for (intptr_t i = 0; i < length; i++) {
1415 Sample* sample = At(i); 1349 Sample* sample = At(i);
1416 if (sample->ignore_sample()) { 1350 if (sample->ignore_sample()) {
1417 // Bad sample. 1351 // Bad sample.
1418 continue; 1352 continue;
1419 } 1353 }
1420 if (!sample->head_sample()) { 1354 if (!sample->head_sample()) {
1421 // An inner sample in a chain of samples. 1355 // An inner sample in a chain of samples.
(...skipping 28 matching lines...) Expand all
1450 return buffer; 1384 return buffer;
1451 } 1385 }
1452 1386
1453 1387
1454 ProcessedSample* SampleBuffer::BuildProcessedSample( 1388 ProcessedSample* SampleBuffer::BuildProcessedSample(
1455 Sample* sample, 1389 Sample* sample,
1456 const CodeLookupTable& clt) { 1390 const CodeLookupTable& clt) {
1457 Thread* thread = Thread::Current(); 1391 Thread* thread = Thread::Current();
1458 Zone* zone = thread->zone(); 1392 Zone* zone = thread->zone();
1459 1393
1460 ProcessedSample* processed_sample = new(zone) ProcessedSample(); 1394 ProcessedSample* processed_sample = new (zone) ProcessedSample();
1461 1395
1462 // Copy state bits from sample. 1396 // Copy state bits from sample.
1463 processed_sample->set_timestamp(sample->timestamp()); 1397 processed_sample->set_timestamp(sample->timestamp());
1464 processed_sample->set_tid(sample->tid()); 1398 processed_sample->set_tid(sample->tid());
1465 processed_sample->set_vm_tag(sample->vm_tag()); 1399 processed_sample->set_vm_tag(sample->vm_tag());
1466 processed_sample->set_user_tag(sample->user_tag()); 1400 processed_sample->set_user_tag(sample->user_tag());
1467 if (sample->is_allocation_sample()) { 1401 if (sample->is_allocation_sample()) {
1468 processed_sample->set_allocation_cid(sample->allocation_cid()); 1402 processed_sample->set_allocation_cid(sample->allocation_cid());
1469 } 1403 }
1470 processed_sample->set_first_frame_executing(!sample->exit_frame_sample()); 1404 processed_sample->set_first_frame_executing(!sample->exit_frame_sample());
1471 1405
1472 // Copy stack trace from sample(s). 1406 // Copy stack trace from sample(s).
1473 bool truncated = false; 1407 bool truncated = false;
1474 Sample* current = sample; 1408 Sample* current = sample;
1475 while (current != NULL) { 1409 while (current != NULL) {
1476 for (intptr_t i = 0; i < kSampleSize; i++) { 1410 for (intptr_t i = 0; i < kSampleSize; i++) {
1477 if (current->At(i) == 0) { 1411 if (current->At(i) == 0) {
1478 break; 1412 break;
1479 } 1413 }
1480 processed_sample->Add(current->At(i)); 1414 processed_sample->Add(current->At(i));
1481 } 1415 }
1482 1416
1483 truncated = truncated || current->truncated_trace(); 1417 truncated = truncated || current->truncated_trace();
1484 current = Next(current); 1418 current = Next(current);
1485 } 1419 }
1486 1420
1487 if (!sample->exit_frame_sample()) { 1421 if (!sample->exit_frame_sample()) {
1488 processed_sample->FixupCaller(clt, 1422 processed_sample->FixupCaller(clt, sample->pc_marker(),
1489 sample->pc_marker(),
1490 sample->GetStackBuffer()); 1423 sample->GetStackBuffer());
1491 } 1424 }
1492 1425
1493 processed_sample->set_truncated(truncated); 1426 processed_sample->set_truncated(truncated);
1494 return processed_sample; 1427 return processed_sample;
1495 } 1428 }
1496 1429
1497 1430
1498 Sample* SampleBuffer::Next(Sample* sample) { 1431 Sample* SampleBuffer::Next(Sample* sample) {
1499 if (!sample->is_continuation_sample()) 1432 if (!sample->is_continuation_sample()) return NULL;
1500 return NULL;
1501 Sample* next_sample = At(sample->continuation_index()); 1433 Sample* next_sample = At(sample->continuation_index());
1502 // Sanity check. 1434 // Sanity check.
1503 ASSERT(sample != next_sample); 1435 ASSERT(sample != next_sample);
1504 // Detect invalid chaining. 1436 // Detect invalid chaining.
1505 if (sample->isolate() != next_sample->isolate()) { 1437 if (sample->isolate() != next_sample->isolate()) {
1506 return NULL; 1438 return NULL;
1507 } 1439 }
1508 if (sample->timestamp() != next_sample->timestamp()) { 1440 if (sample->timestamp() != next_sample->timestamp()) {
1509 return NULL; 1441 return NULL;
1510 } 1442 }
1511 if (sample->tid() != next_sample->tid()) { 1443 if (sample->tid() != next_sample->tid()) {
1512 return NULL; 1444 return NULL;
1513 } 1445 }
1514 return next_sample; 1446 return next_sample;
1515 } 1447 }
1516 1448
1517 1449
1518 ProcessedSample::ProcessedSample() 1450 ProcessedSample::ProcessedSample()
1519 : pcs_(kSampleSize), 1451 : pcs_(kSampleSize),
1520 timestamp_(0), 1452 timestamp_(0),
1521 vm_tag_(0), 1453 vm_tag_(0),
1522 user_tag_(0), 1454 user_tag_(0),
1523 allocation_cid_(-1), 1455 allocation_cid_(-1),
1524 truncated_(false), 1456 truncated_(false),
1525 timeline_trie_(NULL) { 1457 timeline_trie_(NULL) {}
1526 }
1527 1458
1528 1459
1529 void ProcessedSample::FixupCaller(const CodeLookupTable& clt, 1460 void ProcessedSample::FixupCaller(const CodeLookupTable& clt,
1530 uword pc_marker, 1461 uword pc_marker,
1531 uword* stack_buffer) { 1462 uword* stack_buffer) {
1532 const CodeDescriptor* cd = clt.FindCode(At(0)); 1463 const CodeDescriptor* cd = clt.FindCode(At(0));
1533 if (cd == NULL) { 1464 if (cd == NULL) {
1534 // No Dart code. 1465 // No Dart code.
1535 return; 1466 return;
1536 } 1467 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 1529
1599 1530
1600 ProcessedSampleBuffer::ProcessedSampleBuffer() 1531 ProcessedSampleBuffer::ProcessedSampleBuffer()
1601 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { 1532 : code_lookup_table_(new CodeLookupTable(Thread::Current())) {
1602 ASSERT(code_lookup_table_ != NULL); 1533 ASSERT(code_lookup_table_ != NULL);
1603 } 1534 }
1604 1535
1605 #endif // !PRODUCT 1536 #endif // !PRODUCT
1606 1537
1607 } // namespace dart 1538 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler.h ('k') | runtime/vm/profiler_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698