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

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

Issue 2680213002: Updated MallocHooks to collect stack traces when memory is allocated. (Closed)
Patch Set: Updated MallocHooks to collect stack traces when memory is allocated. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/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->isolate(), previous->timestamp(), previous->tid()); 171 next->Init(previous->port(), 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) {} 324 : SampleVisitor(isolate->main_port()) {}
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(Isolate* isolate, 360 ProfilerStackWalker(Dart_Port port_id,
361 Sample* head_sample, 361 Sample* head_sample,
362 SampleBuffer* sample_buffer) 362 SampleBuffer* sample_buffer,
363 : isolate_(isolate), 363 intptr_t skip_count = 0)
364 : port_id_(port_id),
364 sample_(head_sample), 365 sample_(head_sample),
365 sample_buffer_(sample_buffer), 366 sample_buffer_(sample_buffer),
367 skip_count_(skip_count),
368 frames_skipped_(0),
366 frame_index_(0), 369 frame_index_(0),
367 total_frames_(0) { 370 total_frames_(0) {
368 ASSERT(isolate_ != NULL);
369 if (sample_ == NULL) { 371 if (sample_ == NULL) {
370 ASSERT(sample_buffer_ == NULL); 372 ASSERT(sample_buffer_ == NULL);
371 } else { 373 } else {
372 ASSERT(sample_buffer_ != NULL); 374 ASSERT(sample_buffer_ != NULL);
373 ASSERT(sample_->head_sample()); 375 ASSERT(sample_->head_sample());
374 } 376 }
375 } 377 }
376 378
377 bool Append(uword pc) { 379 bool Append(uword pc) {
380 if (frames_skipped_ < skip_count_) {
381 frames_skipped_++;
382 return true;
383 }
384
378 if (sample_ == NULL) { 385 if (sample_ == NULL) {
379 DumpStackFrame(frame_index_, pc); 386 DumpStackFrame(frame_index_, pc);
380 frame_index_++; 387 frame_index_++;
381 total_frames_++; 388 total_frames_++;
382 return true; 389 return true;
383 } 390 }
384 if (total_frames_ >= FLAG_max_profile_depth) { 391 if (total_frames_ >= FLAG_max_profile_depth) {
385 sample_->set_truncated_trace(true); 392 sample_->set_truncated_trace(true);
386 return false; 393 return false;
387 } 394 }
388 ASSERT(sample_ != NULL); 395 ASSERT(sample_ != NULL);
389 if (frame_index_ == kSampleSize) { 396 if (frame_index_ == kSampleSize) {
390 Sample* new_sample = sample_buffer_->ReserveSampleAndLink(sample_); 397 Sample* new_sample = sample_buffer_->ReserveSampleAndLink(sample_);
391 if (new_sample == NULL) { 398 if (new_sample == NULL) {
392 // Could not reserve new sample- mark this as truncated. 399 // Could not reserve new sample- mark this as truncated.
393 sample_->set_truncated_trace(true); 400 sample_->set_truncated_trace(true);
394 return false; 401 return false;
395 } 402 }
396 frame_index_ = 0; 403 frame_index_ = 0;
397 sample_ = new_sample; 404 sample_ = new_sample;
398 } 405 }
399 ASSERT(frame_index_ < kSampleSize); 406 ASSERT(frame_index_ < kSampleSize);
400 sample_->SetAt(frame_index_, pc); 407 sample_->SetAt(frame_index_, pc);
401 frame_index_++; 408 frame_index_++;
402 total_frames_++; 409 total_frames_++;
403 return true; 410 return true;
404 } 411 }
405 412
406 protected: 413 protected:
407 Isolate* isolate_; 414 Dart_Port port_id_;
408 Sample* sample_; 415 Sample* sample_;
409 SampleBuffer* sample_buffer_; 416 SampleBuffer* sample_buffer_;
417 intptr_t skip_count_;
418 intptr_t frames_skipped_;
410 intptr_t frame_index_; 419 intptr_t frame_index_;
411 intptr_t total_frames_; 420 intptr_t total_frames_;
412 }; 421 };
413 422
414 423
415 // Executing Dart code, walk the stack. 424 // Executing Dart code, walk the stack.
416 class ProfilerDartStackWalker : public ProfilerStackWalker { 425 class ProfilerDartStackWalker : public ProfilerStackWalker {
417 public: 426 public:
418 ProfilerDartStackWalker(Thread* thread, 427 ProfilerDartStackWalker(Thread* thread,
419 Sample* sample, 428 Sample* sample,
420 SampleBuffer* sample_buffer, 429 SampleBuffer* sample_buffer,
421 uword stack_lower, 430 uword stack_lower,
422 uword stack_upper, 431 uword stack_upper,
423 uword pc, 432 uword pc,
424 uword fp, 433 uword fp,
425 uword sp, 434 uword sp,
426 bool exited_dart_code, 435 bool exited_dart_code,
427 bool allocation_sample) 436 bool allocation_sample,
428 : ProfilerStackWalker(thread->isolate(), sample, sample_buffer), 437 intptr_t skip_count = 0)
438 : ProfilerStackWalker((thread->isolate() != NULL)
439 ? thread->isolate()->main_port()
440 : ILLEGAL_PORT,
441 sample,
442 sample_buffer,
443 skip_count),
429 pc_(reinterpret_cast<uword*>(pc)), 444 pc_(reinterpret_cast<uword*>(pc)),
430 fp_(reinterpret_cast<uword*>(fp)), 445 fp_(reinterpret_cast<uword*>(fp)),
431 sp_(reinterpret_cast<uword*>(sp)), 446 sp_(reinterpret_cast<uword*>(sp)),
432 stack_upper_(stack_upper), 447 stack_upper_(stack_upper),
433 stack_lower_(stack_lower), 448 stack_lower_(stack_lower),
434 has_exit_frame_(exited_dart_code) { 449 has_exit_frame_(exited_dart_code) {
435 if (exited_dart_code) { 450 if (exited_dart_code) {
436 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, 451 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames,
437 thread); 452 thread);
438 pc_ = NULL; 453 pc_ = NULL;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 bool has_exit_frame_; 605 bool has_exit_frame_;
591 }; 606 };
592 607
593 608
594 // If the VM is compiled without frame pointers (which is the default on 609 // If the VM is compiled without frame pointers (which is the default on
595 // recent GCC versions with optimizing enabled) the stack walking code may 610 // recent GCC versions with optimizing enabled) the stack walking code may
596 // fail. 611 // fail.
597 // 612 //
598 class ProfilerNativeStackWalker : public ProfilerStackWalker { 613 class ProfilerNativeStackWalker : public ProfilerStackWalker {
599 public: 614 public:
600 ProfilerNativeStackWalker(Isolate* isolate, 615 ProfilerNativeStackWalker(Dart_Port port_id,
601 Sample* sample, 616 Sample* sample,
602 SampleBuffer* sample_buffer, 617 SampleBuffer* sample_buffer,
603 uword stack_lower, 618 uword stack_lower,
604 uword stack_upper, 619 uword stack_upper,
605 uword pc, 620 uword pc,
606 uword fp, 621 uword fp,
607 uword sp) 622 uword sp,
608 : ProfilerStackWalker(isolate, sample, sample_buffer), 623 intptr_t skip_count = 0)
624 : ProfilerStackWalker(port_id, sample, sample_buffer, skip_count),
609 stack_upper_(stack_upper), 625 stack_upper_(stack_upper),
610 original_pc_(pc), 626 original_pc_(pc),
611 original_fp_(fp), 627 original_fp_(fp),
612 original_sp_(sp), 628 original_sp_(sp),
613 lower_bound_(stack_lower) {} 629 lower_bound_(stack_lower) {}
614 630
615 void walk() { 631 void walk() {
616 const uword kMaxStep = VirtualMemory::PageSize(); 632 const uword kMaxStep = VirtualMemory::PageSize();
633
617 Append(original_pc_); 634 Append(original_pc_);
618 635
619 uword* pc = reinterpret_cast<uword*>(original_pc_); 636 uword* pc = reinterpret_cast<uword*>(original_pc_);
620 uword* fp = reinterpret_cast<uword*>(original_fp_); 637 uword* fp = reinterpret_cast<uword*>(original_fp_);
621 uword* previous_fp = fp; 638 uword* previous_fp = fp;
622 639
623 uword gap = original_fp_ - original_sp_; 640 uword gap = original_fp_ - original_sp_;
624 if (gap >= kMaxStep) { 641 if (gap >= kMaxStep) {
625 // Gap between frame pointer and stack pointer is 642 // Gap between frame pointer and stack pointer is
626 // too large. 643 // too large.
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 // it. If |get_os_thread_bounds| is true then if |isolate| stackbounds are 817 // it. If |get_os_thread_bounds| is true then if |isolate| stackbounds are
801 // not available we fallback to using underlying OS thread bounds. This only 818 // not available we fallback to using underlying OS thread bounds. This only
802 // works for the current thread. 819 // works for the current thread.
803 // Return |false| if anything looks suspicious. 820 // Return |false| if anything looks suspicious.
804 static bool GetAndValidateThreadStackBounds(Thread* thread, 821 static bool GetAndValidateThreadStackBounds(Thread* thread,
805 uintptr_t fp, 822 uintptr_t fp,
806 uintptr_t sp, 823 uintptr_t sp,
807 uword* stack_lower, 824 uword* stack_lower,
808 uword* stack_upper, 825 uword* stack_upper,
809 bool get_os_thread_bounds = false) { 826 bool get_os_thread_bounds = false) {
810 ASSERT(thread != NULL); 827 OSThread* os_thread = NULL;
811 OSThread* os_thread = thread->os_thread(); 828 if (thread != NULL) {
829 os_thread = thread->os_thread();
830 } else {
831 os_thread = OSThread::Current();
832 }
812 ASSERT(os_thread != NULL); 833 ASSERT(os_thread != NULL);
813 ASSERT(stack_lower != NULL); 834 ASSERT(stack_lower != NULL);
814 ASSERT(stack_upper != NULL); 835 ASSERT(stack_upper != NULL);
815 ASSERT(!get_os_thread_bounds || (Thread::Current() == thread)); 836 ASSERT(!get_os_thread_bounds || (Thread::Current() == thread));
816 837
817 #if defined(USING_SIMULATOR) 838 #if defined(USING_SIMULATOR)
818 const bool use_simulator_stack_bounds = thread->IsExecutingDartCode(); 839 const bool use_simulator_stack_bounds = thread->IsExecutingDartCode();
819 if (use_simulator_stack_bounds) { 840 if (use_simulator_stack_bounds) {
820 Isolate* isolate = thread->isolate(); 841 Isolate* isolate = thread->isolate();
821 ASSERT(isolate != NULL); 842 ASSERT(isolate != NULL);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 } 901 }
881 902
882 903
883 static Sample* SetupSample(Thread* thread, 904 static Sample* SetupSample(Thread* thread,
884 SampleBuffer* sample_buffer, 905 SampleBuffer* sample_buffer,
885 ThreadId tid) { 906 ThreadId tid) {
886 ASSERT(thread != NULL); 907 ASSERT(thread != NULL);
887 Isolate* isolate = thread->isolate(); 908 Isolate* isolate = thread->isolate();
888 ASSERT(sample_buffer != NULL); 909 ASSERT(sample_buffer != NULL);
889 Sample* sample = sample_buffer->ReserveSample(); 910 Sample* sample = sample_buffer->ReserveSample();
890 sample->Init(isolate, OS::GetCurrentMonotonicMicros(), tid); 911 sample->Init(isolate->main_port(), OS::GetCurrentMonotonicMicros(), tid);
891 uword vm_tag = thread->vm_tag(); 912 uword vm_tag = thread->vm_tag();
892 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) 913 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC)
893 // When running in the simulator, the runtime entry function address 914 // When running in the simulator, the runtime entry function address
894 // (stored as the vm tag) is the address of a redirect function. 915 // (stored as the vm tag) is the address of a redirect function.
895 // Attempt to find the real runtime entry function address and use that. 916 // Attempt to find the real runtime entry function address and use that.
896 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag); 917 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag);
897 if (redirect_vm_tag != 0) { 918 if (redirect_vm_tag != 0) {
898 vm_tag = redirect_vm_tag; 919 vm_tag = redirect_vm_tag;
899 } 920 }
900 #endif 921 #endif
901 sample->set_vm_tag(vm_tag); 922 sample->set_vm_tag(vm_tag);
902 sample->set_user_tag(isolate->user_tag()); 923 sample->set_user_tag(isolate->user_tag());
903 sample->set_thread_task(thread->task_kind()); 924 sample->set_thread_task(thread->task_kind());
904 return sample; 925 return sample;
905 } 926 }
906 927
907 928
929 static Sample* SetupSampleNative(SampleBuffer* sample_buffer, ThreadId tid) {
930 Sample* sample = sample_buffer->ReserveSample();
931 sample->Init(ILLEGAL_PORT, OS::GetCurrentMonotonicMicros(), tid);
932 sample->set_is_native_allocation_sample(true);
933
934 Thread* thread = Thread::Current();
935
936 // TODO(bkonyi) Any samples created while a current thread doesn't exist are
937 // ignored by the NativeAllocationSampleFilter since the default task is
938 // kUnknownTask. Is this what we want to do?
939 if (thread != NULL) {
940 sample->set_thread_task(thread->task_kind());
941 }
942 return sample;
943 }
944
945
908 static bool CheckIsolate(Isolate* isolate) { 946 static bool CheckIsolate(Isolate* isolate) {
909 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { 947 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) {
910 // No isolate. 948 // No isolate.
911 return false; 949 return false;
912 } 950 }
913 return isolate != Dart::vm_isolate(); 951 return isolate != Dart::vm_isolate();
914 } 952 }
915 953
916 954
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
929 void Profiler::DumpStackTrace(void* context) { 955 void Profiler::DumpStackTrace(void* context) {
930 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) 956 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS)
931 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 957 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
932 mcontext_t mcontext = ucontext->uc_mcontext; 958 mcontext_t mcontext = ucontext->uc_mcontext;
933 uword pc = SignalHandler::GetProgramCounter(mcontext); 959 uword pc = SignalHandler::GetProgramCounter(mcontext);
934 uword fp = SignalHandler::GetFramePointer(mcontext); 960 uword fp = SignalHandler::GetFramePointer(mcontext);
935 uword sp = SignalHandler::GetCStackPointer(mcontext); 961 uword sp = SignalHandler::GetCStackPointer(mcontext);
936 DumpStackTrace(sp, fp, pc); 962 DumpStackTrace(sp, fp, pc);
937 #else 963 #else
938 // TODO(fschneider): Add support for more platforms. 964 // TODO(fschneider): Add support for more platforms.
939 // Do nothing on unsupported platforms. 965 // Do nothing on unsupported platforms.
940 #endif 966 #endif
941 } 967 }
942 968
943 969
944 void Profiler::DumpStackTrace() { 970 void Profiler::DumpStackTrace() {
945 uintptr_t sp = Thread::GetCurrentStackPointer(); 971 uintptr_t sp = Thread::GetCurrentStackPointer();
946 uintptr_t fp = 0; 972 uintptr_t fp = 0;
947 uintptr_t pc = GetProgramCounter(); 973 uintptr_t pc = OS::GetProgramCounter();
948 974
949 COPY_FP_REGISTER(fp); 975 COPY_FP_REGISTER(fp);
950 976
951 DumpStackTrace(sp, fp, pc); 977 DumpStackTrace(sp, fp, pc);
952 } 978 }
953 979
954 980
955 void Profiler::DumpStackTrace(uword sp, uword fp, uword pc) { 981 void Profiler::DumpStackTrace(uword sp, uword fp, uword pc) {
956 // Allow only one stack trace to prevent recursively printing stack traces if 982 // Allow only one stack trace to prevent recursively printing stack traces if
957 // we hit an assert while printing the stack. 983 // we hit an assert while printing the stack.
(...skipping 27 matching lines...) Expand all
985 1011
986 if (!GetAndValidateThreadStackBounds(thread, fp, sp, &stack_lower, 1012 if (!GetAndValidateThreadStackBounds(thread, fp, sp, &stack_lower,
987 &stack_upper, 1013 &stack_upper,
988 /*get_os_thread_bounds=*/true)) { 1014 /*get_os_thread_bounds=*/true)) {
989 OS::PrintErr( 1015 OS::PrintErr(
990 "Stack dump aborted because GetAndValidateThreadStackBounds.\n"); 1016 "Stack dump aborted because GetAndValidateThreadStackBounds.\n");
991 return; 1017 return;
992 } 1018 }
993 1019
994 ProfilerNativeStackWalker native_stack_walker( 1020 ProfilerNativeStackWalker native_stack_walker(
995 isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp); 1021 (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, NULL, NULL,
1022 stack_lower, stack_upper, pc, fp, sp);
996 native_stack_walker.walk(); 1023 native_stack_walker.walk();
997 OS::PrintErr("-- End of DumpStackTrace\n"); 1024 OS::PrintErr("-- End of DumpStackTrace\n");
998 } 1025 }
999 1026
1000 1027
1001 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { 1028 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) {
1002 ASSERT(thread != NULL); 1029 ASSERT(thread != NULL);
1003 OSThread* os_thread = thread->os_thread(); 1030 OSThread* os_thread = thread->os_thread();
1004 ASSERT(os_thread != NULL); 1031 ASSERT(os_thread != NULL);
1005 Isolate* isolate = thread->isolate(); 1032 Isolate* isolate = thread->isolate();
1006 if (!CheckIsolate(isolate)) { 1033 if (!CheckIsolate(isolate)) {
1007 return; 1034 return;
1008 } 1035 }
1009 1036
1010 const bool exited_dart_code = thread->HasExitedDartCode(); 1037 const bool exited_dart_code = thread->HasExitedDartCode();
1011 1038
1012 SampleBuffer* sample_buffer = Profiler::sample_buffer(); 1039 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1013 if (sample_buffer == NULL) { 1040 if (sample_buffer == NULL) {
1014 // Profiler not initialized. 1041 // Profiler not initialized.
1015 return; 1042 return;
1016 } 1043 }
1017 1044
1018 uintptr_t sp = Thread::GetCurrentStackPointer(); 1045 uintptr_t sp = Thread::GetCurrentStackPointer();
1019 uintptr_t fp = 0; 1046 uintptr_t fp = 0;
1020 uintptr_t pc = GetProgramCounter(); 1047 uintptr_t pc = OS::GetProgramCounter();
1021 1048
1022 COPY_FP_REGISTER(fp); 1049 COPY_FP_REGISTER(fp);
1023 1050
1024 uword stack_lower = 0; 1051 uword stack_lower = 0;
1025 uword stack_upper = 0; 1052 uword stack_upper = 0;
1026 1053
1027 if (!InitialRegisterCheck(pc, fp, sp)) { 1054 if (!InitialRegisterCheck(pc, fp, sp)) {
1028 return; 1055 return;
1029 } 1056 }
1030 1057
1031 if (!GetAndValidateThreadStackBounds(thread, fp, sp, &stack_lower, 1058 if (!GetAndValidateThreadStackBounds(thread, fp, sp, &stack_lower,
1032 &stack_upper)) { 1059 &stack_upper)) {
1033 // Could not get stack boundary. 1060 // Could not get stack boundary.
1034 return; 1061 return;
1035 } 1062 }
1036 1063
1037 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1064 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1038 sample->SetAllocationCid(cid); 1065 sample->SetAllocationCid(cid);
1039 1066
1040 if (FLAG_profile_vm) { 1067 if (FLAG_profile_vm) {
1041 ProfilerNativeStackWalker native_stack_walker( 1068 ProfilerNativeStackWalker native_stack_walker(
1042 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); 1069 (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, sample,
1070 sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1043 native_stack_walker.walk(); 1071 native_stack_walker.walk();
1044 } else if (exited_dart_code) { 1072 } else if (exited_dart_code) {
1045 ProfilerDartStackWalker dart_exit_stack_walker( 1073 ProfilerDartStackWalker dart_exit_stack_walker(
1046 thread, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp, 1074 thread, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp,
1047 exited_dart_code, true); 1075 exited_dart_code, true);
1048 dart_exit_stack_walker.walk(); 1076 dart_exit_stack_walker.walk();
1049 } else { 1077 } else {
1050 // Fall back. 1078 // Fall back.
1051 uintptr_t pc = GetProgramCounter(); 1079 uintptr_t pc = OS::GetProgramCounter();
1052 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1080 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1053 sample->SetAllocationCid(cid); 1081 sample->SetAllocationCid(cid);
1054 sample->SetAt(0, pc); 1082 sample->SetAt(0, pc);
1055 } 1083 }
1056 } 1084 }
1057 1085
1058 1086
1087 Sample* Profiler::SampleNativeAllocation(intptr_t skip_count) {
1088 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1089 if (sample_buffer == NULL) {
1090 return NULL;
1091 }
1092
1093 uintptr_t sp = Thread::GetCurrentStackPointer();
1094 uintptr_t fp = 0;
1095 uintptr_t pc = OS::GetProgramCounter();
1096
1097 COPY_FP_REGISTER(fp);
1098
1099 uword stack_lower = 0;
1100 uword stack_upper = 0;
1101 if (!InitialRegisterCheck(pc, fp, sp)) {
1102 return NULL;
1103 }
1104
1105 OSThread* os_thread = OSThread::Current();
1106 if (os_thread->stack_base() == 0) {
1107 stack_lower = sp;
Cutch 2017/02/21 18:53:35 OSThread::GetCurrentStackBounds
bkonyi 2017/02/22 19:12:51 Done.
1108 stack_upper = ~static_cast<uintptr_t>(0x0);
1109 } else {
1110 if (!GetAndValidateThreadStackBounds(NULL, fp, sp, &stack_lower,
1111 &stack_upper)) {
1112 // Could not get stack boundary.
1113 return NULL;
1114 }
1115 }
1116 Sample* sample = SetupSampleNative(sample_buffer, os_thread->trace_id());
1117 ProfilerNativeStackWalker native_stack_walker(
1118 ILLEGAL_PORT, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp,
1119 skip_count);
1120 native_stack_walker.walk();
1121 return sample;
1122 }
1123
1124
1059 void Profiler::SampleThreadSingleFrame(Thread* thread, uintptr_t pc) { 1125 void Profiler::SampleThreadSingleFrame(Thread* thread, uintptr_t pc) {
1060 ASSERT(thread != NULL); 1126 ASSERT(thread != NULL);
1061 OSThread* os_thread = thread->os_thread(); 1127 OSThread* os_thread = thread->os_thread();
1062 ASSERT(os_thread != NULL); 1128 ASSERT(os_thread != NULL);
1063 Isolate* isolate = thread->isolate(); 1129 Isolate* isolate = thread->isolate();
1064 1130
1065 SampleBuffer* sample_buffer = Profiler::sample_buffer(); 1131 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1066 if (sample_buffer == NULL) { 1132 if (sample_buffer == NULL) {
1067 // Profiler not initialized. 1133 // Profiler not initialized.
1068 return; 1134 return;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 // Setup sample. 1240 // Setup sample.
1175 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); 1241 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
1176 // Increment counter for vm tag. 1242 // Increment counter for vm tag.
1177 VMTagCounters* counters = isolate->vm_tag_counters(); 1243 VMTagCounters* counters = isolate->vm_tag_counters();
1178 ASSERT(counters != NULL); 1244 ASSERT(counters != NULL);
1179 if (thread->IsMutatorThread()) { 1245 if (thread->IsMutatorThread()) {
1180 counters->Increment(sample->vm_tag()); 1246 counters->Increment(sample->vm_tag());
1181 } 1247 }
1182 1248
1183 ProfilerNativeStackWalker native_stack_walker( 1249 ProfilerNativeStackWalker native_stack_walker(
1184 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); 1250 (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, sample,
1251 sample_buffer, stack_lower, stack_upper, pc, fp, sp);
1185 const bool exited_dart_code = thread->HasExitedDartCode(); 1252 const bool exited_dart_code = thread->HasExitedDartCode();
1186 ProfilerDartStackWalker dart_stack_walker(thread, sample, sample_buffer, 1253 ProfilerDartStackWalker dart_stack_walker(thread, sample, sample_buffer,
1187 stack_lower, stack_upper, pc, fp, 1254 stack_lower, stack_upper, pc, fp,
1188 sp, exited_dart_code, false); 1255 sp, exited_dart_code, false);
1189 1256
1190 // All memory access is done inside CollectSample. 1257 // All memory access is done inside CollectSample.
1191 CollectSample(isolate, exited_dart_code, in_dart_code, sample, 1258 CollectSample(isolate, exited_dart_code, in_dart_code, sample,
1192 &native_stack_walker, &dart_stack_walker, pc, fp, sp, 1259 &native_stack_walker, &dart_stack_walker, pc, fp, sp,
1193 &counters_); 1260 &counters_);
1194 } 1261 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 for (intptr_t i = 0; i < length; i++) { 1401 for (intptr_t i = 0; i < length; i++) {
1335 Sample* sample = At(i); 1402 Sample* sample = At(i);
1336 if (sample->ignore_sample()) { 1403 if (sample->ignore_sample()) {
1337 // Bad sample. 1404 // Bad sample.
1338 continue; 1405 continue;
1339 } 1406 }
1340 if (!sample->head_sample()) { 1407 if (!sample->head_sample()) {
1341 // An inner sample in a chain of samples. 1408 // An inner sample in a chain of samples.
1342 continue; 1409 continue;
1343 } 1410 }
1344 if (sample->isolate() != filter->isolate()) { 1411 // If we're requesting all the native allocation samples, we don't care
1412 // whether or not we're in the same isolate as the sample.
1413 if ((sample->port() != filter->port()) &&
1414 !sample->is_native_allocation_sample()) {
1345 // Another isolate. 1415 // Another isolate.
1346 continue; 1416 continue;
1347 } 1417 }
1348 if (sample->timestamp() == 0) { 1418 if (sample->timestamp() == 0) {
1349 // Empty. 1419 // Empty.
1350 continue; 1420 continue;
1351 } 1421 }
1352 if (sample->At(0) == 0) { 1422 if (sample->At(0) == 0) {
1353 // No frames. 1423 // No frames.
1354 continue; 1424 continue;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 return processed_sample; 1483 return processed_sample;
1414 } 1484 }
1415 1485
1416 1486
1417 Sample* SampleBuffer::Next(Sample* sample) { 1487 Sample* SampleBuffer::Next(Sample* sample) {
1418 if (!sample->is_continuation_sample()) return NULL; 1488 if (!sample->is_continuation_sample()) return NULL;
1419 Sample* next_sample = At(sample->continuation_index()); 1489 Sample* next_sample = At(sample->continuation_index());
1420 // Sanity check. 1490 // Sanity check.
1421 ASSERT(sample != next_sample); 1491 ASSERT(sample != next_sample);
1422 // Detect invalid chaining. 1492 // Detect invalid chaining.
1423 if (sample->isolate() != next_sample->isolate()) { 1493 if (sample->port() != next_sample->port()) {
1424 return NULL; 1494 return NULL;
1425 } 1495 }
1426 if (sample->timestamp() != next_sample->timestamp()) { 1496 if (sample->timestamp() != next_sample->timestamp()) {
1427 return NULL; 1497 return NULL;
1428 } 1498 }
1429 if (sample->tid() != next_sample->tid()) { 1499 if (sample->tid() != next_sample->tid()) {
1430 return NULL; 1500 return NULL;
1431 } 1501 }
1432 return next_sample; 1502 return next_sample;
1433 } 1503 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 1585
1516 1586
1517 ProcessedSampleBuffer::ProcessedSampleBuffer() 1587 ProcessedSampleBuffer::ProcessedSampleBuffer()
1518 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { 1588 : code_lookup_table_(new CodeLookupTable(Thread::Current())) {
1519 ASSERT(code_lookup_table_ != NULL); 1589 ASSERT(code_lookup_table_ != NULL);
1520 } 1590 }
1521 1591
1522 #endif // !PRODUCT 1592 #endif // !PRODUCT
1523 1593
1524 } // namespace dart 1594 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698