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" |
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 Loading... | |
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) { |
Ivan Posva
2015/10/28 06:45:16
Is this API even needed given that we are profilin
| |
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(); | |
164 if (profiler_data == NULL) { | |
165 return; | |
166 } | |
167 Thread* thread = Thread::Current(); | 117 Thread* thread = Thread::Current(); |
168 thread->SetThreadInterrupter(RecordSampleInterruptCallback, thread); | 118 thread->SetThreadInterrupter(RecordSampleInterruptCallback, thread); |
169 ThreadInterrupter::WakeUp(); | |
170 } | 119 } |
171 | 120 |
172 | 121 |
173 void Profiler::EndExecution(Isolate* isolate) { | 122 void Profiler::EndExecution(Isolate* isolate) { |
Ivan Posva
2015/10/28 06:45:16
ditto.
| |
174 if (isolate == NULL) { | 123 if (isolate == NULL) { |
175 return; | 124 return; |
176 } | 125 } |
177 if (!FLAG_profile) { | 126 if (!FLAG_profile) { |
178 return; | 127 return; |
179 } | 128 } |
180 ASSERT(initialized_); | 129 ASSERT(initialized_); |
181 Thread* thread = Thread::Current(); | 130 Thread* thread = Thread::Current(); |
182 thread->SetThreadInterrupter(NULL, NULL); | 131 thread->SetThreadInterrupter(NULL, NULL); |
183 } | 132 } |
184 | 133 |
185 | 134 |
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; | 135 intptr_t Sample::pcs_length_ = 0; |
222 intptr_t Sample::instance_size_ = 0; | 136 intptr_t Sample::instance_size_ = 0; |
223 | 137 |
224 | 138 |
225 void Sample::InitOnce() { | 139 void Sample::InitOnce() { |
226 pcs_length_ = kSampleSize; | 140 pcs_length_ = kSampleSize; |
227 instance_size_ = | 141 instance_size_ = |
228 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT. | 142 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT. |
229 } | 143 } |
230 | 144 |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 // Has |thread| exited Dart code? | 775 // Has |thread| exited Dart code? |
862 static bool ExitedDart(Thread* thread) { | 776 static bool ExitedDart(Thread* thread) { |
863 return (thread->top_exit_frame_info() != 0) && | 777 return (thread->top_exit_frame_info() != 0) && |
864 (thread->vm_tag() != VMTag::kDartTagId); | 778 (thread->vm_tag() != VMTag::kDartTagId); |
865 } | 779 } |
866 | 780 |
867 | 781 |
868 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within | 782 // Get |isolate|'s stack boundary and verify that |sp| and |fp| are within |
869 // it. Return |false| if anything looks suspicious. | 783 // it. Return |false| if anything looks suspicious. |
870 static bool GetAndValidateIsolateStackBounds(Thread* thread, | 784 static bool GetAndValidateIsolateStackBounds(Thread* thread, |
785 uintptr_t fp, | |
871 uintptr_t sp, | 786 uintptr_t sp, |
872 uintptr_t fp, | |
873 uword* stack_lower, | 787 uword* stack_lower, |
874 uword* stack_upper) { | 788 uword* stack_upper) { |
875 ASSERT(thread != NULL); | 789 ASSERT(thread != NULL); |
876 Isolate* isolate = thread->isolate(); | 790 Isolate* isolate = thread->isolate(); |
877 ASSERT(isolate != NULL); | 791 ASSERT(isolate != NULL); |
878 ASSERT(stack_lower != NULL); | 792 ASSERT(stack_lower != NULL); |
879 ASSERT(stack_upper != NULL); | 793 ASSERT(stack_upper != NULL); |
880 #if defined(USING_SIMULATOR) | 794 #if defined(USING_SIMULATOR) |
881 const bool in_dart_code = ExecutingDart(thread); | 795 const bool in_dart_code = ExecutingDart(thread); |
882 if (in_dart_code) { | 796 if (in_dart_code) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
914 | 828 |
915 if ((fp < *stack_lower) || (fp >= *stack_upper)) { | 829 if ((fp < *stack_lower) || (fp >= *stack_upper)) { |
916 // Frame pointer is outside isolate stack boundary. | 830 // Frame pointer is outside isolate stack boundary. |
917 return false; | 831 return false; |
918 } | 832 } |
919 | 833 |
920 return true; | 834 return true; |
921 } | 835 } |
922 | 836 |
923 | 837 |
924 // Some simple sanity checking of |pc|, |sp|, and |fp|. | 838 // Some simple sanity checking of |pc|, |fp|, and |sp|. |
925 static bool InitialRegisterCheck(uintptr_t pc, uintptr_t sp, uintptr_t fp) { | 839 static bool InitialRegisterCheck(uintptr_t pc, uintptr_t fp, uintptr_t sp) { |
926 if ((sp == 0) || (fp == 0) || (pc == 0)) { | 840 if ((sp == 0) || (fp == 0) || (pc == 0)) { |
927 // None of these registers should be zero. | 841 // None of these registers should be zero. |
928 return false; | 842 return false; |
929 } | 843 } |
930 | 844 |
931 if (sp > fp) { | 845 if (sp > fp) { |
932 // Assuming the stack grows down, we should never have a stack pointer above | 846 // Assuming the stack grows down, we should never have a stack pointer above |
933 // the frame pointer. | 847 // the frame pointer. |
934 return false; | 848 return false; |
935 } | 849 } |
936 | 850 |
937 return true; | 851 return true; |
938 } | 852 } |
939 | 853 |
940 | 854 |
941 // Return |isolate|'s sample buffer. | |
942 static SampleBuffer* GetSampleBuffer(Isolate* isolate) { | |
943 IsolateProfilerData* profiler_data = isolate->profiler_data(); | |
944 if (profiler_data == NULL) { | |
945 // Profiler not initialized. | |
946 return NULL; | |
947 } | |
948 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); | |
949 return sample_buffer; | |
950 } | |
951 | |
952 | |
953 static Sample* SetupSample(Thread* thread, | 855 static Sample* SetupSample(Thread* thread, |
954 SampleBuffer* sample_buffer, | 856 SampleBuffer* sample_buffer, |
955 ThreadId tid) { | 857 ThreadId tid) { |
956 ASSERT(thread != NULL); | 858 ASSERT(thread != NULL); |
957 Isolate* isolate = thread->isolate(); | 859 Isolate* isolate = thread->isolate(); |
958 ASSERT(sample_buffer != NULL); | 860 ASSERT(sample_buffer != NULL); |
959 Sample* sample = sample_buffer->ReserveSample(); | 861 Sample* sample = sample_buffer->ReserveSample(); |
960 sample->Init(isolate, OS::GetCurrentTimeMicros(), tid); | 862 sample->Init(isolate, OS::GetCurrentTimeMicros(), tid); |
961 uword vm_tag = thread->vm_tag(); | 863 uword vm_tag = thread->vm_tag(); |
962 #if defined(USING_SIMULATOR) | 864 #if defined(USING_SIMULATOR) |
963 // When running in the simulator, the runtime entry function address | 865 // When running in the simulator, the runtime entry function address |
964 // (stored as the vm tag) is the address of a redirect function. | 866 // (stored as the vm tag) is the address of a redirect function. |
965 // Attempt to find the real runtime entry function address and use that. | 867 // Attempt to find the real runtime entry function address and use that. |
966 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag); | 868 uword redirect_vm_tag = Simulator::FunctionForRedirect(vm_tag); |
967 if (redirect_vm_tag != 0) { | 869 if (redirect_vm_tag != 0) { |
968 vm_tag = redirect_vm_tag; | 870 vm_tag = redirect_vm_tag; |
969 } | 871 } |
970 #endif | 872 #endif |
971 sample->set_vm_tag(vm_tag); | 873 sample->set_vm_tag(vm_tag); |
972 sample->set_user_tag(isolate->user_tag()); | 874 sample->set_user_tag(isolate->user_tag()); |
973 return sample; | 875 return sample; |
974 } | 876 } |
975 | 877 |
976 | 878 |
977 static bool CheckIsolate(Isolate* isolate) { | 879 static bool CheckIsolate(Isolate* isolate) { |
978 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { | 880 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { |
979 // No isolate. | 881 // No isolate. |
980 return false; | 882 return false; |
981 } | 883 } |
982 ASSERT(isolate != Dart::vm_isolate()); | 884 return isolate != Dart::vm_isolate(); |
983 return true; | |
984 } | 885 } |
985 | 886 |
986 | 887 |
987 #if defined(TARGET_OS_WINDOWS) | 888 #if defined(TARGET_OS_WINDOWS) |
988 __declspec(noinline) | 889 __declspec(noinline) |
989 static uintptr_t GetProgramCounter() { | 890 static uintptr_t GetProgramCounter() { |
990 return reinterpret_cast<uintptr_t>(_ReturnAddress()); | 891 return reinterpret_cast<uintptr_t>(_ReturnAddress()); |
991 } | 892 } |
992 #else | 893 #else |
993 static uintptr_t __attribute__((noinline)) GetProgramCounter() { | 894 static uintptr_t __attribute__((noinline)) GetProgramCounter() { |
994 return reinterpret_cast<uintptr_t>( | 895 return reinterpret_cast<uintptr_t>( |
995 __builtin_extract_return_addr(__builtin_return_address(0))); | 896 __builtin_extract_return_addr(__builtin_return_address(0))); |
996 } | 897 } |
997 #endif | 898 #endif |
998 | 899 |
999 void Profiler::RecordAllocation(Thread* thread, intptr_t cid) { | 900 void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
1000 ASSERT(thread != NULL); | 901 ASSERT(thread != NULL); |
1001 Isolate* isolate = thread->isolate(); | 902 Isolate* isolate = thread->isolate(); |
1002 if (!CheckIsolate(isolate)) { | 903 if (!CheckIsolate(isolate)) { |
1003 return; | 904 return; |
1004 } | 905 } |
1005 | 906 |
1006 const bool exited_dart_code = ExitedDart(thread); | 907 const bool exited_dart_code = ExitedDart(thread); |
1007 | 908 |
1008 SampleBuffer* sample_buffer = GetSampleBuffer(isolate); | 909 SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
1009 if (sample_buffer == NULL) { | 910 if (sample_buffer == NULL) { |
1010 // Profiler not initialized. | 911 // Profiler not initialized. |
1011 return; | 912 return; |
1012 } | 913 } |
1013 | 914 |
1014 if (FLAG_profile_vm) { | 915 if (FLAG_profile_vm) { |
1015 uintptr_t sp = Isolate::GetCurrentStackPointer(); | 916 uintptr_t sp = Isolate::GetCurrentStackPointer(); |
1016 uintptr_t fp = 0; | 917 uintptr_t fp = 0; |
1017 uintptr_t pc = GetProgramCounter(); | 918 uintptr_t pc = GetProgramCounter(); |
1018 | 919 |
1019 COPY_FP_REGISTER(fp); | 920 COPY_FP_REGISTER(fp); |
1020 | 921 |
1021 uword stack_lower = 0; | 922 uword stack_lower = 0; |
1022 uword stack_upper = 0; | 923 uword stack_upper = 0; |
1023 | 924 |
1024 if (!InitialRegisterCheck(pc, sp, fp)) { | 925 if (!InitialRegisterCheck(pc, fp, sp)) { |
1025 return; | 926 return; |
1026 } | 927 } |
1027 | 928 |
1028 if (!GetAndValidateIsolateStackBounds(thread, | 929 if (!GetAndValidateIsolateStackBounds(thread, |
930 fp, | |
1029 sp, | 931 sp, |
1030 fp, | |
1031 &stack_lower, | 932 &stack_lower, |
1032 &stack_upper)) { | 933 &stack_upper)) { |
1033 // Could not get stack boundary. | 934 // Could not get stack boundary. |
1034 return; | 935 return; |
1035 } | 936 } |
1036 | 937 |
1037 Sample* sample = SetupSample(thread, | 938 Sample* sample = SetupSample(thread, |
1038 sample_buffer, | 939 sample_buffer, |
1039 OSThread::GetCurrentThreadId()); | 940 OSThread::GetCurrentThreadId()); |
1040 sample->SetAllocationCid(cid); | 941 sample->SetAllocationCid(cid); |
(...skipping 21 matching lines...) Expand all Loading... | |
1062 Sample* sample = SetupSample(thread, | 963 Sample* sample = SetupSample(thread, |
1063 sample_buffer, | 964 sample_buffer, |
1064 OSThread::GetCurrentThreadId()); | 965 OSThread::GetCurrentThreadId()); |
1065 sample->SetAllocationCid(cid); | 966 sample->SetAllocationCid(cid); |
1066 sample->set_vm_tag(VMTag::kEmbedderTagId); | 967 sample->set_vm_tag(VMTag::kEmbedderTagId); |
1067 sample->SetAt(0, pc); | 968 sample->SetAt(0, pc); |
1068 } | 969 } |
1069 } | 970 } |
1070 | 971 |
1071 | 972 |
1072 void Profiler::RecordSampleInterruptCallback( | 973 void Profiler::SampleMutator(Thread* thread, |
Ivan Posva
2015/10/28 06:45:16
Not only mutator, right?
| |
1073 const InterruptedThreadState& state, | 974 uintptr_t pc, |
1074 void* data) { | 975 uintptr_t fp, |
1075 Thread* thread = reinterpret_cast<Thread*>(data); | 976 uintptr_t sp) { |
977 ASSERT(thread != NULL); | |
1076 Isolate* isolate = thread->isolate(); | 978 Isolate* isolate = thread->isolate(); |
1077 if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { | 979 if (!CheckIsolate(isolate)) { |
1078 // No isolate. | |
1079 return; | 980 return; |
1080 } | 981 } |
1081 ASSERT(isolate != Dart::vm_isolate()); | |
1082 | 982 |
1083 SampleBuffer* sample_buffer = GetSampleBuffer(isolate); | 983 if (!isolate->IsMutatorThread(thread)) { |
1084 if (sample_buffer == NULL) { | 984 // Not the mutator thread. |
1085 // Profiler not initialized. | 985 return; |
986 } | |
987 | |
988 if (isolate->HasDebugger()) { | |
989 Debugger* debugger = isolate->debugger(); | |
990 if (debugger->IsPaused()) { | |
991 // Mutator is paused at breakpoint. | |
992 return; | |
993 } | |
994 } | |
995 | |
996 MessageHandler* msg_handler = isolate->message_handler(); | |
997 if ((msg_handler != NULL) && | |
998 (msg_handler->paused_on_start() || | |
999 msg_handler->paused_on_exit())) { | |
1000 // Isolate is paused at start / exit. | |
1086 return; | 1001 return; |
1087 } | 1002 } |
1088 | 1003 |
1089 const bool exited_dart_code = ExitedDart(thread); | 1004 const bool exited_dart_code = ExitedDart(thread); |
1090 const bool in_dart_code = ExecutingDart(thread); | 1005 const bool in_dart_code = ExecutingDart(thread); |
1091 | 1006 |
1092 uintptr_t sp = 0; | |
1093 uintptr_t fp = state.fp; | |
1094 uintptr_t pc = state.pc; | |
1095 #if defined(USING_SIMULATOR) | |
1096 Simulator* simulator = NULL; | |
1097 #endif | |
1098 | |
1099 if (in_dart_code) { | |
1100 // If we're in Dart code, use the Dart stack pointer. | |
1101 #if defined(USING_SIMULATOR) | |
1102 simulator = isolate->simulator(); | |
1103 sp = simulator->get_register(SPREG); | |
1104 fp = simulator->get_register(FPREG); | |
1105 pc = simulator->get_pc(); | |
1106 #else | |
1107 sp = state.dsp; | |
1108 #endif | |
1109 } else { | |
1110 // If we're in runtime code, use the C stack pointer. | |
1111 sp = state.csp; | |
1112 } | |
1113 | |
1114 if (!InitialRegisterCheck(pc, sp, fp)) { | |
1115 return; | |
1116 } | |
1117 | |
1118 if (StubCode::InJumpToExceptionHandlerStub(pc)) { | |
1119 // The JumpToExceptionHandler stub manually adjusts the stack pointer, | |
1120 // frame pointer, and some isolate state before jumping to a catch entry. | |
1121 // It is not safe to walk the stack when executing this stub. | |
1122 return; | |
1123 } | |
1124 | |
1125 uword stack_lower = 0; | 1007 uword stack_lower = 0; |
1126 uword stack_upper = 0; | 1008 uword stack_upper = 0; |
1127 if (!GetAndValidateIsolateStackBounds(thread, | 1009 if (!GetAndValidateIsolateStackBounds(thread, |
1010 fp, | |
1128 sp, | 1011 sp, |
1129 fp, | |
1130 &stack_lower, | 1012 &stack_lower, |
1131 &stack_upper)) { | 1013 &stack_upper)) { |
1132 // Could not get stack boundary. | 1014 // Could not get stack boundary. |
1133 return; | 1015 return; |
1134 } | 1016 } |
1135 | 1017 |
1136 // At this point we have a valid stack boundary for this isolate and | 1018 // At this point we have a valid stack boundary for this isolate and |
1137 // know that our initial stack and frame pointers are within the boundary. | 1019 // know that our initial stack and frame pointers are within the boundary. |
1020 SampleBuffer* sample_buffer = Profiler::sample_buffer(); | |
1021 if (sample_buffer == NULL) { | |
1022 // Profiler not initialized. | |
1023 return; | |
1024 } | |
1138 | 1025 |
1139 // Setup sample. | 1026 // Setup sample. |
1140 Sample* sample = SetupSample(thread, | 1027 Sample* sample = SetupSample(thread, |
1141 sample_buffer, | 1028 sample_buffer, |
1142 OSThread::GetCurrentThreadId()); | 1029 OSThread::GetCurrentThreadId()); |
1143 // Increment counter for vm tag. | 1030 // Increment counter for vm tag. |
1144 VMTagCounters* counters = isolate->vm_tag_counters(); | 1031 VMTagCounters* counters = isolate->vm_tag_counters(); |
1145 ASSERT(counters != NULL); | 1032 ASSERT(counters != NULL); |
1146 counters->Increment(sample->vm_tag()); | 1033 counters->Increment(sample->vm_tag()); |
1147 | 1034 |
(...skipping 26 matching lines...) Expand all Loading... | |
1174 sample, | 1061 sample, |
1175 &native_stack_walker, | 1062 &native_stack_walker, |
1176 &dart_exit_stack_walker, | 1063 &dart_exit_stack_walker, |
1177 &dart_stack_walker, | 1064 &dart_stack_walker, |
1178 pc, | 1065 pc, |
1179 fp, | 1066 fp, |
1180 sp); | 1067 sp); |
1181 } | 1068 } |
1182 | 1069 |
1183 | 1070 |
1071 void Profiler::RecordSampleInterruptCallback( | |
1072 const InterruptedThreadState& state, | |
1073 void* data) { | |
1074 Thread* thread = reinterpret_cast<Thread*>(data); | |
siva
2015/10/26 23:45:26
ASSERT this is a valid thread in the thread list?
| |
1075 const bool in_dart_code = ExecutingDart(thread); | |
siva
2015/10/26 23:45:26
ExecutingDart should be in class Thread now?
thre
Cutch
2015/10/27 22:36:24
Done.
| |
1076 | |
1077 uintptr_t sp = 0; | |
1078 uintptr_t fp = state.fp; | |
1079 uintptr_t pc = state.pc; | |
1080 #if defined(USING_SIMULATOR) | |
1081 Simulator* simulator = NULL; | |
1082 #endif | |
1083 | |
1084 if (StubCode::InJumpToExceptionHandlerStub(pc)) { | |
1085 // The JumpToExceptionHandler stub manually adjusts the stack pointer, | |
1086 // frame pointer, and some isolate state before jumping to a catch entry. | |
1087 // It is not safe to walk the stack when executing this stub. | |
1088 return; | |
1089 } | |
1090 | |
1091 if (in_dart_code) { | |
1092 // If we're in Dart code, use the Dart stack pointer. | |
1093 #if defined(USING_SIMULATOR) | |
1094 simulator = isolate->simulator(); | |
1095 sp = simulator->get_register(SPREG); | |
1096 fp = simulator->get_register(FPREG); | |
1097 pc = simulator->get_pc(); | |
1098 #else | |
1099 sp = state.dsp; | |
1100 #endif | |
1101 } else { | |
1102 // If we're in runtime code, use the C stack pointer. | |
1103 sp = state.csp; | |
1104 } | |
1105 | |
1106 if (!InitialRegisterCheck(pc, fp, sp)) { | |
1107 return; | |
1108 } | |
1109 | |
1110 SampleMutator(thread, pc, fp, sp); | |
siva
2015/10/26 23:45:26
So we will not be profiling the background compila
Cutch
2015/10/27 22:36:24
This is intentional and temporary.
| |
1111 } | |
1112 | |
1113 | |
1184 ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer( | 1114 ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer( |
1185 SampleFilter* filter) { | 1115 SampleFilter* filter) { |
1186 ASSERT(filter != NULL); | 1116 ASSERT(filter != NULL); |
1187 Thread* thread = Thread::Current(); | 1117 Thread* thread = Thread::Current(); |
1188 Zone* zone = thread->zone(); | 1118 Zone* zone = thread->zone(); |
1189 | 1119 |
1190 ProcessedSampleBuffer* buffer = new(zone) ProcessedSampleBuffer(); | 1120 ProcessedSampleBuffer* buffer = new(zone) ProcessedSampleBuffer(); |
1191 | 1121 |
1192 const intptr_t length = capacity(); | 1122 const intptr_t length = capacity(); |
1193 for (intptr_t i = 0; i < length; i++) { | 1123 for (intptr_t i = 0; i < length; i++) { |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1391 uword pc) { | 1321 uword pc) { |
1392 return vm_isolate->heap()->CodeContains(pc) | 1322 return vm_isolate->heap()->CodeContains(pc) |
1393 || isolate->heap()->CodeContains(pc); | 1323 || isolate->heap()->CodeContains(pc); |
1394 } | 1324 } |
1395 | 1325 |
1396 | 1326 |
1397 ProcessedSampleBuffer::ProcessedSampleBuffer() { | 1327 ProcessedSampleBuffer::ProcessedSampleBuffer() { |
1398 } | 1328 } |
1399 | 1329 |
1400 } // namespace dart | 1330 } // namespace dart |
OLD | NEW |