Chromium Code Reviews| 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 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 865 const uword original_pc_; | 865 const uword original_pc_; |
| 866 const uword original_fp_; | 866 const uword original_fp_; |
| 867 const uword original_sp_; | 867 const uword original_sp_; |
| 868 uword lower_bound_; | 868 uword lower_bound_; |
| 869 }; | 869 }; |
| 870 | 870 |
| 871 | 871 |
| 872 static void CopyPCMarkerIfSafe(Sample* sample) { | 872 static void CopyPCMarkerIfSafe(Sample* sample) { |
| 873 ASSERT(sample != NULL); | 873 ASSERT(sample != NULL); |
| 874 | 874 |
| 875 if (sample->vm_tag() != VMTag::kDartTagId) { | |
| 876 // We can only trust the stack pointer if we are executing Dart code. | |
| 877 // See http://dartbug.com/20421 for details. | |
| 878 return; | |
| 879 } | |
| 875 uword* fp = reinterpret_cast<uword*>(sample->fp()); | 880 uword* fp = reinterpret_cast<uword*>(sample->fp()); |
| 876 uword* sp = reinterpret_cast<uword*>(sample->sp()); | 881 uword* sp = reinterpret_cast<uword*>(sample->sp()); |
| 877 | 882 |
| 878 // If FP == SP, the pc marker hasn't been pushed. | 883 // If FP == SP, the pc marker hasn't been pushed. |
| 879 if (fp > sp) { | 884 if (fp > sp) { |
| 880 #if defined(TARGET_OS_WINDOWS) | 885 #if defined(TARGET_OS_WINDOWS) |
| 881 COMPILE_ASSERT(kPcMarkerSlotFromFp < 0); | 886 COMPILE_ASSERT(kPcMarkerSlotFromFp < 0); |
| 882 // If the fp is at the beginning of a page, it may be unsafe to access | 887 // If the fp is at the beginning of a page, it may be unsafe to access |
| 883 // the pc marker, because we are reading it from a different thread on | 888 // the pc marker, because we are reading it from a different thread on |
| 884 // Windows. The marker is below fp and the previous page may be a guard | 889 // Windows. The marker is below fp and the previous page may be a guard |
| 885 // page. | 890 // page. |
| 886 const intptr_t kPageMask = VirtualMemory::PageSize() - 1; | 891 const intptr_t kPageMask = VirtualMemory::PageSize() - 1; |
| 887 if ((sample->fp() & kPageMask) == 0) { | 892 if ((sample->fp() & kPageMask) == 0) { |
| 888 return; | 893 return; |
| 889 } | 894 } |
| 890 #endif | 895 #endif |
| 891 uword* pc_marker_ptr = fp + kPcMarkerSlotFromFp; | 896 uword* pc_marker_ptr = fp + kPcMarkerSlotFromFp; |
| 892 // MSan/ASan are unaware of frames initialized by generated code. | 897 // MSan/ASan are unaware of frames initialized by generated code. |
| 893 MSAN_UNPOISON(pc_marker_ptr, kWordSize); | 898 MSAN_UNPOISON(pc_marker_ptr, kWordSize); |
| 894 ASAN_UNPOISON(pc_marker_ptr, kWordSize); | 899 ASAN_UNPOISON(pc_marker_ptr, kWordSize); |
| 895 sample->set_pc_marker(*pc_marker_ptr); | 900 sample->set_pc_marker(*pc_marker_ptr); |
| 896 } | 901 } |
| 897 } | 902 } |
| 898 | 903 |
| 899 | 904 |
| 900 static void CopyStackBuffer(Sample* sample) { | 905 static void CopyStackBuffer(Sample* sample) { |
| 901 ASSERT(sample != NULL); | 906 ASSERT(sample != NULL); |
| 907 if (sample->vm_tag() != VMTag::kDartTagId) { | |
| 908 // We can only trust the stack pointer if we are executing Dart code. | |
| 909 // See http://dartbug.com/20421 for details. | |
| 910 return; | |
| 911 } | |
| 902 uword* sp = reinterpret_cast<uword*>(sample->sp()); | 912 uword* sp = reinterpret_cast<uword*>(sample->sp()); |
| 903 uword* buffer = sample->GetStackBuffer(); | 913 uword* buffer = sample->GetStackBuffer(); |
| 904 if (sp != NULL) { | 914 if (sp != NULL) { |
| 905 for (intptr_t i = 0; i < Sample::kStackBufferSizeInWords; i++) { | 915 for (intptr_t i = 0; i < Sample::kStackBufferSizeInWords; i++) { |
| 906 MSAN_UNPOISON(sp, kWordSize); | 916 MSAN_UNPOISON(sp, kWordSize); |
| 907 ASAN_UNPOISON(sp, kWordSize); | 917 ASAN_UNPOISON(sp, kWordSize); |
| 908 buffer[i] = *sp; | 918 buffer[i] = *sp; |
| 909 sp++; | 919 sp++; |
| 910 } | 920 } |
| 911 } | 921 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1010 #endif | 1020 #endif |
| 1011 // Increment counter for vm tag. | 1021 // Increment counter for vm tag. |
| 1012 VMTagCounters* counters = isolate->vm_tag_counters(); | 1022 VMTagCounters* counters = isolate->vm_tag_counters(); |
| 1013 ASSERT(counters != NULL); | 1023 ASSERT(counters != NULL); |
| 1014 counters->Increment(vm_tag); | 1024 counters->Increment(vm_tag); |
| 1015 sample->set_vm_tag(vm_tag); | 1025 sample->set_vm_tag(vm_tag); |
| 1016 sample->set_user_tag(isolate->user_tag()); | 1026 sample->set_user_tag(isolate->user_tag()); |
| 1017 sample->set_sp(sp); | 1027 sample->set_sp(sp); |
| 1018 sample->set_fp(state.fp); | 1028 sample->set_fp(state.fp); |
| 1019 sample->set_lr(state.lr); | 1029 sample->set_lr(state.lr); |
| 1020 CopyStackBuffer(sample); | 1030 CopyStackBuffer(sample); |
|
koda
2015/02/26 21:05:31
I would prefer to have the "if" here instead, and
| |
| 1021 #if !(defined(TARGET_OS_WINDOWS) && defined(TARGET_ARCH_X64)) | 1031 CopyPCMarkerIfSafe(sample); |
| 1022 // It is never safe to read other thread's stack unless on Win64 | |
| 1023 // other thread is inside Dart code. | |
| 1024 if (vm_tag != VMTag::kDartTagId) { | |
| 1025 CopyPCMarkerIfSafe(sample); | |
| 1026 } | |
| 1027 #endif | |
| 1028 | 1032 |
| 1029 // Walk the call stack. | 1033 // Walk the call stack. |
| 1030 if (FLAG_profile_vm) { | 1034 if (FLAG_profile_vm) { |
| 1031 // Always walk the native stack collecting both native and Dart frames. | 1035 // Always walk the native stack collecting both native and Dart frames. |
| 1032 ProfilerNativeStackWalker stackWalker(sample, | 1036 ProfilerNativeStackWalker stackWalker(sample, |
| 1033 stack_lower, | 1037 stack_lower, |
| 1034 stack_upper, | 1038 stack_upper, |
| 1035 state.pc, | 1039 state.pc, |
| 1036 state.fp, | 1040 state.fp, |
| 1037 sp); | 1041 sp); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1070 state.pc, | 1074 state.pc, |
| 1071 state.fp, | 1075 state.fp, |
| 1072 sp); | 1076 sp); |
| 1073 stackWalker.walk(); | 1077 stackWalker.walk(); |
| 1074 #endif | 1078 #endif |
| 1075 } | 1079 } |
| 1076 } | 1080 } |
| 1077 } | 1081 } |
| 1078 | 1082 |
| 1079 } // namespace dart | 1083 } // namespace dart |
| OLD | NEW |