| OLD | NEW |
| 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 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 | 411 |
| 412 protected: | 412 protected: |
| 413 Isolate* isolate_; | 413 Isolate* isolate_; |
| 414 Sample* sample_; | 414 Sample* sample_; |
| 415 SampleBuffer* sample_buffer_; | 415 SampleBuffer* sample_buffer_; |
| 416 intptr_t frame_index_; | 416 intptr_t frame_index_; |
| 417 intptr_t total_frames_; | 417 intptr_t total_frames_; |
| 418 }; | 418 }; |
| 419 | 419 |
| 420 | 420 |
| 421 // Given an exit frame, walk the Dart stack. | |
| 422 class ProfilerDartExitStackWalker : public ProfilerStackWalker { | |
| 423 public: | |
| 424 ProfilerDartExitStackWalker(Thread* thread, | |
| 425 Isolate* isolate, | |
| 426 Sample* sample, | |
| 427 SampleBuffer* sample_buffer) | |
| 428 : ProfilerStackWalker(isolate, sample, sample_buffer), | |
| 429 frame_iterator_(thread) {} | |
| 430 | |
| 431 void walk() { | |
| 432 // Mark that this sample was collected from an exit frame. | |
| 433 sample_->set_exit_frame_sample(true); | |
| 434 | |
| 435 StackFrame* frame = frame_iterator_.NextFrame(); | |
| 436 if (sample_ == NULL) { | |
| 437 // Only when we are dumping the stack trace for debug purposes. | |
| 438 Code& code = Code::Handle(); | |
| 439 while (frame != NULL) { | |
| 440 code ^= frame->LookupDartCode(); | |
| 441 if (!Append(frame->pc(), code)) { | |
| 442 return; | |
| 443 } | |
| 444 frame = frame_iterator_.NextFrame(); | |
| 445 } | |
| 446 } else { | |
| 447 while (frame != NULL) { | |
| 448 if (!Append(frame->pc())) { | |
| 449 return; | |
| 450 } | |
| 451 frame = frame_iterator_.NextFrame(); | |
| 452 } | |
| 453 } | |
| 454 } | |
| 455 | |
| 456 private: | |
| 457 DartFrameIterator frame_iterator_; | |
| 458 }; | |
| 459 | |
| 460 | |
| 461 // Executing Dart code, walk the stack. | 421 // Executing Dart code, walk the stack. |
| 462 class ProfilerDartStackWalker : public ProfilerStackWalker { | 422 class ProfilerDartStackWalker : public ProfilerStackWalker { |
| 463 public: | 423 public: |
| 464 ProfilerDartStackWalker(Isolate* isolate, | 424 ProfilerDartStackWalker(Thread* thread, |
| 465 Sample* sample, | 425 Sample* sample, |
| 466 SampleBuffer* sample_buffer, | 426 SampleBuffer* sample_buffer, |
| 467 uword stack_lower, | 427 uword stack_lower, |
| 468 uword stack_upper, | 428 uword stack_upper, |
| 469 uword pc, | 429 uword pc, |
| 470 uword fp, | 430 uword fp, |
| 471 uword sp) | 431 uword sp, |
| 472 : ProfilerStackWalker(isolate, sample, sample_buffer), | 432 bool exited_dart_code, |
| 433 bool allocation_sample) |
| 434 : ProfilerStackWalker(thread->isolate(), sample, sample_buffer), |
| 435 pc_(reinterpret_cast<uword*>(pc)), |
| 436 fp_(reinterpret_cast<uword*>(fp)), |
| 437 sp_(reinterpret_cast<uword*>(sp)), |
| 473 stack_upper_(stack_upper), | 438 stack_upper_(stack_upper), |
| 474 stack_lower_(stack_lower) { | 439 stack_lower_(stack_lower), |
| 475 pc_ = reinterpret_cast<uword*>(pc); | 440 has_exit_frame_(exited_dart_code) { |
| 476 fp_ = reinterpret_cast<uword*>(fp); | 441 if (exited_dart_code) { |
| 477 sp_ = reinterpret_cast<uword*>(sp); | 442 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, |
| 443 thread); |
| 444 pc_ = NULL; |
| 445 fp_ = NULL; |
| 446 sp_ = NULL; |
| 447 if (!iterator.HasNextFrame()) { |
| 448 return; |
| 449 } |
| 450 // Ensure we are able to get to the exit frame. |
| 451 StackFrame* frame = iterator.NextFrame(); |
| 452 if (!frame->IsExitFrame()) { |
| 453 return; |
| 454 } |
| 455 // Skip the exit frame. |
| 456 if (!iterator.HasNextFrame()) { |
| 457 return; |
| 458 } |
| 459 frame = iterator.NextFrame(); |
| 460 // Record frame details of the first frame from which we start walking. |
| 461 pc_ = reinterpret_cast<uword*>(frame->pc()); |
| 462 fp_ = reinterpret_cast<uword*>(frame->fp()); |
| 463 sp_ = reinterpret_cast<uword*>(frame->sp()); |
| 464 } |
| 478 } | 465 } |
| 479 | 466 |
| 480 void walk() { | 467 void walk() { |
| 481 sample_->set_exit_frame_sample(false); | 468 sample_->set_exit_frame_sample(has_exit_frame_); |
| 482 if (!ValidFramePointer()) { | 469 if (!ValidFramePointer()) { |
| 483 sample_->set_ignore_sample(true); | 470 sample_->set_ignore_sample(true); |
| 484 return; | 471 return; |
| 485 } | 472 } |
| 486 ASSERT(ValidFramePointer()); | 473 ASSERT(ValidFramePointer()); |
| 487 uword return_pc = InitialReturnAddress(); | 474 uword return_pc = InitialReturnAddress(); |
| 488 if (StubCode::InInvocationStub(return_pc)) { | 475 if (StubCode::InInvocationStub(return_pc)) { |
| 489 // Edge case- we have called out from the Invocation Stub but have not | 476 // Edge case- we have called out from the Invocation Stub but have not |
| 490 // created the stack frame of the callee. Attempt to locate the exit | 477 // created the stack frame of the callee. Attempt to locate the exit |
| 491 // frame before walking the stack. | 478 // frame before walking the stack. |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 } | 585 } |
| 599 uword cursor = reinterpret_cast<uword>(fp); | 586 uword cursor = reinterpret_cast<uword>(fp); |
| 600 cursor += sizeof(fp); | 587 cursor += sizeof(fp); |
| 601 return (cursor >= stack_lower_) && (cursor < stack_upper_); | 588 return (cursor >= stack_lower_) && (cursor < stack_upper_); |
| 602 } | 589 } |
| 603 | 590 |
| 604 uword* pc_; | 591 uword* pc_; |
| 605 uword* fp_; | 592 uword* fp_; |
| 606 uword* sp_; | 593 uword* sp_; |
| 607 const uword stack_upper_; | 594 const uword stack_upper_; |
| 608 uword stack_lower_; | 595 const uword stack_lower_; |
| 596 bool has_exit_frame_; |
| 609 }; | 597 }; |
| 610 | 598 |
| 611 | 599 |
| 612 // If the VM is compiled without frame pointers (which is the default on | 600 // If the VM is compiled without frame pointers (which is the default on |
| 613 // recent GCC versions with optimizing enabled) the stack walking code may | 601 // recent GCC versions with optimizing enabled) the stack walking code may |
| 614 // fail. | 602 // fail. |
| 615 // | 603 // |
| 616 class ProfilerNativeStackWalker : public ProfilerStackWalker { | 604 class ProfilerNativeStackWalker : public ProfilerStackWalker { |
| 617 public: | 605 public: |
| 618 ProfilerNativeStackWalker(Isolate* isolate, | 606 ProfilerNativeStackWalker(Isolate* isolate, |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 return EXCEPTION_EXECUTE_HANDLER; | 739 return EXCEPTION_EXECUTE_HANDLER; |
| 752 } | 740 } |
| 753 #endif | 741 #endif |
| 754 | 742 |
| 755 // All memory access done to collect the sample is performed in CollectSample. | 743 // All memory access done to collect the sample is performed in CollectSample. |
| 756 static void CollectSample(Isolate* isolate, | 744 static void CollectSample(Isolate* isolate, |
| 757 bool exited_dart_code, | 745 bool exited_dart_code, |
| 758 bool in_dart_code, | 746 bool in_dart_code, |
| 759 Sample* sample, | 747 Sample* sample, |
| 760 ProfilerNativeStackWalker* native_stack_walker, | 748 ProfilerNativeStackWalker* native_stack_walker, |
| 761 ProfilerDartExitStackWalker* dart_exit_stack_walker, | |
| 762 ProfilerDartStackWalker* dart_stack_walker, | 749 ProfilerDartStackWalker* dart_stack_walker, |
| 763 uword pc, | 750 uword pc, |
| 764 uword fp, | 751 uword fp, |
| 765 uword sp, | 752 uword sp, |
| 766 ProfilerCounters* counters) { | 753 ProfilerCounters* counters) { |
| 767 ASSERT(counters != NULL); | 754 ASSERT(counters != NULL); |
| 768 #if defined(TARGET_OS_WINDOWS) | 755 #if defined(TARGET_OS_WINDOWS) |
| 769 // Use structured exception handling to trap guard page access on Windows. | 756 // Use structured exception handling to trap guard page access on Windows. |
| 770 __try { | 757 __try { |
| 771 #endif | 758 #endif |
| 772 | 759 |
| 773 if (in_dart_code) { | 760 if (in_dart_code) { |
| 774 // We can only trust the stack pointer if we are executing Dart code. | 761 // We can only trust the stack pointer if we are executing Dart code. |
| 775 // See http://dartbug.com/20421 for details. | 762 // See http://dartbug.com/20421 for details. |
| 776 CopyStackBuffer(sample, sp); | 763 CopyStackBuffer(sample, sp); |
| 777 } | 764 } |
| 778 | 765 |
| 779 if (FLAG_profile_vm) { | 766 if (FLAG_profile_vm) { |
| 780 // Always walk the native stack collecting both native and Dart frames. | 767 // Always walk the native stack collecting both native and Dart frames. |
| 781 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1); | 768 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1); |
| 782 native_stack_walker->walk(); | 769 native_stack_walker->walk(); |
| 783 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { | 770 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { |
| 784 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1); | 771 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1); |
| 785 // We have a valid exit frame info, use the Dart stack walker. | 772 // We have a valid exit frame info, use the Dart stack walker. |
| 786 dart_exit_stack_walker->walk(); | 773 dart_stack_walker->walk(); |
| 787 } else if (StubCode::HasBeenInitialized() && in_dart_code) { | 774 } else if (StubCode::HasBeenInitialized() && in_dart_code) { |
| 788 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1); | 775 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1); |
| 789 // We are executing Dart code. We have frame pointers. | 776 // We are executing Dart code. We have frame pointers. |
| 790 dart_stack_walker->walk(); | 777 dart_stack_walker->walk(); |
| 791 } else { | 778 } else { |
| 792 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1); | 779 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1); |
| 793 sample->SetAt(0, pc); | 780 sample->SetAt(0, pc); |
| 794 } | 781 } |
| 795 | 782 |
| 796 #if defined(TARGET_OS_WINDOWS) | 783 #if defined(TARGET_OS_WINDOWS) |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 #endif | 931 #endif |
| 945 | 932 |
| 946 | 933 |
| 947 void Profiler::DumpStackTrace(void* context) { | 934 void Profiler::DumpStackTrace(void* context) { |
| 948 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) | 935 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) |
| 949 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); | 936 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
| 950 mcontext_t mcontext = ucontext->uc_mcontext; | 937 mcontext_t mcontext = ucontext->uc_mcontext; |
| 951 uword pc = SignalHandler::GetProgramCounter(mcontext); | 938 uword pc = SignalHandler::GetProgramCounter(mcontext); |
| 952 uword fp = SignalHandler::GetFramePointer(mcontext); | 939 uword fp = SignalHandler::GetFramePointer(mcontext); |
| 953 uword sp = SignalHandler::GetCStackPointer(mcontext); | 940 uword sp = SignalHandler::GetCStackPointer(mcontext); |
| 954 DumpStackTrace(/* native_stack_trace = */ true, sp, fp, pc); | 941 DumpStackTrace(sp, fp, pc); |
| 955 #else | 942 #else |
| 956 // TODO(fschneider): Add support for more platforms. | 943 // TODO(fschneider): Add support for more platforms. |
| 957 // Do nothing on unsupported platforms. | 944 // Do nothing on unsupported platforms. |
| 958 #endif | 945 #endif |
| 959 } | 946 } |
| 960 | 947 |
| 961 | 948 |
| 962 void Profiler::DumpStackTrace(bool native_stack_trace) { | 949 void Profiler::DumpStackTrace() { |
| 963 uintptr_t sp = Thread::GetCurrentStackPointer(); | 950 uintptr_t sp = Thread::GetCurrentStackPointer(); |
| 964 uintptr_t fp = 0; | 951 uintptr_t fp = 0; |
| 965 uintptr_t pc = GetProgramCounter(); | 952 uintptr_t pc = GetProgramCounter(); |
| 966 | 953 |
| 967 COPY_FP_REGISTER(fp); | 954 COPY_FP_REGISTER(fp); |
| 968 | 955 |
| 969 DumpStackTrace(native_stack_trace, sp, fp, pc); | 956 DumpStackTrace(sp, fp, pc); |
| 970 } | 957 } |
| 971 | 958 |
| 972 | 959 |
| 973 void Profiler::DumpStackTrace(bool native_stack_trace, | 960 void Profiler::DumpStackTrace(uword sp, uword fp, uword pc) { |
| 974 uword sp, | |
| 975 uword fp, | |
| 976 uword pc) { | |
| 977 // Allow only one stack trace to prevent recursively printing stack traces if | 961 // Allow only one stack trace to prevent recursively printing stack traces if |
| 978 // we hit an assert while printing the stack. | 962 // we hit an assert while printing the stack. |
| 979 static uintptr_t started_dump = 0; | 963 static uintptr_t started_dump = 0; |
| 980 if (AtomicOperations::FetchAndIncrement(&started_dump) != 0) { | 964 if (AtomicOperations::FetchAndIncrement(&started_dump) != 0) { |
| 981 OS::PrintErr("Aborting re-entrant request for stack trace.\n"); | 965 OS::PrintErr("Aborting re-entrant request for stack trace.\n"); |
| 982 return; | 966 return; |
| 983 } | 967 } |
| 984 | 968 |
| 985 Thread* thread = Thread::Current(); | 969 Thread* thread = Thread::Current(); |
| 986 if (thread == NULL) { | 970 if (thread == NULL) { |
| 987 return; | 971 return; |
| 988 } | 972 } |
| 989 OSThread* os_thread = thread->os_thread(); | 973 OSThread* os_thread = thread->os_thread(); |
| 990 ASSERT(os_thread != NULL); | 974 ASSERT(os_thread != NULL); |
| 991 Isolate* isolate = thread->isolate(); | 975 Isolate* isolate = thread->isolate(); |
| 992 if (!CheckIsolate(isolate)) { | 976 if (!CheckIsolate(isolate)) { |
| 993 return; | 977 return; |
| 994 } | 978 } |
| 995 | 979 |
| 996 const bool exited_dart_code = thread->HasExitedDartCode(); | 980 OS::PrintErr("Dumping native stack trace for thread %" Px "\n", |
| 997 | |
| 998 OS::PrintErr("Dumping %s stack trace for thread %" Px "\n", | |
| 999 native_stack_trace ? "native" : "dart-only", | |
| 1000 OSThread::ThreadIdToIntPtr(os_thread->trace_id())); | 981 OSThread::ThreadIdToIntPtr(os_thread->trace_id())); |
| 1001 | 982 |
| 1002 uword stack_lower = 0; | 983 uword stack_lower = 0; |
| 1003 uword stack_upper = 0; | 984 uword stack_upper = 0; |
| 1004 | 985 |
| 1005 if (!InitialRegisterCheck(pc, fp, sp)) { | 986 if (!InitialRegisterCheck(pc, fp, sp)) { |
| 1006 OS::PrintErr("Stack dump aborted because InitialRegisterCheck.\n"); | 987 OS::PrintErr("Stack dump aborted because InitialRegisterCheck.\n"); |
| 1007 return; | 988 return; |
| 1008 } | 989 } |
| 1009 | 990 |
| 1010 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, | 991 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, |
| 1011 &stack_upper)) { | 992 &stack_upper)) { |
| 1012 OS::PrintErr( | 993 OS::PrintErr( |
| 1013 "Stack dump aborted because GetAndValidateIsolateStackBounds.\n"); | 994 "Stack dump aborted because GetAndValidateIsolateStackBounds.\n"); |
| 1014 return; | 995 return; |
| 1015 } | 996 } |
| 1016 | 997 |
| 1017 if (native_stack_trace) { | 998 ProfilerNativeStackWalker native_stack_walker( |
| 1018 ProfilerNativeStackWalker native_stack_walker( | 999 isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp); |
| 1019 isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp); | 1000 native_stack_walker.walk(); |
| 1020 native_stack_walker.walk(); | |
| 1021 } else if (exited_dart_code) { | |
| 1022 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, NULL, | |
| 1023 NULL); | |
| 1024 dart_exit_stack_walker.walk(); | |
| 1025 } else { | |
| 1026 ProfilerDartStackWalker dart_stack_walker(isolate, NULL, NULL, stack_lower, | |
| 1027 stack_upper, pc, fp, sp); | |
| 1028 } | |
| 1029 OS::PrintErr("-- End of DumpStackTrace\n"); | 1001 OS::PrintErr("-- End of DumpStackTrace\n"); |
| 1030 } | 1002 } |
| 1031 | 1003 |
| 1032 | 1004 |
| 1033 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { | 1005 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
| 1034 ASSERT(thread != NULL); | 1006 ASSERT(thread != NULL); |
| 1035 OSThread* os_thread = thread->os_thread(); | 1007 OSThread* os_thread = thread->os_thread(); |
| 1036 ASSERT(os_thread != NULL); | 1008 ASSERT(os_thread != NULL); |
| 1037 Isolate* isolate = thread->isolate(); | 1009 Isolate* isolate = thread->isolate(); |
| 1038 if (!CheckIsolate(isolate)) { | 1010 if (!CheckIsolate(isolate)) { |
| 1039 return; | 1011 return; |
| 1040 } | 1012 } |
| 1041 | 1013 |
| 1042 const bool exited_dart_code = thread->HasExitedDartCode(); | 1014 const bool exited_dart_code = thread->HasExitedDartCode(); |
| 1043 | 1015 |
| 1044 SampleBuffer* sample_buffer = Profiler::sample_buffer(); | 1016 SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
| 1045 if (sample_buffer == NULL) { | 1017 if (sample_buffer == NULL) { |
| 1046 // Profiler not initialized. | 1018 // Profiler not initialized. |
| 1047 return; | 1019 return; |
| 1048 } | 1020 } |
| 1049 | 1021 |
| 1022 uintptr_t sp = Thread::GetCurrentStackPointer(); |
| 1023 uintptr_t fp = 0; |
| 1024 uintptr_t pc = GetProgramCounter(); |
| 1025 |
| 1026 COPY_FP_REGISTER(fp); |
| 1027 |
| 1028 uword stack_lower = 0; |
| 1029 uword stack_upper = 0; |
| 1030 |
| 1031 if (!InitialRegisterCheck(pc, fp, sp)) { |
| 1032 return; |
| 1033 } |
| 1034 |
| 1035 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, |
| 1036 &stack_upper)) { |
| 1037 // Could not get stack boundary. |
| 1038 return; |
| 1039 } |
| 1040 |
| 1041 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); |
| 1042 sample->SetAllocationCid(cid); |
| 1043 |
| 1050 if (FLAG_profile_vm) { | 1044 if (FLAG_profile_vm) { |
| 1051 uintptr_t sp = Thread::GetCurrentStackPointer(); | |
| 1052 uintptr_t fp = 0; | |
| 1053 uintptr_t pc = GetProgramCounter(); | |
| 1054 | |
| 1055 COPY_FP_REGISTER(fp); | |
| 1056 | |
| 1057 uword stack_lower = 0; | |
| 1058 uword stack_upper = 0; | |
| 1059 | |
| 1060 if (!InitialRegisterCheck(pc, fp, sp)) { | |
| 1061 return; | |
| 1062 } | |
| 1063 | |
| 1064 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, | |
| 1065 &stack_upper)) { | |
| 1066 // Could not get stack boundary. | |
| 1067 return; | |
| 1068 } | |
| 1069 | |
| 1070 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); | |
| 1071 sample->SetAllocationCid(cid); | |
| 1072 ProfilerNativeStackWalker native_stack_walker( | 1045 ProfilerNativeStackWalker native_stack_walker( |
| 1073 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); | 1046 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
| 1074 native_stack_walker.walk(); | 1047 native_stack_walker.walk(); |
| 1075 } else if (exited_dart_code) { | 1048 } else if (exited_dart_code) { |
| 1076 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); | 1049 ProfilerDartStackWalker dart_exit_stack_walker( |
| 1077 sample->SetAllocationCid(cid); | 1050 thread, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp, |
| 1078 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, sample, | 1051 exited_dart_code, true); |
| 1079 sample_buffer); | |
| 1080 dart_exit_stack_walker.walk(); | 1052 dart_exit_stack_walker.walk(); |
| 1081 } else { | 1053 } else { |
| 1082 // Fall back. | 1054 // Fall back. |
| 1083 uintptr_t pc = GetProgramCounter(); | 1055 uintptr_t pc = GetProgramCounter(); |
| 1084 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); | 1056 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); |
| 1085 sample->SetAllocationCid(cid); | 1057 sample->SetAllocationCid(cid); |
| 1086 sample->SetAt(0, pc); | 1058 sample->SetAt(0, pc); |
| 1087 } | 1059 } |
| 1088 } | 1060 } |
| 1089 | 1061 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1207 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); | 1179 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); |
| 1208 // Increment counter for vm tag. | 1180 // Increment counter for vm tag. |
| 1209 VMTagCounters* counters = isolate->vm_tag_counters(); | 1181 VMTagCounters* counters = isolate->vm_tag_counters(); |
| 1210 ASSERT(counters != NULL); | 1182 ASSERT(counters != NULL); |
| 1211 if (thread->IsMutatorThread()) { | 1183 if (thread->IsMutatorThread()) { |
| 1212 counters->Increment(sample->vm_tag()); | 1184 counters->Increment(sample->vm_tag()); |
| 1213 } | 1185 } |
| 1214 | 1186 |
| 1215 ProfilerNativeStackWalker native_stack_walker( | 1187 ProfilerNativeStackWalker native_stack_walker( |
| 1216 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); | 1188 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
| 1217 | |
| 1218 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, sample, | |
| 1219 sample_buffer); | |
| 1220 | |
| 1221 ProfilerDartStackWalker dart_stack_walker( | |
| 1222 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); | |
| 1223 | |
| 1224 const bool exited_dart_code = thread->HasExitedDartCode(); | 1189 const bool exited_dart_code = thread->HasExitedDartCode(); |
| 1190 ProfilerDartStackWalker dart_stack_walker(thread, sample, sample_buffer, |
| 1191 stack_lower, stack_upper, pc, fp, |
| 1192 sp, exited_dart_code, false); |
| 1225 | 1193 |
| 1226 // All memory access is done inside CollectSample. | 1194 // All memory access is done inside CollectSample. |
| 1227 CollectSample(isolate, exited_dart_code, in_dart_code, sample, | 1195 CollectSample(isolate, exited_dart_code, in_dart_code, sample, |
| 1228 &native_stack_walker, &dart_exit_stack_walker, | 1196 &native_stack_walker, &dart_stack_walker, pc, fp, sp, |
| 1229 &dart_stack_walker, pc, fp, sp, &counters_); | 1197 &counters_); |
| 1230 } | 1198 } |
| 1231 | 1199 |
| 1232 | 1200 |
| 1233 CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) { | 1201 CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) { |
| 1234 ASSERT(!code_.IsNull()); | 1202 ASSERT(!code_.IsNull()); |
| 1235 } | 1203 } |
| 1236 | 1204 |
| 1237 | 1205 |
| 1238 uword CodeDescriptor::Start() const { | 1206 uword CodeDescriptor::Start() const { |
| 1239 return code_.PayloadStart(); | 1207 return code_.PayloadStart(); |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1551 | 1519 |
| 1552 | 1520 |
| 1553 ProcessedSampleBuffer::ProcessedSampleBuffer() | 1521 ProcessedSampleBuffer::ProcessedSampleBuffer() |
| 1554 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { | 1522 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { |
| 1555 ASSERT(code_lookup_table_ != NULL); | 1523 ASSERT(code_lookup_table_ != NULL); |
| 1556 } | 1524 } |
| 1557 | 1525 |
| 1558 #endif // !PRODUCT | 1526 #endif // !PRODUCT |
| 1559 | 1527 |
| 1560 } // namespace dart | 1528 } // namespace dart |
| OLD | NEW |