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 13 matching lines...) Expand all Loading... |
24 #include "vm/simulator.h" | 24 #include "vm/simulator.h" |
25 #include "vm/stack_frame.h" | 25 #include "vm/stack_frame.h" |
26 | 26 |
27 namespace dart { | 27 namespace dart { |
28 | 28 |
29 static const intptr_t kSampleSize = 8; | 29 static const intptr_t kSampleSize = 8; |
30 static const intptr_t kMaxSamplesPerTick = 4; | 30 static const intptr_t kMaxSamplesPerTick = 4; |
31 | 31 |
32 DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates."); | 32 DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates."); |
33 | 33 |
34 #if defined(TARGET_OS_ANDROID) || defined(TARGET_ARCH_ARM64) || \ | 34 #if defined(HOST_OS_ANDROID) || defined(TARGET_ARCH_ARM64) || \ |
35 defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS) | 35 defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS) |
36 DEFINE_FLAG(int, | 36 DEFINE_FLAG(int, |
37 profile_period, | 37 profile_period, |
38 10000, | 38 10000, |
39 "Time between profiler samples in microseconds. Minimum 50."); | 39 "Time between profiler samples in microseconds. Minimum 50."); |
40 #else | 40 #else |
41 DEFINE_FLAG(int, | 41 DEFINE_FLAG(int, |
42 profile_period, | 42 profile_period, |
43 1000, | 43 1000, |
44 "Time between profiler samples in microseconds. Minimum 50."); | 44 "Time between profiler samples in microseconds. Minimum 50."); |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 for (intptr_t i = 0; i < Sample::kStackBufferSizeInWords; i++) { | 727 for (intptr_t i = 0; i < Sample::kStackBufferSizeInWords; i++) { |
728 MSAN_UNPOISON(sp, kWordSize); | 728 MSAN_UNPOISON(sp, kWordSize); |
729 ASAN_UNPOISON(sp, kWordSize); | 729 ASAN_UNPOISON(sp, kWordSize); |
730 buffer[i] = *sp; | 730 buffer[i] = *sp; |
731 sp++; | 731 sp++; |
732 } | 732 } |
733 } | 733 } |
734 } | 734 } |
735 | 735 |
736 | 736 |
737 #if defined(TARGET_OS_WINDOWS) | 737 #if defined(HOST_OS_WINDOWS) |
738 // On Windows this code is synchronously executed from the thread interrupter | 738 // On Windows this code is synchronously executed from the thread interrupter |
739 // thread. This means we can safely have a static fault_address. | 739 // thread. This means we can safely have a static fault_address. |
740 static uword fault_address = 0; | 740 static uword fault_address = 0; |
741 static LONG GuardPageExceptionFilter(EXCEPTION_POINTERS* ep) { | 741 static LONG GuardPageExceptionFilter(EXCEPTION_POINTERS* ep) { |
742 fault_address = 0; | 742 fault_address = 0; |
743 if (ep->ExceptionRecord->ExceptionCode != STATUS_GUARD_PAGE_VIOLATION) { | 743 if (ep->ExceptionRecord->ExceptionCode != STATUS_GUARD_PAGE_VIOLATION) { |
744 return EXCEPTION_CONTINUE_SEARCH; | 744 return EXCEPTION_CONTINUE_SEARCH; |
745 } | 745 } |
746 // https://goo.gl/p5Fe10 | 746 // https://goo.gl/p5Fe10 |
747 fault_address = ep->ExceptionRecord->ExceptionInformation[1]; | 747 fault_address = ep->ExceptionRecord->ExceptionInformation[1]; |
748 // Read access. | 748 // Read access. |
749 ASSERT(ep->ExceptionRecord->ExceptionInformation[0] == 0); | 749 ASSERT(ep->ExceptionRecord->ExceptionInformation[0] == 0); |
750 return EXCEPTION_EXECUTE_HANDLER; | 750 return EXCEPTION_EXECUTE_HANDLER; |
751 } | 751 } |
752 #endif | 752 #endif |
753 | 753 |
754 // All memory access done to collect the sample is performed in CollectSample. | 754 // All memory access done to collect the sample is performed in CollectSample. |
755 static void CollectSample(Isolate* isolate, | 755 static void CollectSample(Isolate* isolate, |
756 bool exited_dart_code, | 756 bool exited_dart_code, |
757 bool in_dart_code, | 757 bool in_dart_code, |
758 Sample* sample, | 758 Sample* sample, |
759 ProfilerNativeStackWalker* native_stack_walker, | 759 ProfilerNativeStackWalker* native_stack_walker, |
760 ProfilerDartStackWalker* dart_stack_walker, | 760 ProfilerDartStackWalker* dart_stack_walker, |
761 uword pc, | 761 uword pc, |
762 uword fp, | 762 uword fp, |
763 uword sp, | 763 uword sp, |
764 ProfilerCounters* counters) { | 764 ProfilerCounters* counters) { |
765 ASSERT(counters != NULL); | 765 ASSERT(counters != NULL); |
766 #if defined(TARGET_OS_WINDOWS) | 766 #if defined(HOST_OS_WINDOWS) |
767 // Use structured exception handling to trap guard page access on Windows. | 767 // Use structured exception handling to trap guard page access on Windows. |
768 __try { | 768 __try { |
769 #endif | 769 #endif |
770 | 770 |
771 if (in_dart_code) { | 771 if (in_dart_code) { |
772 // We can only trust the stack pointer if we are executing Dart code. | 772 // We can only trust the stack pointer if we are executing Dart code. |
773 // See http://dartbug.com/20421 for details. | 773 // See http://dartbug.com/20421 for details. |
774 CopyStackBuffer(sample, sp); | 774 CopyStackBuffer(sample, sp); |
775 } | 775 } |
776 | 776 |
777 if (FLAG_profile_vm) { | 777 if (FLAG_profile_vm) { |
778 // Always walk the native stack collecting both native and Dart frames. | 778 // Always walk the native stack collecting both native and Dart frames. |
779 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1); | 779 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1); |
780 native_stack_walker->walk(); | 780 native_stack_walker->walk(); |
781 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { | 781 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { |
782 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1); | 782 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1); |
783 // We have a valid exit frame info, use the Dart stack walker. | 783 // We have a valid exit frame info, use the Dart stack walker. |
784 dart_stack_walker->walk(); | 784 dart_stack_walker->walk(); |
785 } else if (StubCode::HasBeenInitialized() && in_dart_code) { | 785 } else if (StubCode::HasBeenInitialized() && in_dart_code) { |
786 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1); | 786 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1); |
787 // We are executing Dart code. We have frame pointers. | 787 // We are executing Dart code. We have frame pointers. |
788 dart_stack_walker->walk(); | 788 dart_stack_walker->walk(); |
789 } else { | 789 } else { |
790 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1); | 790 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1); |
791 sample->SetAt(0, pc); | 791 sample->SetAt(0, pc); |
792 } | 792 } |
793 | 793 |
794 #if defined(TARGET_OS_WINDOWS) | 794 #if defined(HOST_OS_WINDOWS) |
795 // Use structured exception handling to trap guard page access. | 795 // Use structured exception handling to trap guard page access. |
796 } __except (GuardPageExceptionFilter(GetExceptionInformation())) { // NOLINT | 796 } __except (GuardPageExceptionFilter(GetExceptionInformation())) { // NOLINT |
797 // Sample collection triggered a guard page fault: | 797 // Sample collection triggered a guard page fault: |
798 // 1) discard entire sample. | 798 // 1) discard entire sample. |
799 sample->set_ignore_sample(true); | 799 sample->set_ignore_sample(true); |
800 | 800 |
801 // 2) Reenable guard bit on page that triggered the fault. | 801 // 2) Reenable guard bit on page that triggered the fault. |
802 // https://goo.gl/5mCsXW | 802 // https://goo.gl/5mCsXW |
803 DWORD new_protect = PAGE_READWRITE | PAGE_GUARD; | 803 DWORD new_protect = PAGE_READWRITE | PAGE_GUARD; |
804 DWORD old_protect = 0; | 804 DWORD old_protect = 0; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 static bool CheckIsolate(Isolate* isolate) { | 954 static bool CheckIsolate(Isolate* isolate) { |
955 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { | 955 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { |
956 // No isolate. | 956 // No isolate. |
957 return false; | 957 return false; |
958 } | 958 } |
959 return isolate != Dart::vm_isolate(); | 959 return isolate != Dart::vm_isolate(); |
960 } | 960 } |
961 | 961 |
962 | 962 |
963 void Profiler::DumpStackTrace(void* context) { | 963 void Profiler::DumpStackTrace(void* context) { |
964 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) | 964 #if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) |
965 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); | 965 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
966 mcontext_t mcontext = ucontext->uc_mcontext; | 966 mcontext_t mcontext = ucontext->uc_mcontext; |
967 uword pc = SignalHandler::GetProgramCounter(mcontext); | 967 uword pc = SignalHandler::GetProgramCounter(mcontext); |
968 uword fp = SignalHandler::GetFramePointer(mcontext); | 968 uword fp = SignalHandler::GetFramePointer(mcontext); |
969 uword sp = SignalHandler::GetCStackPointer(mcontext); | 969 uword sp = SignalHandler::GetCStackPointer(mcontext); |
970 DumpStackTrace(sp, fp, pc); | 970 DumpStackTrace(sp, fp, pc); |
971 #else | 971 #else |
972 // TODO(fschneider): Add support for more platforms. | 972 // TODO(fschneider): Add support for more platforms. |
973 // Do nothing on unsupported platforms. | 973 // Do nothing on unsupported platforms. |
974 #endif | 974 #endif |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1592 | 1592 |
1593 | 1593 |
1594 ProcessedSampleBuffer::ProcessedSampleBuffer() | 1594 ProcessedSampleBuffer::ProcessedSampleBuffer() |
1595 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { | 1595 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { |
1596 ASSERT(code_lookup_table_ != NULL); | 1596 ASSERT(code_lookup_table_ != NULL); |
1597 } | 1597 } |
1598 | 1598 |
1599 #endif // !PRODUCT | 1599 #endif // !PRODUCT |
1600 | 1600 |
1601 } // namespace dart | 1601 } // namespace dart |
OLD | NEW |