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

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

Issue 1412733008: Switch profiler from isolates to threads (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
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/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"
11 #include "vm/code_patcher.h" 11 #include "vm/code_patcher.h"
12 #include "vm/debugger.h"
12 #include "vm/instructions.h" 13 #include "vm/instructions.h"
13 #include "vm/isolate.h" 14 #include "vm/isolate.h"
14 #include "vm/json_stream.h" 15 #include "vm/json_stream.h"
15 #include "vm/lockers.h" 16 #include "vm/lockers.h"
17 #include "vm/message_handler.h"
16 #include "vm/native_symbol.h" 18 #include "vm/native_symbol.h"
17 #include "vm/object.h" 19 #include "vm/object.h"
18 #include "vm/os.h" 20 #include "vm/os.h"
19 #include "vm/profiler.h" 21 #include "vm/profiler.h"
20 #include "vm/reusable_handles.h" 22 #include "vm/reusable_handles.h"
21 #include "vm/signal_handler.h" 23 #include "vm/signal_handler.h"
22 #include "vm/simulator.h" 24 #include "vm/simulator.h"
23 #include "vm/stack_frame.h" 25 #include "vm/stack_frame.h"
24 26
25 namespace dart { 27 namespace dart {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 void Profiler::SetSamplePeriod(intptr_t period) { 99 void Profiler::SetSamplePeriod(intptr_t period) {
98 const int kMinimumProfilePeriod = 50; 100 const int kMinimumProfilePeriod = 50;
99 if (period < kMinimumProfilePeriod) { 101 if (period < kMinimumProfilePeriod) {
100 FLAG_profile_period = kMinimumProfilePeriod; 102 FLAG_profile_period = kMinimumProfilePeriod;
101 } else { 103 } else {
102 FLAG_profile_period = period; 104 FLAG_profile_period = period;
103 } 105 }
104 } 106 }
105 107
106 108
107 void Profiler::InitProfilingForIsolate(Isolate* isolate, bool shared_buffer) {
108 if (!FLAG_profile) {
109 return;
110 }
111 ASSERT(isolate == Isolate::Current());
112 ASSERT(isolate != NULL);
113 ASSERT(sample_buffer_ != NULL);
114 {
115 MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
116 SampleBuffer* sample_buffer = sample_buffer_;
117 if (!shared_buffer) {
118 sample_buffer = new SampleBuffer();
119 }
120 IsolateProfilerData* profiler_data =
121 new IsolateProfilerData(sample_buffer, !shared_buffer);
122 ASSERT(profiler_data != NULL);
123 isolate->set_profiler_data(profiler_data);
124 if (FLAG_trace_profiled_isolates) {
125 OS::Print("Profiler Setup %p %s\n", isolate, isolate->name());
126 }
127 }
128 BeginExecution(isolate);
129 }
130
131
132 void Profiler::ShutdownProfilingForIsolate(Isolate* isolate) {
133 ASSERT(isolate != NULL);
134 if (!FLAG_profile) {
135 return;
136 }
137 // We do not have a current isolate.
138 ASSERT(Isolate::Current() == NULL);
139 {
140 MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
141 IsolateProfilerData* profiler_data = isolate->profiler_data();
142 if (profiler_data == NULL) {
143 // Already freed.
144 return;
145 }
146 isolate->set_profiler_data(NULL);
147 delete profiler_data;
148 if (FLAG_trace_profiled_isolates) {
149 OS::Print("Profiler Shutdown %p %s\n", isolate, isolate->name());
150 }
151 }
152 }
153
154
155 void Profiler::BeginExecution(Isolate* isolate) { 109 void Profiler::BeginExecution(Isolate* isolate) {
156 if (isolate == NULL) { 110 if (isolate == NULL) {
157 return; 111 return;
158 } 112 }
159 if (!FLAG_profile) { 113 if (!FLAG_profile) {
160 return; 114 return;
161 } 115 }
162 ASSERT(initialized_); 116 ASSERT(initialized_);
163 IsolateProfilerData* profiler_data = isolate->profiler_data(); 117 Thread* thread = Thread::Current();
164 if (profiler_data == NULL) { 118 if (thread == NULL) {
165 return; 119 return;
166 } 120 }
167 Thread* thread = Thread::Current(); 121 thread->SetThreadInterruptCallback(SampleThreadInterruptCallback);
168 thread->SetThreadInterrupter(RecordSampleInterruptCallback, thread);
169 ThreadInterrupter::WakeUp();
170 } 122 }
171 123
172 124
173 void Profiler::EndExecution(Isolate* isolate) { 125 void Profiler::EndExecution(Isolate* isolate) {
174 if (isolate == NULL) { 126 if (isolate == NULL) {
175 return; 127 return;
176 } 128 }
177 if (!FLAG_profile) { 129 if (!FLAG_profile) {
178 return; 130 return;
179 } 131 }
180 ASSERT(initialized_); 132 ASSERT(initialized_);
181 Thread* thread = Thread::Current(); 133 Thread* thread = Thread::Current();
182 thread->SetThreadInterrupter(NULL, NULL); 134 thread->SetThreadInterruptCallback(NULL);
Ivan Posva 2015/10/28 08:27:47 It looks like we have several redundant ways of di
183 } 135 }
184 136
185 137
186 IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer,
187 bool own_sample_buffer) {
188 ASSERT(sample_buffer != NULL);
189 sample_buffer_ = sample_buffer;
190 own_sample_buffer_ = own_sample_buffer;
191 block_count_ = 0;
192 }
193
194
195 IsolateProfilerData::~IsolateProfilerData() {
196 if (own_sample_buffer_) {
197 delete sample_buffer_;
198 sample_buffer_ = NULL;
199 own_sample_buffer_ = false;
200 }
201 }
202
203
204 void IsolateProfilerData::Block() {
205 block_count_++;
206 }
207
208
209 void IsolateProfilerData::Unblock() {
210 block_count_--;
211 if (block_count_ < 0) {
212 FATAL("Too many calls to Dart_IsolateUnblocked.");
213 }
214 if (!blocked()) {
215 // We just unblocked this isolate, wake up the thread interrupter.
216 ThreadInterrupter::WakeUp();
217 }
218 }
219
220
221 intptr_t Sample::pcs_length_ = 0; 138 intptr_t Sample::pcs_length_ = 0;
222 intptr_t Sample::instance_size_ = 0; 139 intptr_t Sample::instance_size_ = 0;
223 140
224 141
225 void Sample::InitOnce() { 142 void Sample::InitOnce() {
226 pcs_length_ = kSampleSize; 143 pcs_length_ = kSampleSize;
227 instance_size_ = 144 instance_size_ =
228 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT. 145 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT.
229 } 146 }
230 147
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 727
811 if (in_dart_code) { 728 if (in_dart_code) {
812 // We can only trust the stack pointer if we are executing Dart code. 729 // We can only trust the stack pointer if we are executing Dart code.
813 // See http://dartbug.com/20421 for details. 730 // See http://dartbug.com/20421 for details.
814 CopyStackBuffer(sample, sp); 731 CopyStackBuffer(sample, sp);
815 } 732 }
816 733
817 if (FLAG_profile_vm) { 734 if (FLAG_profile_vm) {
818 // Always walk the native stack collecting both native and Dart frames. 735 // Always walk the native stack collecting both native and Dart frames.
819 native_stack_walker->walk(); 736 native_stack_walker->walk();
820 } else if (exited_dart_code) { 737 } else if (StubCode::HasBeenInitialized() && exited_dart_code) {
821 // We have a valid exit frame info, use the Dart stack walker. 738 // We have a valid exit frame info, use the Dart stack walker.
822 dart_exit_stack_walker->walk(); 739 dart_exit_stack_walker->walk();
823 } else if (in_dart_code) { 740 } else if (StubCode::HasBeenInitialized() && in_dart_code) {
824 // We are executing Dart code. We have frame pointers. 741 // We are executing Dart code. We have frame pointers.
825 dart_stack_walker->walk(); 742 dart_stack_walker->walk();
826 } else { 743 } else {
827 sample->set_vm_tag(VMTag::kEmbedderTagId); 744 sample->set_vm_tag(VMTag::kEmbedderTagId);
828 sample->SetAt(0, pc); 745 sample->SetAt(0, pc);
829 } 746 }
830 747
831 #if defined(TARGET_OS_WINDOWS) 748 #if defined(TARGET_OS_WINDOWS)
832 // Use structured exception handling to trap guard page access. 749 // Use structured exception handling to trap guard page access.
833 } __except(GuardPageExceptionFilter(GetExceptionInformation())) { 750 } __except(GuardPageExceptionFilter(GetExceptionInformation())) {
(...skipping 10 matching lines...) Expand all
844 new_protect, 761 new_protect,
845 &old_protect); 762 &old_protect);
846 USE(success); 763 USE(success);
847 ASSERT(success); 764 ASSERT(success);
848 ASSERT(old_protect == PAGE_READWRITE); 765 ASSERT(old_protect == PAGE_READWRITE);
849 } 766 }
850 #endif 767 #endif
851 } 768 }
852 769
853 770
854 // Is |thread| executing Dart code?
855 static bool ExecutingDart(Thread* thread) {
856 ASSERT(thread != NULL);
857 return (thread->top_exit_frame_info() == 0) &&
858 (thread->vm_tag() == VMTag::kDartTagId);
859 }
860
861
862 // Has |thread| exited Dart code?
863 static bool ExitedDart(Thread* thread) {
864 return (thread->top_exit_frame_info() != 0) &&
865 (thread->vm_tag() != VMTag::kDartTagId);
866 }
867
868
869 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within 771 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within
870 // it. Return |false| if anything looks suspicious. 772 // it. Return |false| if anything looks suspicious.
871 static bool GetAndValidateIsolateStackBounds(Thread* thread, 773 static bool GetAndValidateIsolateStackBounds(Thread* thread,
774 uintptr_t fp,
872 uintptr_t sp, 775 uintptr_t sp,
873 uintptr_t fp,
874 uword* stack_lower, 776 uword* stack_lower,
875 uword* stack_upper) { 777 uword* stack_upper) {
876 ASSERT(thread != NULL); 778 ASSERT(thread != NULL);
877 Isolate* isolate = thread->isolate(); 779 Isolate* isolate = thread->isolate();
878 ASSERT(isolate != NULL); 780 ASSERT(isolate != NULL);
879 ASSERT(stack_lower != NULL); 781 ASSERT(stack_lower != NULL);
880 ASSERT(stack_upper != NULL); 782 ASSERT(stack_upper != NULL);
881 #if defined(USING_SIMULATOR) 783 #if defined(USING_SIMULATOR)
882 const bool in_dart_code = ExecutingDart(thread); 784 const bool in_dart_code = thread->IsExecutingDartCode();
883 if (in_dart_code) { 785 if (in_dart_code) {
884 Simulator* simulator = isolate->simulator(); 786 Simulator* simulator = isolate->simulator();
885 *stack_lower = simulator->StackBase(); 787 *stack_lower = simulator->StackBase();
886 *stack_upper = simulator->StackTop(); 788 *stack_upper = simulator->StackTop();
887 } else if (!isolate->GetProfilerStackBounds(stack_lower, stack_upper)) { 789 } else if (!isolate->GetProfilerStackBounds(stack_lower, stack_upper)) {
888 // Could not get stack boundary. 790 // Could not get stack boundary.
889 return false; 791 return false;
890 } 792 }
891 if ((*stack_lower == 0) || (*stack_upper == 0)) { 793 if ((*stack_lower == 0) || (*stack_upper == 0)) {
892 return false; 794 return false;
(...skipping 22 matching lines...) Expand all
915 817
916 if ((fp < *stack_lower) || (fp >= *stack_upper)) { 818 if ((fp < *stack_lower) || (fp >= *stack_upper)) {
917 // Frame pointer is outside isolate stack boundary. 819 // Frame pointer is outside isolate stack boundary.
918 return false; 820 return false;
919 } 821 }
920 822
921 return true; 823 return true;
922 } 824 }
923 825
924 826
925 // Some simple sanity checking of |pc|, |sp|, and |fp|. 827 // Some simple sanity checking of |pc|, |fp|, and |sp|.
926 static bool InitialRegisterCheck(uintptr_t pc, uintptr_t sp, uintptr_t fp) { 828 static bool InitialRegisterCheck(uintptr_t pc, uintptr_t fp, uintptr_t sp) {
927 if ((sp == 0) || (fp == 0) || (pc == 0)) { 829 if ((sp == 0) || (fp == 0) || (pc == 0)) {
928 // None of these registers should be zero. 830 // None of these registers should be zero.
929 return false; 831 return false;
930 } 832 }
931 833
932 if (sp > fp) { 834 if (sp > fp) {
933 // Assuming the stack grows down, we should never have a stack pointer above 835 // Assuming the stack grows down, we should never have a stack pointer above
934 // the frame pointer. 836 // the frame pointer.
935 return false; 837 return false;
936 } 838 }
937 839
938 return true; 840 return true;
939 } 841 }
940 842
941 843
942 // Return |isolate|'s sample buffer.
943 static SampleBuffer* GetSampleBuffer(Isolate* isolate) {
944 IsolateProfilerData* profiler_data = isolate->profiler_data();
945 if (profiler_data == NULL) {
946 // Profiler not initialized.
947 return NULL;
948 }
949 SampleBuffer* sample_buffer = profiler_data->sample_buffer();
950 return sample_buffer;
951 }
952
953
954 static Sample* SetupSample(Thread* thread, 844 static Sample* SetupSample(Thread* thread,
955 SampleBuffer* sample_buffer, 845 SampleBuffer* sample_buffer,
956 ThreadId tid) { 846 ThreadId tid) {
957 ASSERT(thread != NULL); 847 ASSERT(thread != NULL);
958 Isolate* isolate = thread->isolate(); 848 Isolate* isolate = thread->isolate();
959 ASSERT(sample_buffer != NULL); 849 ASSERT(sample_buffer != NULL);
960 Sample* sample = sample_buffer->ReserveSample(); 850 Sample* sample = sample_buffer->ReserveSample();
961 sample->Init(isolate, OS::GetCurrentTimeMicros(), tid); 851 sample->Init(isolate, OS::GetCurrentTimeMicros(), tid);
962 uword vm_tag = thread->vm_tag(); 852 uword vm_tag = thread->vm_tag();
963 #if defined(USING_SIMULATOR) 853 #if defined(USING_SIMULATOR)
964 // When running in the simulator, the runtime entry function address 854 // When running in the simulator, the runtime entry function address
965 // (stored as the vm tag) is the address of a redirect function. 855 // (stored as the vm tag) is the address of a redirect function.
966 // Attempt to find the real runtime entry function address and use that. 856 // Attempt to find the real runtime entry function address and use that.
967 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag); 857 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag);
968 if (redirect_vm_tag != 0) { 858 if (redirect_vm_tag != 0) {
969 vm_tag = redirect_vm_tag; 859 vm_tag = redirect_vm_tag;
970 } 860 }
971 #endif 861 #endif
972 sample->set_vm_tag(vm_tag); 862 sample->set_vm_tag(vm_tag);
973 sample->set_user_tag(isolate->user_tag()); 863 sample->set_user_tag(isolate->user_tag());
974 return sample; 864 return sample;
975 } 865 }
976 866
977 867
978 static bool CheckIsolate(Isolate* isolate) { 868 static bool CheckIsolate(Isolate* isolate) {
979 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { 869 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) {
980 // No isolate. 870 // No isolate.
981 return false; 871 return false;
982 } 872 }
983 ASSERT(isolate != Dart::vm_isolate()); 873 return isolate != Dart::vm_isolate();
984 return true;
985 } 874 }
986 875
987 876
988 #if defined(TARGET_OS_WINDOWS) 877 #if defined(TARGET_OS_WINDOWS)
989 __declspec(noinline) 878 __declspec(noinline)
990 static uintptr_t GetProgramCounter() { 879 static uintptr_t GetProgramCounter() {
991 return reinterpret_cast<uintptr_t>(_ReturnAddress()); 880 return reinterpret_cast<uintptr_t>(_ReturnAddress());
992 } 881 }
993 #else 882 #else
994 static uintptr_t __attribute__((noinline)) GetProgramCounter() { 883 static uintptr_t __attribute__((noinline)) GetProgramCounter() {
995 return reinterpret_cast<uintptr_t>( 884 return reinterpret_cast<uintptr_t>(
996 __builtin_extract_return_addr(__builtin_return_address(0))); 885 __builtin_extract_return_addr(__builtin_return_address(0)));
997 } 886 }
998 #endif 887 #endif
999 888
1000 void Profiler::RecordAllocation(Thread* thread, intptr_t cid) { 889 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) {
1001 ASSERT(thread != NULL); 890 ASSERT(thread != NULL);
1002 Isolate* isolate = thread->isolate(); 891 Isolate* isolate = thread->isolate();
1003 if (!CheckIsolate(isolate)) { 892 if (!CheckIsolate(isolate)) {
1004 return; 893 return;
1005 } 894 }
1006 895
1007 const bool exited_dart_code = ExitedDart(thread); 896 const bool exited_dart_code = thread->HasExitedDartCode();
Ivan Posva 2015/10/28 08:27:47 Shouldn't this be an assert? The thread has better
Cutch 2015/10/28 14:39:19 This is called from Object::Allocate which means w
1008 897
1009 SampleBuffer* sample_buffer = GetSampleBuffer(isolate); 898 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1010 if (sample_buffer == NULL) { 899 if (sample_buffer == NULL) {
1011 // Profiler not initialized. 900 // Profiler not initialized.
1012 return; 901 return;
1013 } 902 }
1014 903
1015 if (FLAG_profile_vm) { 904 if (FLAG_profile_vm) {
1016 uintptr_t sp = Isolate::GetCurrentStackPointer(); 905 uintptr_t sp = Isolate::GetCurrentStackPointer();
1017 uintptr_t fp = 0; 906 uintptr_t fp = 0;
1018 uintptr_t pc = GetProgramCounter(); 907 uintptr_t pc = GetProgramCounter();
1019 908
1020 COPY_FP_REGISTER(fp); 909 COPY_FP_REGISTER(fp);
1021 910
1022 uword stack_lower = 0; 911 uword stack_lower = 0;
1023 uword stack_upper = 0; 912 uword stack_upper = 0;
1024 913
1025 if (!InitialRegisterCheck(pc, sp, fp)) { 914 if (!InitialRegisterCheck(pc, fp, sp)) {
1026 return; 915 return;
1027 } 916 }
1028 917
1029 if (!GetAndValidateIsolateStackBounds(thread, 918 if (!GetAndValidateIsolateStackBounds(thread,
919 fp,
1030 sp, 920 sp,
1031 fp,
1032 &stack_lower, 921 &stack_lower,
1033 &stack_upper)) { 922 &stack_upper)) {
1034 // Could not get stack boundary. 923 // Could not get stack boundary.
1035 return; 924 return;
1036 } 925 }
1037 926
1038 Sample* sample = SetupSample(thread, 927 Sample* sample = SetupSample(thread,
1039 sample_buffer, 928 sample_buffer,
1040 OSThread::GetCurrentThreadId()); 929 OSThread::GetCurrentThreadId());
1041 sample->SetAllocationCid(cid); 930 sample->SetAllocationCid(cid);
(...skipping 22 matching lines...) Expand all
1064 Sample* sample = SetupSample(thread, 953 Sample* sample = SetupSample(thread,
1065 sample_buffer, 954 sample_buffer,
1066 OSThread::GetCurrentThreadId()); 955 OSThread::GetCurrentThreadId());
1067 sample->SetAllocationCid(cid); 956 sample->SetAllocationCid(cid);
1068 sample->set_vm_tag(VMTag::kEmbedderTagId); 957 sample->set_vm_tag(VMTag::kEmbedderTagId);
1069 sample->SetAt(0, pc); 958 sample->SetAt(0, pc);
1070 } 959 }
1071 } 960 }
1072 961
1073 962
1074 void Profiler::RecordSampleInterruptCallback( 963 void Profiler::SampleThread(Thread* thread,
1075 const InterruptedThreadState& state, 964 uintptr_t pc,
1076 void* data) { 965 uintptr_t fp,
1077 Thread* thread = reinterpret_cast<Thread*>(data); 966 uintptr_t sp) {
967 ASSERT(thread != NULL);
1078 Isolate* isolate = thread->isolate(); 968 Isolate* isolate = thread->isolate();
1079 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { 969 if (!CheckIsolate(isolate)) {
1080 // No isolate.
1081 return;
1082 }
1083 ASSERT(isolate != Dart::vm_isolate());
1084
1085 SampleBuffer* sample_buffer = GetSampleBuffer(isolate);
1086 if (sample_buffer == NULL) {
1087 // Profiler not initialized.
1088 return; 970 return;
1089 } 971 }
1090 972
1091 const bool exited_dart_code = ExitedDart(thread); 973 if (!thread->IsMutatorThread()) {
1092 const bool in_dart_code = ExecutingDart(thread); 974 // Not a mutator thread.
1093 975 // TODO(johnmccutchan): Profile all threads with an isolate.
1094 uintptr_t sp = 0;
1095 uintptr_t fp = state.fp;
1096 uintptr_t pc = state.pc;
1097 #if defined(USING_SIMULATOR)
1098 Simulator* simulator = NULL;
1099 #endif
1100
1101 if (in_dart_code) {
1102 // If we're in Dart code, use the Dart stack pointer.
1103 #if defined(USING_SIMULATOR)
1104 simulator = isolate->simulator();
1105 sp = simulator->get_register(SPREG);
1106 fp = simulator->get_register(FPREG);
1107 pc = simulator->get_pc();
1108 #else
1109 sp = state.dsp;
1110 #endif
1111 } else {
1112 // If we're in runtime code, use the C stack pointer.
1113 sp = state.csp;
1114 }
1115
1116 if (!InitialRegisterCheck(pc, sp, fp)) {
1117 return; 976 return;
1118 } 977 }
1119 978
1120 if (StubCode::InJumpToExceptionHandlerStub(pc)) { 979 if (isolate->HasDebugger()) {
Ivan Posva 2015/10/28 08:27:47 Please add a comment that this is really only rele
Cutch 2015/10/28 14:39:18 Done.
1121 // The JumpToExceptionHandler stub manually adjusts the stack pointer, 980 Debugger* debugger = isolate->debugger();
1122 // frame pointer, and some isolate state before jumping to a catch entry. 981 if (debugger->IsPaused()) {
1123 // It is not safe to walk the stack when executing this stub. 982 // Mutator is paused at breakpoint.
983 return;
984 }
985 }
986
987 MessageHandler* msg_handler = isolate->message_handler();
Ivan Posva 2015/10/28 08:27:47 This and the debugger check are only relevant for
Cutch 2015/10/28 14:39:18 I've factored both of these checks into a helper f
988 if ((msg_handler != NULL) &&
989 (msg_handler->paused_on_start() ||
990 msg_handler->paused_on_exit())) {
991 // Isolate is paused at start / exit.
1124 return; 992 return;
1125 } 993 }
1126 994
995 const bool exited_dart_code = thread->HasExitedDartCode();
Ivan Posva 2015/10/28 08:27:47 Is there any particular reason why this should be
Cutch 2015/10/28 14:39:19 No. Moved down closer to their use.
996 const bool in_dart_code = thread->IsExecutingDartCode();
997
1127 uword stack_lower = 0; 998 uword stack_lower = 0;
1128 uword stack_upper = 0; 999 uword stack_upper = 0;
1129 if (!GetAndValidateIsolateStackBounds(thread, 1000 if (!GetAndValidateIsolateStackBounds(thread,
1001 fp,
1130 sp, 1002 sp,
1131 fp,
1132 &stack_lower, 1003 &stack_lower,
1133 &stack_upper)) { 1004 &stack_upper)) {
1134 // Could not get stack boundary. 1005 // Could not get stack boundary.
1135 return; 1006 return;
1136 } 1007 }
1137 1008
1138 // At this point we have a valid stack boundary for this isolate and 1009 // At this point we have a valid stack boundary for this isolate and
1139 // know that our initial stack and frame pointers are within the boundary. 1010 // know that our initial stack and frame pointers are within the boundary.
1011 SampleBuffer* sample_buffer = Profiler::sample_buffer();
1012 if (sample_buffer == NULL) {
1013 // Profiler not initialized.
1014 return;
1015 }
1140 1016
1141 // Setup sample. 1017 // Setup sample.
1142 Sample* sample = SetupSample(thread, 1018 Sample* sample = SetupSample(thread,
1143 sample_buffer, 1019 sample_buffer,
1144 OSThread::GetCurrentThreadId()); 1020 OSThread::GetCurrentThreadId());
1145 // Increment counter for vm tag. 1021 // Increment counter for vm tag.
1146 VMTagCounters* counters = isolate->vm_tag_counters(); 1022 VMTagCounters* counters = isolate->vm_tag_counters();
1147 ASSERT(counters != NULL); 1023 ASSERT(counters != NULL);
1148 counters->Increment(sample->vm_tag()); 1024 counters->Increment(sample->vm_tag());
1149 1025
(...skipping 27 matching lines...) Expand all
1177 sample, 1053 sample,
1178 &native_stack_walker, 1054 &native_stack_walker,
1179 &dart_exit_stack_walker, 1055 &dart_exit_stack_walker,
1180 &dart_stack_walker, 1056 &dart_stack_walker,
1181 pc, 1057 pc,
1182 fp, 1058 fp,
1183 sp); 1059 sp);
1184 } 1060 }
1185 1061
1186 1062
1063 void Profiler::SampleThreadInterruptCallback(
1064 Thread* thread,
1065 const InterruptedThreadState& state) {
1066 const bool in_dart_code = thread->IsExecutingDartCode();
1067
1068 uintptr_t sp = 0;
1069 uintptr_t fp = state.fp;
1070 uintptr_t pc = state.pc;
1071 #if defined(USING_SIMULATOR)
1072 Simulator* simulator = NULL;
1073 #endif
1074
1075 if (StubCode::HasBeenInitialized() &&
1076 StubCode::InJumpToExceptionHandlerStub(pc)) {
1077 // The JumpToExceptionHandler stub manually adjusts the stack pointer,
1078 // frame pointer, and some isolate state before jumping to a catch entry.
1079 // It is not safe to walk the stack when executing this stub.
1080 return;
1081 }
1082
1083 if (in_dart_code) {
1084 // If we're in Dart code, use the Dart stack pointer.
1085 #if defined(USING_SIMULATOR)
1086 simulator = isolate->simulator();
1087 sp = simulator->get_register(SPREG);
1088 fp = simulator->get_register(FPREG);
1089 pc = simulator->get_pc();
1090 #else
1091 sp = state.dsp;
1092 #endif
1093 } else {
1094 // If we're in runtime code, use the C stack pointer.
1095 sp = state.csp;
1096 }
1097
1098 if (!InitialRegisterCheck(pc, fp, sp)) {
1099 return;
1100 }
1101
1102 SampleThread(thread, pc, fp, sp);
1103 }
1104
1105
1187 ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer( 1106 ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer(
1188 SampleFilter* filter) { 1107 SampleFilter* filter) {
1189 ASSERT(filter != NULL); 1108 ASSERT(filter != NULL);
1190 Thread* thread = Thread::Current(); 1109 Thread* thread = Thread::Current();
1191 Zone* zone = thread->zone(); 1110 Zone* zone = thread->zone();
1192 1111
1193 ProcessedSampleBuffer* buffer = new(zone) ProcessedSampleBuffer(); 1112 ProcessedSampleBuffer* buffer = new(zone) ProcessedSampleBuffer();
1194 1113
1195 const intptr_t length = capacity(); 1114 const intptr_t length = capacity();
1196 for (intptr_t i = 0; i < length; i++) { 1115 for (intptr_t i = 0; i < length; i++) {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 uword pc) { 1313 uword pc) {
1395 return vm_isolate->heap()->CodeContains(pc) 1314 return vm_isolate->heap()->CodeContains(pc)
1396 || isolate->heap()->CodeContains(pc); 1315 || isolate->heap()->CodeContains(pc);
1397 } 1316 }
1398 1317
1399 1318
1400 ProcessedSampleBuffer::ProcessedSampleBuffer() { 1319 ProcessedSampleBuffer::ProcessedSampleBuffer() {
1401 } 1320 }
1402 1321
1403 } // namespace dart 1322 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698