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 |
421 // Executing Dart code, walk the stack. | 461 // Executing Dart code, walk the stack. |
422 class ProfilerDartStackWalker : public ProfilerStackWalker { | 462 class ProfilerDartStackWalker : public ProfilerStackWalker { |
423 public: | 463 public: |
424 ProfilerDartStackWalker(Thread* thread, | 464 ProfilerDartStackWalker(Isolate* isolate, |
425 Sample* sample, | 465 Sample* sample, |
426 SampleBuffer* sample_buffer, | 466 SampleBuffer* sample_buffer, |
427 uword stack_lower, | 467 uword stack_lower, |
428 uword stack_upper, | 468 uword stack_upper, |
429 uword pc, | 469 uword pc, |
430 uword fp, | 470 uword fp, |
431 uword sp, | 471 uword sp) |
432 bool exited_dart_code, | 472 : ProfilerStackWalker(isolate, sample, sample_buffer), |
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)), | |
438 stack_upper_(stack_upper), | 473 stack_upper_(stack_upper), |
439 stack_lower_(stack_lower), | 474 stack_lower_(stack_lower) { |
440 has_exit_frame_(exited_dart_code) { | 475 pc_ = reinterpret_cast<uword*>(pc); |
441 if (exited_dart_code) { | 476 fp_ = reinterpret_cast<uword*>(fp); |
442 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, | 477 sp_ = reinterpret_cast<uword*>(sp); |
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 } | |
465 } | 478 } |
466 | 479 |
467 void walk() { | 480 void walk() { |
468 sample_->set_exit_frame_sample(has_exit_frame_); | 481 sample_->set_exit_frame_sample(false); |
469 if (!ValidFramePointer()) { | 482 if (!ValidFramePointer()) { |
470 sample_->set_ignore_sample(true); | 483 sample_->set_ignore_sample(true); |
471 return; | 484 return; |
472 } | 485 } |
473 ASSERT(ValidFramePointer()); | 486 ASSERT(ValidFramePointer()); |
474 uword return_pc = InitialReturnAddress(); | 487 uword return_pc = InitialReturnAddress(); |
475 if (StubCode::InInvocationStub(return_pc)) { | 488 if (StubCode::InInvocationStub(return_pc)) { |
476 // Edge case- we have called out from the Invocation Stub but have not | 489 // Edge case- we have called out from the Invocation Stub but have not |
477 // created the stack frame of the callee. Attempt to locate the exit | 490 // created the stack frame of the callee. Attempt to locate the exit |
478 // frame before walking the stack. | 491 // frame before walking the stack. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 } | 598 } |
586 uword cursor = reinterpret_cast<uword>(fp); | 599 uword cursor = reinterpret_cast<uword>(fp); |
587 cursor += sizeof(fp); | 600 cursor += sizeof(fp); |
588 return (cursor >= stack_lower_) && (cursor < stack_upper_); | 601 return (cursor >= stack_lower_) && (cursor < stack_upper_); |
589 } | 602 } |
590 | 603 |
591 uword* pc_; | 604 uword* pc_; |
592 uword* fp_; | 605 uword* fp_; |
593 uword* sp_; | 606 uword* sp_; |
594 const uword stack_upper_; | 607 const uword stack_upper_; |
595 const uword stack_lower_; | 608 uword stack_lower_; |
596 bool has_exit_frame_; | |
597 }; | 609 }; |
598 | 610 |
599 | 611 |
600 // If the VM is compiled without frame pointers (which is the default on | 612 // If the VM is compiled without frame pointers (which is the default on |
601 // recent GCC versions with optimizing enabled) the stack walking code may | 613 // recent GCC versions with optimizing enabled) the stack walking code may |
602 // fail. | 614 // fail. |
603 // | 615 // |
604 class ProfilerNativeStackWalker : public ProfilerStackWalker { | 616 class ProfilerNativeStackWalker : public ProfilerStackWalker { |
605 public: | 617 public: |
606 ProfilerNativeStackWalker(Isolate* isolate, | 618 ProfilerNativeStackWalker(Isolate* isolate, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 return EXCEPTION_EXECUTE_HANDLER; | 751 return EXCEPTION_EXECUTE_HANDLER; |
740 } | 752 } |
741 #endif | 753 #endif |
742 | 754 |
743 // All memory access done to collect the sample is performed in CollectSample. | 755 // All memory access done to collect the sample is performed in CollectSample. |
744 static void CollectSample(Isolate* isolate, | 756 static void CollectSample(Isolate* isolate, |
745 bool exited_dart_code, | 757 bool exited_dart_code, |
746 bool in_dart_code, | 758 bool in_dart_code, |
747 Sample* sample, | 759 Sample* sample, |
748 ProfilerNativeStackWalker* native_stack_walker, | 760 ProfilerNativeStackWalker* native_stack_walker, |
| 761 ProfilerDartExitStackWalker* dart_exit_stack_walker, |
749 ProfilerDartStackWalker* dart_stack_walker, | 762 ProfilerDartStackWalker* dart_stack_walker, |
750 uword pc, | 763 uword pc, |
751 uword fp, | 764 uword fp, |
752 uword sp, | 765 uword sp, |
753 ProfilerCounters* counters) { | 766 ProfilerCounters* counters) { |
754 ASSERT(counters != NULL); | 767 ASSERT(counters != NULL); |
755 #if defined(TARGET_OS_WINDOWS) | 768 #if defined(TARGET_OS_WINDOWS) |
756 // Use structured exception handling to trap guard page access on Windows. | 769 // Use structured exception handling to trap guard page access on Windows. |
757 __try { | 770 __try { |
758 #endif | 771 #endif |
759 | 772 |
760 if (in_dart_code) { | 773 if (in_dart_code) { |
761 // 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. |
762 // See http://dartbug.com/20421 for details. | 775 // See http://dartbug.com/20421 for details. |
763 CopyStackBuffer(sample, sp); | 776 CopyStackBuffer(sample, sp); |
764 } | 777 } |
765 | 778 |
766 if (FLAG_profile_vm) { | 779 if (FLAG_profile_vm) { |
767 // Always walk the native stack collecting both native and Dart frames. | 780 // Always walk the native stack collecting both native and Dart frames. |
768 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1); | 781 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1); |
769 native_stack_walker->walk(); | 782 native_stack_walker->walk(); |
770 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { | 783 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { |
771 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1); | 784 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1); |
772 // 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. |
773 dart_stack_walker->walk(); | 786 dart_exit_stack_walker->walk(); |
774 } else if (StubCode::HasBeenInitialized() && in_dart_code) { | 787 } else if (StubCode::HasBeenInitialized() && in_dart_code) { |
775 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1); | 788 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1); |
776 // We are executing Dart code. We have frame pointers. | 789 // We are executing Dart code. We have frame pointers. |
777 dart_stack_walker->walk(); | 790 dart_stack_walker->walk(); |
778 } else { | 791 } else { |
779 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1); | 792 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1); |
780 sample->SetAt(0, pc); | 793 sample->SetAt(0, pc); |
781 } | 794 } |
782 | 795 |
783 #if defined(TARGET_OS_WINDOWS) | 796 #if defined(TARGET_OS_WINDOWS) |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 return reinterpret_cast<uintptr_t>(_ReturnAddress()); | 937 return reinterpret_cast<uintptr_t>(_ReturnAddress()); |
925 } | 938 } |
926 #else | 939 #else |
927 static uintptr_t __attribute__((noinline)) GetProgramCounter() { | 940 static uintptr_t __attribute__((noinline)) GetProgramCounter() { |
928 return reinterpret_cast<uintptr_t>( | 941 return reinterpret_cast<uintptr_t>( |
929 __builtin_extract_return_addr(__builtin_return_address(0))); | 942 __builtin_extract_return_addr(__builtin_return_address(0))); |
930 } | 943 } |
931 #endif | 944 #endif |
932 | 945 |
933 | 946 |
934 #if defined(TARGET_OS_WINDOWS) | 947 void Profiler::DumpStackTrace(bool native_stack_trace) { |
935 static uintptr_t GetFramePointer() { | |
936 #if defined(HOST_ARCH_IA32) | |
937 uintptr_t fp = 0; | |
938 COPY_FP_REGISTER(fp); | |
939 return fp; | |
940 #else | |
941 // We don't have the asm equivalent to get at the frame pointer on | |
942 // windows x64, return the stack pointer instead. | |
943 return Thread::GetCurrentStackPointer(); | |
944 #endif // defined(HOST_ARCH_IA32). | |
945 } | |
946 #else | |
947 static uintptr_t GetFramePointer() { | |
948 uintptr_t fp = 0; | |
949 COPY_FP_REGISTER(fp); | |
950 return fp; | |
951 } | |
952 #endif // defined(TARGET_OS_WINDOWS). | |
953 | |
954 | |
955 void Profiler::DumpStackTrace() { | |
956 // Allow only one stack trace to prevent recursively printing stack traces if | 948 // Allow only one stack trace to prevent recursively printing stack traces if |
957 // we hit an assert while printing the stack. | 949 // we hit an assert while printing the stack. |
958 static uintptr_t started_dump = 0; | 950 static uintptr_t started_dump = 0; |
959 if (AtomicOperations::FetchAndIncrement(&started_dump) != 0) { | 951 if (AtomicOperations::FetchAndIncrement(&started_dump) != 0) { |
960 OS::PrintErr("Aborting re-entrant request for stack trace.\n"); | 952 OS::PrintErr("Aborting re-entrant request for stack trace.\n"); |
961 return; | 953 return; |
962 } | 954 } |
963 | 955 |
964 Thread* thread = Thread::Current(); | 956 Thread* thread = Thread::Current(); |
965 if (thread == NULL) { | 957 if (thread == NULL) { |
966 return; | 958 return; |
967 } | 959 } |
968 OSThread* os_thread = thread->os_thread(); | 960 OSThread* os_thread = thread->os_thread(); |
969 ASSERT(os_thread != NULL); | 961 ASSERT(os_thread != NULL); |
970 Isolate* isolate = thread->isolate(); | 962 Isolate* isolate = thread->isolate(); |
971 if (!CheckIsolate(isolate)) { | 963 if (!CheckIsolate(isolate)) { |
972 return; | 964 return; |
973 } | 965 } |
974 | 966 |
975 OS::PrintErr("Dumping native stack trace for thread %" Px "\n", | 967 const bool exited_dart_code = thread->HasExitedDartCode(); |
| 968 |
| 969 OS::PrintErr("Dumping %s stack trace for thread %" Px "\n", |
| 970 native_stack_trace ? "native" : "dart-only", |
976 OSThread::ThreadIdToIntPtr(os_thread->trace_id())); | 971 OSThread::ThreadIdToIntPtr(os_thread->trace_id())); |
977 | 972 |
978 uintptr_t sp = Thread::GetCurrentStackPointer(); | 973 uintptr_t sp = Thread::GetCurrentStackPointer(); |
979 uintptr_t fp = GetFramePointer(); | 974 uintptr_t fp = 0; |
980 uintptr_t pc = GetProgramCounter(); | 975 uintptr_t pc = GetProgramCounter(); |
| 976 |
| 977 COPY_FP_REGISTER(fp); |
| 978 |
981 uword stack_lower = 0; | 979 uword stack_lower = 0; |
982 uword stack_upper = 0; | 980 uword stack_upper = 0; |
983 | 981 |
984 if (!InitialRegisterCheck(pc, fp, sp)) { | 982 if (!InitialRegisterCheck(pc, fp, sp)) { |
985 OS::PrintErr("Stack dump aborted because InitialRegisterCheck.\n"); | 983 OS::PrintErr("Stack dump aborted because InitialRegisterCheck.\n"); |
986 return; | 984 return; |
987 } | 985 } |
988 | 986 |
989 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, | 987 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, |
990 &stack_upper)) { | 988 &stack_upper)) { |
991 OS::PrintErr( | 989 OS::PrintErr( |
992 "Stack dump aborted because GetAndValidateIsolateStackBounds.\n"); | 990 "Stack dump aborted because GetAndValidateIsolateStackBounds.\n"); |
993 return; | 991 return; |
994 } | 992 } |
995 | 993 |
996 ProfilerNativeStackWalker native_stack_walker( | 994 if (native_stack_trace) { |
997 isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp); | 995 ProfilerNativeStackWalker native_stack_walker( |
998 native_stack_walker.walk(); | 996 isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp); |
| 997 native_stack_walker.walk(); |
| 998 } else if (exited_dart_code) { |
| 999 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, NULL, |
| 1000 NULL); |
| 1001 dart_exit_stack_walker.walk(); |
| 1002 } else { |
| 1003 ProfilerDartStackWalker dart_stack_walker(isolate, NULL, NULL, stack_lower, |
| 1004 stack_upper, pc, fp, sp); |
| 1005 } |
999 OS::PrintErr("-- End of DumpStackTrace\n"); | 1006 OS::PrintErr("-- End of DumpStackTrace\n"); |
1000 } | 1007 } |
1001 | 1008 |
1002 | 1009 |
1003 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { | 1010 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
1004 ASSERT(thread != NULL); | 1011 ASSERT(thread != NULL); |
1005 OSThread* os_thread = thread->os_thread(); | 1012 OSThread* os_thread = thread->os_thread(); |
1006 ASSERT(os_thread != NULL); | 1013 ASSERT(os_thread != NULL); |
1007 Isolate* isolate = thread->isolate(); | 1014 Isolate* isolate = thread->isolate(); |
1008 if (!CheckIsolate(isolate)) { | 1015 if (!CheckIsolate(isolate)) { |
1009 return; | 1016 return; |
1010 } | 1017 } |
1011 | 1018 |
1012 const bool exited_dart_code = thread->HasExitedDartCode(); | 1019 const bool exited_dart_code = thread->HasExitedDartCode(); |
1013 | 1020 |
1014 SampleBuffer* sample_buffer = Profiler::sample_buffer(); | 1021 SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
1015 if (sample_buffer == NULL) { | 1022 if (sample_buffer == NULL) { |
1016 // Profiler not initialized. | 1023 // Profiler not initialized. |
1017 return; | 1024 return; |
1018 } | 1025 } |
1019 | 1026 |
1020 uintptr_t sp = Thread::GetCurrentStackPointer(); | 1027 if (FLAG_profile_vm) { |
1021 uintptr_t fp = GetFramePointer(); | 1028 uintptr_t sp = Thread::GetCurrentStackPointer(); |
1022 uintptr_t pc = GetProgramCounter(); | 1029 uintptr_t fp = 0; |
1023 uword stack_lower = 0; | 1030 uintptr_t pc = GetProgramCounter(); |
1024 uword stack_upper = 0; | |
1025 | 1031 |
1026 if (!InitialRegisterCheck(pc, fp, sp)) { | 1032 COPY_FP_REGISTER(fp); |
1027 return; | |
1028 } | |
1029 | 1033 |
1030 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, | 1034 uword stack_lower = 0; |
1031 &stack_upper)) { | 1035 uword stack_upper = 0; |
1032 // Could not get stack boundary. | |
1033 return; | |
1034 } | |
1035 | 1036 |
1036 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); | 1037 if (!InitialRegisterCheck(pc, fp, sp)) { |
1037 sample->SetAllocationCid(cid); | 1038 return; |
| 1039 } |
1038 | 1040 |
1039 if (FLAG_profile_vm) { | 1041 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, |
| 1042 &stack_upper)) { |
| 1043 // Could not get stack boundary. |
| 1044 return; |
| 1045 } |
| 1046 |
| 1047 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); |
| 1048 sample->SetAllocationCid(cid); |
1040 ProfilerNativeStackWalker native_stack_walker( | 1049 ProfilerNativeStackWalker native_stack_walker( |
1041 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); | 1050 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
1042 native_stack_walker.walk(); | 1051 native_stack_walker.walk(); |
1043 } else if (exited_dart_code) { | 1052 } else if (exited_dart_code) { |
1044 ProfilerDartStackWalker dart_exit_stack_walker( | 1053 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); |
1045 thread, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp, | 1054 sample->SetAllocationCid(cid); |
1046 exited_dart_code, true); | 1055 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, sample, |
| 1056 sample_buffer); |
1047 dart_exit_stack_walker.walk(); | 1057 dart_exit_stack_walker.walk(); |
1048 } else { | 1058 } else { |
1049 // Fall back. | 1059 // Fall back. |
1050 uintptr_t pc = GetProgramCounter(); | 1060 uintptr_t pc = GetProgramCounter(); |
1051 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); | 1061 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); |
1052 sample->SetAllocationCid(cid); | 1062 sample->SetAllocationCid(cid); |
1053 sample->SetAt(0, pc); | 1063 sample->SetAt(0, pc); |
1054 } | 1064 } |
1055 } | 1065 } |
1056 | 1066 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); | 1185 Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); |
1176 // Increment counter for vm tag. | 1186 // Increment counter for vm tag. |
1177 VMTagCounters* counters = isolate->vm_tag_counters(); | 1187 VMTagCounters* counters = isolate->vm_tag_counters(); |
1178 ASSERT(counters != NULL); | 1188 ASSERT(counters != NULL); |
1179 if (thread->IsMutatorThread()) { | 1189 if (thread->IsMutatorThread()) { |
1180 counters->Increment(sample->vm_tag()); | 1190 counters->Increment(sample->vm_tag()); |
1181 } | 1191 } |
1182 | 1192 |
1183 ProfilerNativeStackWalker native_stack_walker( | 1193 ProfilerNativeStackWalker native_stack_walker( |
1184 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); | 1194 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
| 1195 |
| 1196 ProfilerDartExitStackWalker dart_exit_stack_walker(thread, isolate, sample, |
| 1197 sample_buffer); |
| 1198 |
| 1199 ProfilerDartStackWalker dart_stack_walker( |
| 1200 isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
| 1201 |
1185 const bool exited_dart_code = thread->HasExitedDartCode(); | 1202 const bool exited_dart_code = thread->HasExitedDartCode(); |
1186 ProfilerDartStackWalker dart_stack_walker(thread, sample, sample_buffer, | |
1187 stack_lower, stack_upper, pc, fp, | |
1188 sp, exited_dart_code, false); | |
1189 | 1203 |
1190 // All memory access is done inside CollectSample. | 1204 // All memory access is done inside CollectSample. |
1191 CollectSample(isolate, exited_dart_code, in_dart_code, sample, | 1205 CollectSample(isolate, exited_dart_code, in_dart_code, sample, |
1192 &native_stack_walker, &dart_stack_walker, pc, fp, sp, | 1206 &native_stack_walker, &dart_exit_stack_walker, |
1193 &counters_); | 1207 &dart_stack_walker, pc, fp, sp, &counters_); |
1194 } | 1208 } |
1195 | 1209 |
1196 | 1210 |
1197 CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) { | 1211 CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) { |
1198 ASSERT(!code_.IsNull()); | 1212 ASSERT(!code_.IsNull()); |
1199 } | 1213 } |
1200 | 1214 |
1201 | 1215 |
1202 uword CodeDescriptor::Start() const { | 1216 uword CodeDescriptor::Start() const { |
1203 return code_.PayloadStart(); | 1217 return code_.PayloadStart(); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 | 1529 |
1516 | 1530 |
1517 ProcessedSampleBuffer::ProcessedSampleBuffer() | 1531 ProcessedSampleBuffer::ProcessedSampleBuffer() |
1518 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { | 1532 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { |
1519 ASSERT(code_lookup_table_ != NULL); | 1533 ASSERT(code_lookup_table_ != NULL); |
1520 } | 1534 } |
1521 | 1535 |
1522 #endif // !PRODUCT | 1536 #endif // !PRODUCT |
1523 | 1537 |
1524 } // namespace dart | 1538 } // namespace dart |
OLD | NEW |