Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: runtime/vm/profiler.cc

Issue 183633002: Turn stack walking verification into a flag (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/utils.h" 5 #include "platform/utils.h"
6 6
7 #include "vm/allocation.h" 7 #include "vm/allocation.h"
8 #include "vm/atomic.h" 8 #include "vm/atomic.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 15 matching lines...) Expand all
26 #else 26 #else
27 DEFINE_FLAG(bool, profile, true, "Enable Sampling Profiler"); 27 DEFINE_FLAG(bool, profile, true, "Enable Sampling Profiler");
28 #endif 28 #endif
29 DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates."); 29 DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates.");
30 DEFINE_FLAG(charp, profile_dir, NULL, 30 DEFINE_FLAG(charp, profile_dir, NULL,
31 "Enable writing profile data into specified directory."); 31 "Enable writing profile data into specified directory.");
32 DEFINE_FLAG(int, profile_period, 1000, 32 DEFINE_FLAG(int, profile_period, 1000,
33 "Time between profiler samples in microseconds. Minimum 250."); 33 "Time between profiler samples in microseconds. Minimum 250.");
34 DEFINE_FLAG(int, profile_depth, 8, 34 DEFINE_FLAG(int, profile_depth, 8,
35 "Maximum number stack frames walked. Minimum 1. Maximum 255."); 35 "Maximum number stack frames walked. Minimum 1. Maximum 255.");
36 DEFINE_FLAG(bool, profile_verify_stack_walk, false,
37 "Verify instruction addresses while walking the stack.");
36 38
37 bool Profiler::initialized_ = false; 39 bool Profiler::initialized_ = false;
38 SampleBuffer* Profiler::sample_buffer_ = NULL; 40 SampleBuffer* Profiler::sample_buffer_ = NULL;
39 41
40 void Profiler::InitOnce() { 42 void Profiler::InitOnce() {
41 // Place some sane restrictions on user controlled flags. 43 // Place some sane restrictions on user controlled flags.
42 SetSamplePeriod(FLAG_profile_period); 44 SetSamplePeriod(FLAG_profile_period);
43 SetSampleDepth(FLAG_profile_depth); 45 SetSampleDepth(FLAG_profile_depth);
44 if (!FLAG_profile) { 46 if (!FLAG_profile) {
45 return; 47 return;
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 uword sp) 884 uword sp)
883 : sample_(sample), 885 : sample_(sample),
884 stack_upper_(stack_upper), 886 stack_upper_(stack_upper),
885 original_pc_(pc), 887 original_pc_(pc),
886 original_fp_(fp), 888 original_fp_(fp),
887 original_sp_(sp), 889 original_sp_(sp),
888 lower_bound_(stack_lower) { 890 lower_bound_(stack_lower) {
889 ASSERT(sample_ != NULL); 891 ASSERT(sample_ != NULL);
890 } 892 }
891 893
892 #if defined(DEBUG_STACK_WALK) 894 int walk(Heap* heap) {
893 void set_heap(Heap* heap) {
894 heap_ = heap;
895 }
896 #endif
897
898 int walk() {
899 const intptr_t kMaxStep = 0x1000; // 4K. 895 const intptr_t kMaxStep = 0x1000; // 4K.
900 const bool kWalkStack = true; // Walk the stack. 896 const bool kWalkStack = true; // Walk the stack.
901 // Always store the exclusive PC. 897 // Always store the exclusive PC.
902 sample_->SetAt(0, original_pc_); 898 sample_->SetAt(0, original_pc_);
903 if (!kWalkStack) { 899 if (!kWalkStack) {
904 // Not walking the stack, only took exclusive sample. 900 // Not walking the stack, only took exclusive sample.
905 return 1; 901 return 1;
906 } 902 }
907 uword* pc = reinterpret_cast<uword*>(original_pc_); 903 uword* pc = reinterpret_cast<uword*>(original_pc_);
908 uword* fp = reinterpret_cast<uword*>(original_fp_); 904 uword* fp = reinterpret_cast<uword*>(original_fp_);
909 uword* previous_fp = fp; 905 uword* previous_fp = fp;
910 if (original_sp_ > original_fp_) { 906 if (original_sp_ > original_fp_) {
911 // Stack pointer should not be above frame pointer. 907 // Stack pointer should not be above frame pointer.
912 return 1; 908 return 1;
913 } 909 }
914 intptr_t gap = original_fp_ - original_sp_; 910 intptr_t gap = original_fp_ - original_sp_;
915 if (gap >= kMaxStep) { 911 if (gap >= kMaxStep) {
916 // Gap between frame pointer and stack pointer is 912 // Gap between frame pointer and stack pointer is
917 // too large. 913 // too large.
918 return 1; 914 return 1;
919 } 915 }
920 if (original_sp_ < lower_bound_) { 916 if (original_sp_ < lower_bound_) {
921 // The stack pointer gives us a better lower bound than 917 // The stack pointer gives us a better lower bound than
922 // the isolates stack limit. 918 // the isolates stack limit.
923 lower_bound_ = original_sp_; 919 lower_bound_ = original_sp_;
924 } 920 }
925 int i = 0; 921 int i = 0;
926 for (; i < FLAG_profile_depth; i++) { 922 for (; i < FLAG_profile_depth; i++) {
927 #if defined(DEBUG_STACK_WALK) 923 if (FLAG_profile_verify_stack_walk) {
928 VerifyCodeAddress(i, reinterpret_cast<uword>(pc)); 924 VerifyCodeAddress(heap, i, reinterpret_cast<uword>(pc));
929 #endif 925 }
930 sample_->SetAt(i, reinterpret_cast<uword>(pc)); 926 sample_->SetAt(i, reinterpret_cast<uword>(pc));
931 if (!ValidFramePointer(fp)) { 927 if (!ValidFramePointer(fp)) {
932 return i + 1; 928 return i + 1;
933 } 929 }
934 pc = CallerPC(fp); 930 pc = CallerPC(fp);
935 previous_fp = fp; 931 previous_fp = fp;
936 fp = CallerFP(fp); 932 fp = CallerFP(fp);
937 intptr_t step = fp - previous_fp; 933 intptr_t step = fp - previous_fp;
938 if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) { 934 if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) {
939 // Frame pointer step is too large. 935 // Frame pointer step is too large.
940 // Frame pointer did not move to a higher address. 936 // Frame pointer did not move to a higher address.
941 // Frame pointer is outside of isolate stack bounds. 937 // Frame pointer is outside of isolate stack bounds.
942 return i + 1; 938 return i + 1;
943 } 939 }
944 // Move the lower bound up. 940 // Move the lower bound up.
945 lower_bound_ = reinterpret_cast<uword>(fp); 941 lower_bound_ = reinterpret_cast<uword>(fp);
946 } 942 }
947 return i; 943 return i;
948 } 944 }
949 945
950 private: 946 private:
951 #if defined(DEBUG_STACK_WALK) 947 void VerifyCodeAddress(Heap* heap, int i, uword pc) {
952 void VerifyCodeAddress(int i, uword pc) { 948 if (heap != NULL) {
953 if (heap_ != NULL) { 949 if (heap->Contains(pc) && !heap->CodeContains(pc)) {
954 if (heap_->Contains(pc) && !heap_->CodeContains(pc)) {
955 for (int j = 0; j < i; j++) { 950 for (int j = 0; j < i; j++) {
956 OS::Print("%d %" Px "\n", j, sample_->At(j)); 951 OS::Print("%d %" Px "\n", j, sample_->At(j));
957 } 952 }
958 OS::Print("%d %" Px " <--\n", i, pc); 953 OS::Print("%d %" Px " <--\n", i, pc);
959 OS::Print("---ASSERT-FAILED---\n"); 954 OS::Print("---ASSERT-FAILED---\n");
960 OS::Print("%" Px " %" Px "\n", original_pc_, original_fp_); 955 OS::Print("%" Px " %" Px "\n", original_pc_, original_fp_);
961 UNREACHABLE(); 956 UNREACHABLE();
962 } 957 }
963 } 958 }
964 } 959 }
965 #endif
966 960
967 uword* CallerPC(uword* fp) const { 961 uword* CallerPC(uword* fp) const {
968 ASSERT(fp != NULL); 962 ASSERT(fp != NULL);
969 return reinterpret_cast<uword*>(*(fp + kSavedCallerPcSlotFromFp)); 963 return reinterpret_cast<uword*>(*(fp + kSavedCallerPcSlotFromFp));
970 } 964 }
971 965
972 uword* CallerFP(uword* fp) const { 966 uword* CallerFP(uword* fp) const {
973 ASSERT(fp != NULL); 967 ASSERT(fp != NULL);
974 return reinterpret_cast<uword*>(*(fp + kSavedCallerFpSlotFromFp)); 968 return reinterpret_cast<uword*>(*(fp + kSavedCallerFpSlotFromFp));
975 } 969 }
976 970
977 bool ValidFramePointer(uword* fp) const { 971 bool ValidFramePointer(uword* fp) const {
978 if (fp == NULL) { 972 if (fp == NULL) {
979 return false; 973 return false;
980 } 974 }
981 uword cursor = reinterpret_cast<uword>(fp); 975 uword cursor = reinterpret_cast<uword>(fp);
982 cursor += sizeof(fp); 976 cursor += sizeof(fp);
983 bool r = cursor >= lower_bound_ && cursor < stack_upper_; 977 bool r = cursor >= lower_bound_ && cursor < stack_upper_;
984 return r; 978 return r;
985 } 979 }
986 980
987 #if defined(DEBUG_STACK_WALK) 981
988 Heap* heap_;
989 #endif
990 Sample* sample_; 982 Sample* sample_;
991 const uword stack_upper_; 983 const uword stack_upper_;
992 const uword original_pc_; 984 const uword original_pc_;
993 const uword original_fp_; 985 const uword original_fp_;
994 const uword original_sp_; 986 const uword original_sp_;
995 uword lower_bound_; 987 uword lower_bound_;
996 }; 988 };
997 989
998 void Profiler::RecordSampleInterruptCallback( 990 void Profiler::RecordSampleInterruptCallback(
999 const InterruptedThreadState& state, 991 const InterruptedThreadState& state,
(...skipping 14 matching lines...) Expand all
1014 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid); 1006 sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid);
1015 uword stack_lower = 0; 1007 uword stack_lower = 0;
1016 uword stack_upper = 0; 1008 uword stack_upper = 0;
1017 isolate->GetStackBounds(&stack_lower, &stack_upper); 1009 isolate->GetStackBounds(&stack_lower, &stack_upper);
1018 if ((stack_lower == 0) || (stack_upper == 0)) { 1010 if ((stack_lower == 0) || (stack_upper == 0)) {
1019 stack_lower = 0; 1011 stack_lower = 0;
1020 stack_upper = 0; 1012 stack_upper = 0;
1021 } 1013 }
1022 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper, 1014 ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
1023 state.pc, state.fp, state.sp); 1015 state.pc, state.fp, state.sp);
1024 #if defined(DEBUG_STACK_WALK) 1016 stackWalker.walk(isolate->heap());
1025 stackWalker.set_heap(isolate->heap());
1026 #endif
1027 stackWalker.walk();
1028 } 1017 }
1029 1018
1030 1019
1031 } // namespace dart 1020 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698