| 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 |