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

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

Issue 2713803003: Revert "Updated MallocHooks to collect stack traces when memory is allocated." (Closed)
Patch Set: Created 3 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
« 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 161
162 Sample* SampleBuffer::ReserveSample() { 162 Sample* SampleBuffer::ReserveSample() {
163 return At(ReserveSampleSlot()); 163 return At(ReserveSampleSlot());
164 } 164 }
165 165
166 166
167 Sample* SampleBuffer::ReserveSampleAndLink(Sample* previous) { 167 Sample* SampleBuffer::ReserveSampleAndLink(Sample* previous) {
168 ASSERT(previous != NULL); 168 ASSERT(previous != NULL);
169 intptr_t next_index = ReserveSampleSlot(); 169 intptr_t next_index = ReserveSampleSlot();
170 Sample* next = At(next_index); 170 Sample* next = At(next_index);
171 next->Init(previous->port(), previous->timestamp(), previous->tid()); 171 next->Init(previous->isolate(), previous->timestamp(), previous->tid());
172 next->set_head_sample(false); 172 next->set_head_sample(false);
173 // Mark that previous continues at next. 173 // Mark that previous continues at next.
174 previous->SetContinuationIndex(next_index); 174 previous->SetContinuationIndex(next_index);
175 return next; 175 return next;
176 } 176 }
177 177
178 178
179 // Attempts to find the true return address when a Dart frame is being setup 179 // Attempts to find the true return address when a Dart frame is being setup
180 // or torn down. 180 // or torn down.
181 // NOTE: Architecture specific implementations below. 181 // NOTE: Architecture specific implementations below.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
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->main_port()) {} 324 : SampleVisitor(isolate) {}
325 325
326 326
327 void ClearProfileVisitor::VisitSample(Sample* sample) { 327 void ClearProfileVisitor::VisitSample(Sample* sample) {
328 sample->Clear(); 328 sample->Clear();
329 } 329 }
330 330
331 331
332 static void DumpStackFrame(intptr_t frame_index, uword pc) { 332 static void DumpStackFrame(intptr_t frame_index, uword pc) {
333 Isolate* isolate = Isolate::Current(); 333 Isolate* isolate = Isolate::Current();
334 if ((isolate != NULL) && isolate->is_runnable()) { 334 if ((isolate != NULL) && isolate->is_runnable()) {
(...skipping 15 matching lines...) Expand all
350 OS::PrintErr(" [0x%" Pp "] Unknown symbol\n", pc); 350 OS::PrintErr(" [0x%" Pp "] Unknown symbol\n", pc);
351 } else { 351 } else {
352 OS::PrintErr(" [0x%" Pp "] %s\n", pc, native_symbol_name); 352 OS::PrintErr(" [0x%" Pp "] %s\n", pc, native_symbol_name);
353 NativeSymbolResolver::FreeSymbolName(native_symbol_name); 353 NativeSymbolResolver::FreeSymbolName(native_symbol_name);
354 } 354 }
355 } 355 }
356 356
357 357
358 class ProfilerStackWalker : public ValueObject { 358 class ProfilerStackWalker : public ValueObject {
359 public: 359 public:
360 ProfilerStackWalker(Dart_Port port_id, 360 ProfilerStackWalker(Isolate* isolate,
361 Sample* head_sample, 361 Sample* head_sample,
362 SampleBuffer* sample_buffer, 362 SampleBuffer* sample_buffer)
363 intptr_t skip_count = 0) 363 : isolate_(isolate),
364 : port_id_(port_id),
365 sample_(head_sample), 364 sample_(head_sample),
366 sample_buffer_(sample_buffer), 365 sample_buffer_(sample_buffer),
367 skip_count_(skip_count),
368 frames_skipped_(0),
369 frame_index_(0), 366 frame_index_(0),
370 total_frames_(0) { 367 total_frames_(0) {
368 ASSERT(isolate_ != NULL);
371 if (sample_ == NULL) { 369 if (sample_ == NULL) {
372 ASSERT(sample_buffer_ == NULL); 370 ASSERT(sample_buffer_ == NULL);
373 } else { 371 } else {
374 ASSERT(sample_buffer_ != NULL); 372 ASSERT(sample_buffer_ != NULL);
375 ASSERT(sample_->head_sample()); 373 ASSERT(sample_->head_sample());
376 } 374 }
377 } 375 }
378 376
379 bool Append(uword pc) { 377 bool Append(uword pc) {
380 if (frames_skipped_ < skip_count_) {
381 frames_skipped_++;
382 return true;
383 }
384
385 if (sample_ == NULL) { 378 if (sample_ == NULL) {
386 DumpStackFrame(frame_index_, pc); 379 DumpStackFrame(frame_index_, pc);
387 frame_index_++; 380 frame_index_++;
388 total_frames_++; 381 total_frames_++;
389 return true; 382 return true;
390 } 383 }
391 if (total_frames_ >= FLAG_max_profile_depth) { 384 if (total_frames_ >= FLAG_max_profile_depth) {
392 sample_->set_truncated_trace(true); 385 sample_->set_truncated_trace(true);
393 return false; 386 return false;
394 } 387 }
395 ASSERT(sample_ != NULL); 388 ASSERT(sample_ != NULL);
396 if (frame_index_ == kSampleSize) { 389 if (frame_index_ == kSampleSize) {
397 Sample* new_sample = sample_buffer_->ReserveSampleAndLink(sample_); 390 Sample* new_sample = sample_buffer_->ReserveSampleAndLink(sample_);
398 if (new_sample == NULL) { 391 if (new_sample == NULL) {
399 // Could not reserve new sample- mark this as truncated. 392 // Could not reserve new sample- mark this as truncated.
400 sample_->set_truncated_trace(true); 393 sample_->set_truncated_trace(true);
401 return false; 394 return false;
402 } 395 }
403 frame_index_ = 0; 396 frame_index_ = 0;
404 sample_ = new_sample; 397 sample_ = new_sample;
405 } 398 }
406 ASSERT(frame_index_ < kSampleSize); 399 ASSERT(frame_index_ < kSampleSize);
407 sample_->SetAt(frame_index_, pc); 400 sample_->SetAt(frame_index_, pc);
408 frame_index_++; 401 frame_index_++;
409 total_frames_++; 402 total_frames_++;
410 return true; 403 return true;
411 } 404 }
412 405
413 protected: 406 protected:
414 Dart_Port port_id_; 407 Isolate* isolate_;
415 Sample* sample_; 408 Sample* sample_;
416 SampleBuffer* sample_buffer_; 409 SampleBuffer* sample_buffer_;
417 intptr_t skip_count_;
418 intptr_t frames_skipped_;
419 intptr_t frame_index_; 410 intptr_t frame_index_;
420 intptr_t total_frames_; 411 intptr_t total_frames_;
421 }; 412 };
422 413
423 414
424 // Executing Dart code, walk the stack. 415 // Executing Dart code, walk the stack.
425 class ProfilerDartStackWalker : public ProfilerStackWalker { 416 class ProfilerDartStackWalker : public ProfilerStackWalker {
426 public: 417 public:
427 ProfilerDartStackWalker(Thread* thread, 418 ProfilerDartStackWalker(Thread* thread,
428 Sample* sample, 419 Sample* sample,
429 SampleBuffer* sample_buffer, 420 SampleBuffer* sample_buffer,
430 uword stack_lower, 421 uword stack_lower,
431 uword stack_upper, 422 uword stack_upper,
432 uword pc, 423 uword pc,
433 uword fp, 424 uword fp,
434 uword sp, 425 uword sp,
435 bool exited_dart_code, 426 bool exited_dart_code,
436 bool allocation_sample, 427 bool allocation_sample)
437 intptr_t skip_count = 0) 428 : ProfilerStackWalker(thread->isolate(), sample, sample_buffer),
438 : ProfilerStackWalker((thread->isolate() != NULL)
439 ? thread->isolate()->main_port()
440 : ILLEGAL_PORT,
441 sample,
442 sample_buffer,
443 skip_count),
444 pc_(reinterpret_cast<uword*>(pc)), 429 pc_(reinterpret_cast<uword*>(pc)),
445 fp_(reinterpret_cast<uword*>(fp)), 430 fp_(reinterpret_cast<uword*>(fp)),
446 sp_(reinterpret_cast<uword*>(sp)), 431 sp_(reinterpret_cast<uword*>(sp)),
447 stack_upper_(stack_upper), 432 stack_upper_(stack_upper),
448 stack_lower_(stack_lower), 433 stack_lower_(stack_lower),
449 has_exit_frame_(exited_dart_code) { 434 has_exit_frame_(exited_dart_code) {
450 if (exited_dart_code) { 435 if (exited_dart_code) {
451 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, 436 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames,
452 thread); 437 thread);
453 pc_ = NULL; 438 pc_ = NULL;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 bool has_exit_frame_; 590 bool has_exit_frame_;
606 }; 591 };
607 592
608 593
609 // If the VM is compiled without frame pointers (which is the default on 594 // If the VM is compiled without frame pointers (which is the default on
610 // recent GCC versions with optimizing enabled) the stack walking code may 595 // recent GCC versions with optimizing enabled) the stack walking code may
611 // fail. 596 // fail.
612 // 597 //
613 class ProfilerNativeStackWalker : public ProfilerStackWalker { 598 class ProfilerNativeStackWalker : public ProfilerStackWalker {
614 public: 599 public:
615 ProfilerNativeStackWalker(Dart_Port port_id, 600 ProfilerNativeStackWalker(Isolate* isolate,
616 Sample* sample, 601 Sample* sample,
617 SampleBuffer* sample_buffer, 602 SampleBuffer* sample_buffer,
618 uword stack_lower, 603 uword stack_lower,
619 uword stack_upper, 604 uword stack_upper,
620 uword pc, 605 uword pc,
621 uword fp, 606 uword fp,
622 uword sp, 607 uword sp)
623 intptr_t skip_count = 0) 608 : ProfilerStackWalker(isolate, sample, sample_buffer),
624 : ProfilerStackWalker(port_id, sample, sample_buffer, skip_count),
625 stack_upper_(stack_upper), 609 stack_upper_(stack_upper),
626 original_pc_(pc), 610 original_pc_(pc),
627 original_fp_(fp), 611 original_fp_(fp),
628 original_sp_(sp), 612 original_sp_(sp),
629 lower_bound_(stack_lower) {} 613 lower_bound_(stack_lower) {}
630 614
631 void walk() { 615 void walk() {
632 const uword kMaxStep = VirtualMemory::PageSize(); 616 const uword kMaxStep = VirtualMemory::PageSize();
633
634 Append(original_pc_); 617 Append(original_pc_);
635 618
636 uword* pc = reinterpret_cast<uword*>(original_pc_); 619 uword* pc = reinterpret_cast<uword*>(original_pc_);
637 uword* fp = reinterpret_cast<uword*>(original_fp_); 620 uword* fp = reinterpret_cast<uword*>(original_fp_);
638 uword* previous_fp = fp; 621 uword* previous_fp = fp;
639 622
640 uword gap = original_fp_ - original_sp_; 623 uword gap = original_fp_ - original_sp_;
641 if (gap >= kMaxStep) { 624 if (gap >= kMaxStep) {
642 // Gap between frame pointer and stack pointer is 625 // Gap between frame pointer and stack pointer is
643 // too large. 626 // too large.
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 VirtualProtect(reinterpret_cast<void*>(fault_address), 789 VirtualProtect(reinterpret_cast<void*>(fault_address),
807 sizeof(fault_address), new_protect, &old_protect); 790 sizeof(fault_address), new_protect, &old_protect);
808 USE(success); 791 USE(success);
809 ASSERT(success); 792 ASSERT(success);
810 ASSERT(old_protect == PAGE_READWRITE); 793 ASSERT(old_protect == PAGE_READWRITE);
811 } 794 }
812 #endif 795 #endif
813 } 796 }
814 797
815 798
816 static bool ValidateThreadStackBounds(uintptr_t fp,
817 uintptr_t sp,
818 uword stack_lower,
819 uword stack_upper) {
820 if (stack_lower >= stack_upper) {
821 // Stack boundary is invalid.
822 return false;
823 }
824
825 if ((sp < stack_lower) || (sp >= stack_upper)) {
826 // Stack pointer is outside thread's stack boundary.
827 return false;
828 }
829
830 if ((fp < stack_lower) || (fp >= stack_upper)) {
831 // Frame pointer is outside threads's stack boundary.
832 return false;
833 }
834
835 return true;
836 }
837
838
839 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within 799 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within
840 // it. If |get_os_thread_bounds| is true then if |isolate| stackbounds are 800 // it. If |get_os_thread_bounds| is true then if |isolate| stackbounds are
841 // not available we fallback to using underlying OS thread bounds. This only 801 // not available we fallback to using underlying OS thread bounds. This only
842 // works for the current thread. 802 // works for the current thread.
843 // Return |false| if anything looks suspicious. 803 // Return |false| if anything looks suspicious.
844 static bool GetAndValidateThreadStackBounds(Thread* thread, 804 static bool GetAndValidateThreadStackBounds(Thread* thread,
845 uintptr_t fp, 805 uintptr_t fp,
846 uintptr_t sp, 806 uintptr_t sp,
847 uword* stack_lower, 807 uword* stack_lower,
848 uword* stack_upper, 808 uword* stack_upper,
849 bool get_os_thread_bounds = false) { 809 bool get_os_thread_bounds = false) {
850 OSThread* os_thread = NULL; 810 ASSERT(thread != NULL);
851 if (thread != NULL) { 811 OSThread* os_thread = thread->os_thread();
852 os_thread = thread->os_thread();
853 } else {
854 os_thread = OSThread::Current();
855 }
856 ASSERT(os_thread != NULL); 812 ASSERT(os_thread != NULL);
857 ASSERT(stack_lower != NULL); 813 ASSERT(stack_lower != NULL);
858 ASSERT(stack_upper != NULL); 814 ASSERT(stack_upper != NULL);
859 ASSERT(!get_os_thread_bounds || (Thread::Current() == thread)); 815 ASSERT(!get_os_thread_bounds || (Thread::Current() == thread));
860 816
861 #if defined(USING_SIMULATOR) 817 #if defined(USING_SIMULATOR)
862 const bool use_simulator_stack_bounds = thread->IsExecutingDartCode(); 818 const bool use_simulator_stack_bounds = thread->IsExecutingDartCode();
863 if (use_simulator_stack_bounds) { 819 if (use_simulator_stack_bounds) {
864 Isolate* isolate = thread->isolate(); 820 Isolate* isolate = thread->isolate();
865 ASSERT(isolate != NULL); 821 ASSERT(isolate != NULL);
(...skipping 15 matching lines...) Expand all
881 837
882 if ((*stack_lower == 0) || (*stack_upper == 0)) { 838 if ((*stack_lower == 0) || (*stack_upper == 0)) {
883 return false; 839 return false;
884 } 840 }
885 841
886 if (!use_simulator_stack_bounds && (sp > *stack_lower)) { 842 if (!use_simulator_stack_bounds && (sp > *stack_lower)) {
887 // The stack pointer gives us a tighter lower bound. 843 // The stack pointer gives us a tighter lower bound.
888 *stack_lower = sp; 844 *stack_lower = sp;
889 } 845 }
890 846
891 return ValidateThreadStackBounds(fp, sp, *stack_lower, *stack_upper); 847 if (*stack_lower >= *stack_upper) {
848 // Stack boundary is invalid.
849 return false;
850 }
851
852 if ((sp < *stack_lower) || (sp >= *stack_upper)) {
853 // Stack pointer is outside thread's stack boundary.
854 return false;
855 }
856
857 if ((fp < *stack_lower) || (fp >= *stack_upper)) {
858 // Frame pointer is outside threads's stack boundary.
859 return false;
860 }
861
862 return true;
892 } 863 }
893 864
894 865
895 // Some simple sanity checking of |pc|, |fp|, and |sp|. 866 // Some simple sanity checking of |pc|, |fp|, and |sp|.
896 static bool InitialRegisterCheck(uintptr_t pc, uintptr_t fp, uintptr_t sp) { 867 static bool InitialRegisterCheck(uintptr_t pc, uintptr_t fp, uintptr_t sp) {
897 if ((sp == 0) || (fp == 0) || (pc == 0)) { 868 if ((sp == 0) || (fp == 0) || (pc == 0)) {
898 // None of these registers should be zero. 869 // None of these registers should be zero.
899 return false; 870 return false;
900 } 871 }
901 872
902 if (sp > fp) { 873 if (sp > fp) {
903 // Assuming the stack grows down, we should never have a stack pointer above 874 // Assuming the stack grows down, we should never have a stack pointer above
904 // the frame pointer. 875 // the frame pointer.
905 return false; 876 return false;
906 } 877 }
907 878
908 return true; 879 return true;
909 } 880 }
910 881
911 882
912 static Sample* SetupSample(Thread* thread, 883 static Sample* SetupSample(Thread* thread,
913 SampleBuffer* sample_buffer, 884 SampleBuffer* sample_buffer,
914 ThreadId tid) { 885 ThreadId tid) {
915 ASSERT(thread != NULL); 886 ASSERT(thread != NULL);
916 Isolate* isolate = thread->isolate(); 887 Isolate* isolate = thread->isolate();
917 ASSERT(sample_buffer != NULL); 888 ASSERT(sample_buffer != NULL);
918 Sample* sample = sample_buffer->ReserveSample(); 889 Sample* sample = sample_buffer->ReserveSample();
919 sample->Init(isolate->main_port(), OS::GetCurrentMonotonicMicros(), tid); 890 sample->Init(isolate, OS::GetCurrentMonotonicMicros(), tid);
920 uword vm_tag = thread->vm_tag(); 891 uword vm_tag = thread->vm_tag();
921 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) 892 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC)
922 // When running in the simulator, the runtime entry function address 893 // When running in the simulator, the runtime entry function address
923 // (stored as the vm tag) is the address of a redirect function. 894 // (stored as the vm tag) is the address of a redirect function.
924 // Attempt to find the real runtime entry function address and use that. 895 // Attempt to find the real runtime entry function address and use that.
925 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag); 896 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag);
926 if (redirect_vm_tag != 0) { 897 if (redirect_vm_tag != 0) {
927 vm_tag = redirect_vm_tag; 898 vm_tag = redirect_vm_tag;
928 } 899 }
929 #endif 900 #endif
930 sample->set_vm_tag(vm_tag); 901 sample->set_vm_tag(vm_tag);
931 sample->set_user_tag(isolate->user_tag()); 902 sample->set_user_tag(isolate->user_tag());
932 sample->set_thread_task(thread->task_kind()); 903 sample->set_thread_task(thread->task_kind());
933 return sample; 904 return sample;
934 } 905 }
935 906
936 907
937 static Sample* SetupSampleNative(SampleBuffer* sample_buffer, ThreadId tid) {
938 Sample* sample = sample_buffer->ReserveSample();
939 sample->Init(ILLEGAL_PORT, OS::GetCurrentMonotonicMicros(), tid);
940 sample->set_is_native_allocation_sample(true);
941
942 Thread* thread = Thread::Current();
943
944 // TODO(bkonyi) Any samples created while a current thread doesn't exist are
945 // ignored by the NativeAllocationSampleFilter since the default task is
946 // kUnknownTask. Is this what we want to do?
947 if (thread != NULL) {
948 sample->set_thread_task(thread->task_kind());
949 }
950 return sample;
951 }
952
953
954 static bool CheckIsolate(Isolate* isolate) { 908 static bool CheckIsolate(Isolate* isolate) {
955 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { 909 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) {
956 // No isolate. 910 // No isolate.
957 return false; 911 return false;
958 } 912 }
959 return isolate != Dart::vm_isolate(); 913 return isolate != Dart::vm_isolate();
960 } 914 }
961 915
962 916
917 #if defined(TARGET_OS_WINDOWS)
918 __declspec(noinline) static uintptr_t GetProgramCounter() {
919 return reinterpret_cast<uintptr_t>(_ReturnAddress());
920 }
921 #else
922 static uintptr_t __attribute__((noinline)) GetProgramCounter() {
923 return reinterpret_cast<uintptr_t>(
924 __builtin_extract_return_addr(__builtin_return_address(0)));
925 }
926 #endif
927
928
963 void Profiler::DumpStackTrace(void* context) { 929 void Profiler::DumpStackTrace(void* context) {
964 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) 930 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS)
965 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 931 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
966 mcontext_t mcontext = ucontext->uc_mcontext; 932 mcontext_t mcontext = ucontext->uc_mcontext;
967 uword pc = SignalHandler::GetProgramCounter(mcontext); 933 uword pc = SignalHandler::GetProgramCounter(mcontext);
968 uword fp = SignalHandler::GetFramePointer(mcontext); 934 uword fp = SignalHandler::GetFramePointer(mcontext);
969 uword sp = SignalHandler::GetCStackPointer(mcontext); 935 uword sp = SignalHandler::GetCStackPointer(mcontext);
970 DumpStackTrace(sp, fp, pc); 936 DumpStackTrace(sp, fp, pc);
971 #else 937 #else
972 // TODO(fschneider): Add support for more platforms. 938 // TODO(fschneider): Add support for more platforms.
973 // Do nothing on unsupported platforms. 939 // Do nothing on unsupported platforms.
974 #endif 940 #endif
975 } 941 }
976 942
977 943
978 void Profiler::DumpStackTrace() { 944 void Profiler::DumpStackTrace() {
979 uintptr_t sp = Thread::GetCurrentStackPointer(); 945 uintptr_t sp = Thread::GetCurrentStackPointer();
980 uintptr_t fp = 0; 946 uintptr_t fp = 0;
981 uintptr_t pc = OS::GetProgramCounter(); 947 uintptr_t pc = GetProgramCounter();
982 948
983 COPY_FP_REGISTER(fp); 949 COPY_FP_REGISTER(fp);
984 950
985 DumpStackTrace(sp, fp, pc); 951 DumpStackTrace(sp, fp, pc);
986 } 952 }
987 953
988 954
989 void Profiler::DumpStackTrace(uword sp, uword fp, uword pc) { 955 void Profiler::DumpStackTrace(uword sp, uword fp, uword pc) {
990 // Allow only one stack trace to prevent recursively printing stack traces if 956 // Allow only one stack trace to prevent recursively printing stack traces if
991 // we hit an assert while printing the stack. 957 // we hit an assert while printing the stack.
(...skipping 27 matching lines...) Expand all
1019 985
1020 if (!GetAndValidateThreadStackBounds(thread, fp, sp, &stack_lower, 986 if (!GetAndValidateThreadStackBounds(thread, fp, sp, &stack_lower,
1021 &stack_upper, 987 &stack_upper,
1022 /*get_os_thread_bounds=*/true)) { 988 /*get_os_thread_bounds=*/true)) {
1023 OS::PrintErr( 989 OS::PrintErr(
1024 "Stack dump aborted because GetAndValidateThreadStackBounds.\n"); 990 "Stack dump aborted because GetAndValidateThreadStackBounds.\n");
1025 return; 991 return;
1026 } 992 }
1027 993
1028 ProfilerNativeStackWalker native_stack_walker( 994 ProfilerNativeStackWalker native_stack_walker(
1029 (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, NULL, NULL, 995 isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp);
1030 stack_lower, stack_upper, pc, fp, sp);
1031 native_stack_walker.walk(); 996 native_stack_walker.walk();
1032 OS::PrintErr("-- End of DumpStackTrace\n"); 997 OS::PrintErr("-- End of DumpStackTrace\n");
1033 } 998 }
1034 999
1035 1000
1036 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { 1001 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) {
1037 ASSERT(thread != NULL); 1002 ASSERT(thread != NULL);
1038 OSThread* os_thread = thread->os_thread(); 1003 OSThread* os_thread = thread->os_thread();
1039 ASSERT(os_thread != NULL); 1004 ASSERT(os_thread != NULL);
1040 Isolate* isolate = thread->isolate(); 1005 Isolate* isolate = thread->isolate();
1041 if (!CheckIsolate(isolate)) { 1006 if (!CheckIsolate(isolate)) {
1042 return; 1007 return;
1043 } 1008 }
1044 1009
1045 const bool exited_dart_code = thread->HasExitedDartCode(); 1010 const bool exited_dart_code = thread->HasExitedDartCode();
1046 1011
1047 SampleBuffer* sample_buffer = Profiler::sample_buffer(); 1012 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1048 if (sample_buffer == NULL) { 1013 if (sample_buffer == NULL) {
1049 // Profiler not initialized. 1014 // Profiler not initialized.
1050 return; 1015 return;
1051 } 1016 }
1052 1017
1053 uintptr_t sp = Thread::GetCurrentStackPointer(); 1018 uintptr_t sp = Thread::GetCurrentStackPointer();
1054 uintptr_t fp = 0; 1019 uintptr_t fp = 0;
1055 uintptr_t pc = OS::GetProgramCounter(); 1020 uintptr_t pc = GetProgramCounter();
1056 1021
1057 COPY_FP_REGISTER(fp); 1022 COPY_FP_REGISTER(fp);
1058 1023
1059 uword stack_lower = 0; 1024 uword stack_lower = 0;
1060 uword stack_upper = 0; 1025 uword stack_upper = 0;
1061 1026
1062 if (!InitialRegisterCheck(pc, fp, sp)) { 1027 if (!InitialRegisterCheck(pc, fp, sp)) {
1063 return; 1028 return;
1064 } 1029 }
1065 1030
1066 if (!GetAndValidateThreadStackBounds(thread, fp, sp, &stack_lower, 1031 if (!GetAndValidateThreadStackBounds(thread, fp, sp, &stack_lower,
1067 &stack_upper)) { 1032 &stack_upper)) {
1068 // Could not get stack boundary. 1033 // Could not get stack boundary.
1069 return; 1034 return;
1070 } 1035 }
1071 1036
1072 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1037 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1073 sample->SetAllocationCid(cid); 1038 sample->SetAllocationCid(cid);
1074 1039
1075 if (FLAG_profile_vm) { 1040 if (FLAG_profile_vm) {
1076 ProfilerNativeStackWalker native_stack_walker( 1041 ProfilerNativeStackWalker native_stack_walker(
1077 (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, sample, 1042 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1078 sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1079 native_stack_walker.walk(); 1043 native_stack_walker.walk();
1080 } else if (exited_dart_code) { 1044 } else if (exited_dart_code) {
1081 ProfilerDartStackWalker dart_exit_stack_walker( 1045 ProfilerDartStackWalker dart_exit_stack_walker(
1082 thread, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp, 1046 thread, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp,
1083 exited_dart_code, true); 1047 exited_dart_code, true);
1084 dart_exit_stack_walker.walk(); 1048 dart_exit_stack_walker.walk();
1085 } else { 1049 } else {
1086 // Fall back. 1050 // Fall back.
1087 uintptr_t pc = OS::GetProgramCounter(); 1051 uintptr_t pc = GetProgramCounter();
1088 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1052 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1089 sample->SetAllocationCid(cid); 1053 sample->SetAllocationCid(cid);
1090 sample->SetAt(0, pc); 1054 sample->SetAt(0, pc);
1091 } 1055 }
1092 } 1056 }
1093 1057
1094 1058
1095 Sample* Profiler::SampleNativeAllocation(intptr_t skip_count) {
1096 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1097 if (sample_buffer == NULL) {
1098 return NULL;
1099 }
1100
1101 uintptr_t sp = Thread::GetCurrentStackPointer();
1102 uintptr_t fp = 0;
1103 uintptr_t pc = OS::GetProgramCounter();
1104
1105 COPY_FP_REGISTER(fp);
1106
1107 uword stack_lower = 0;
1108 uword stack_upper = 0;
1109 if (!InitialRegisterCheck(pc, fp, sp)) {
1110 AtomicOperations::IncrementInt64By(
1111 &counters_.failure_native_allocation_sample, 1);
1112 return NULL;
1113 }
1114
1115 if (!(OSThread::GetCurrentStackBounds(&stack_lower, &stack_upper) &&
1116 ValidateThreadStackBounds(fp, sp, stack_lower, stack_upper))) {
1117 // Could not get stack boundary.
1118 AtomicOperations::IncrementInt64By(
1119 &counters_.failure_native_allocation_sample, 1);
1120 return NULL;
1121 }
1122
1123 OSThread* os_thread = OSThread::Current();
1124 Sample* sample = SetupSampleNative(sample_buffer, os_thread->trace_id());
1125 ProfilerNativeStackWalker native_stack_walker(
1126 ILLEGAL_PORT, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp,
1127 skip_count);
1128 native_stack_walker.walk();
1129 return sample;
1130 }
1131
1132
1133 void Profiler::SampleThreadSingleFrame(Thread* thread, uintptr_t pc) { 1059 void Profiler::SampleThreadSingleFrame(Thread* thread, uintptr_t pc) {
1134 ASSERT(thread != NULL); 1060 ASSERT(thread != NULL);
1135 OSThread* os_thread = thread->os_thread(); 1061 OSThread* os_thread = thread->os_thread();
1136 ASSERT(os_thread != NULL); 1062 ASSERT(os_thread != NULL);
1137 Isolate* isolate = thread->isolate(); 1063 Isolate* isolate = thread->isolate();
1138 1064
1139 SampleBuffer* sample_buffer = Profiler::sample_buffer(); 1065 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1140 if (sample_buffer == NULL) { 1066 if (sample_buffer == NULL) {
1141 // Profiler not initialized. 1067 // Profiler not initialized.
1142 return; 1068 return;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 // Setup sample. 1174 // Setup sample.
1249 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1175 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1250 // Increment counter for vm tag. 1176 // Increment counter for vm tag.
1251 VMTagCounters* counters = isolate->vm_tag_counters(); 1177 VMTagCounters* counters = isolate->vm_tag_counters();
1252 ASSERT(counters != NULL); 1178 ASSERT(counters != NULL);
1253 if (thread->IsMutatorThread()) { 1179 if (thread->IsMutatorThread()) {
1254 counters->Increment(sample->vm_tag()); 1180 counters->Increment(sample->vm_tag());
1255 } 1181 }
1256 1182
1257 ProfilerNativeStackWalker native_stack_walker( 1183 ProfilerNativeStackWalker native_stack_walker(
1258 (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, sample, 1184 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1259 sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1260 const bool exited_dart_code = thread->HasExitedDartCode(); 1185 const bool exited_dart_code = thread->HasExitedDartCode();
1261 ProfilerDartStackWalker dart_stack_walker(thread, sample, sample_buffer, 1186 ProfilerDartStackWalker dart_stack_walker(thread, sample, sample_buffer,
1262 stack_lower, stack_upper, pc, fp, 1187 stack_lower, stack_upper, pc, fp,
1263 sp, exited_dart_code, false); 1188 sp, exited_dart_code, false);
1264 1189
1265 // All memory access is done inside CollectSample. 1190 // All memory access is done inside CollectSample.
1266 CollectSample(isolate, exited_dart_code, in_dart_code, sample, 1191 CollectSample(isolate, exited_dart_code, in_dart_code, sample,
1267 &native_stack_walker, &dart_stack_walker, pc, fp, sp, 1192 &native_stack_walker, &dart_stack_walker, pc, fp, sp,
1268 &counters_); 1193 &counters_);
1269 } 1194 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 for (intptr_t i = 0; i < length; i++) { 1334 for (intptr_t i = 0; i < length; i++) {
1410 Sample* sample = At(i); 1335 Sample* sample = At(i);
1411 if (sample->ignore_sample()) { 1336 if (sample->ignore_sample()) {
1412 // Bad sample. 1337 // Bad sample.
1413 continue; 1338 continue;
1414 } 1339 }
1415 if (!sample->head_sample()) { 1340 if (!sample->head_sample()) {
1416 // An inner sample in a chain of samples. 1341 // An inner sample in a chain of samples.
1417 continue; 1342 continue;
1418 } 1343 }
1419 // If we're requesting all the native allocation samples, we don't care 1344 if (sample->isolate() != filter->isolate()) {
1420 // whether or not we're in the same isolate as the sample.
1421 if (sample->port() != filter->port()) {
1422 // Another isolate. 1345 // Another isolate.
1423 continue; 1346 continue;
1424 } 1347 }
1425 if (sample->timestamp() == 0) { 1348 if (sample->timestamp() == 0) {
1426 // Empty. 1349 // Empty.
1427 continue; 1350 continue;
1428 } 1351 }
1429 if (sample->At(0) == 0) { 1352 if (sample->At(0) == 0) {
1430 // No frames. 1353 // No frames.
1431 continue; 1354 continue;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1490 return processed_sample; 1413 return processed_sample;
1491 } 1414 }
1492 1415
1493 1416
1494 Sample* SampleBuffer::Next(Sample* sample) { 1417 Sample* SampleBuffer::Next(Sample* sample) {
1495 if (!sample->is_continuation_sample()) return NULL; 1418 if (!sample->is_continuation_sample()) return NULL;
1496 Sample* next_sample = At(sample->continuation_index()); 1419 Sample* next_sample = At(sample->continuation_index());
1497 // Sanity check. 1420 // Sanity check.
1498 ASSERT(sample != next_sample); 1421 ASSERT(sample != next_sample);
1499 // Detect invalid chaining. 1422 // Detect invalid chaining.
1500 if (sample->port() != next_sample->port()) { 1423 if (sample->isolate() != next_sample->isolate()) {
1501 return NULL; 1424 return NULL;
1502 } 1425 }
1503 if (sample->timestamp() != next_sample->timestamp()) { 1426 if (sample->timestamp() != next_sample->timestamp()) {
1504 return NULL; 1427 return NULL;
1505 } 1428 }
1506 if (sample->tid() != next_sample->tid()) { 1429 if (sample->tid() != next_sample->tid()) {
1507 return NULL; 1430 return NULL;
1508 } 1431 }
1509 return next_sample; 1432 return next_sample;
1510 } 1433 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 1515
1593 1516
1594 ProcessedSampleBuffer::ProcessedSampleBuffer() 1517 ProcessedSampleBuffer::ProcessedSampleBuffer()
1595 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { 1518 : code_lookup_table_(new CodeLookupTable(Thread::Current())) {
1596 ASSERT(code_lookup_table_ != NULL); 1519 ASSERT(code_lookup_table_ != NULL);
1597 } 1520 }
1598 1521
1599 #endif // !PRODUCT 1522 #endif // !PRODUCT
1600 1523
1601 } // namespace dart 1524 } // 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