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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 "Always collect native stack traces."); | 46 "Always collect native stack traces."); |
47 #else | 47 #else |
48 DEFINE_FLAG(bool, profile_vm, false, | 48 DEFINE_FLAG(bool, profile_vm, false, |
49 "Always collect native stack traces."); | 49 "Always collect native stack traces."); |
50 #endif | 50 #endif |
51 | 51 |
52 #ifndef PRODUCT | 52 #ifndef PRODUCT |
53 | 53 |
54 bool Profiler::initialized_ = false; | 54 bool Profiler::initialized_ = false; |
55 SampleBuffer* Profiler::sample_buffer_ = NULL; | 55 SampleBuffer* Profiler::sample_buffer_ = NULL; |
56 | 56 ProfilerCounters Profiler::counters_; |
57 | 57 |
58 void Profiler::InitOnce() { | 58 void Profiler::InitOnce() { |
59 // Place some sane restrictions on user controlled flags. | 59 // Place some sane restrictions on user controlled flags. |
60 SetSamplePeriod(FLAG_profile_period); | 60 SetSamplePeriod(FLAG_profile_period); |
61 SetSampleDepth(FLAG_max_profile_depth); | 61 SetSampleDepth(FLAG_max_profile_depth); |
62 Sample::InitOnce(); | 62 Sample::InitOnce(); |
63 if (!FLAG_profiler) { | 63 if (!FLAG_profiler) { |
64 return; | 64 return; |
65 } | 65 } |
66 ASSERT(!initialized_); | 66 ASSERT(!initialized_); |
67 sample_buffer_ = new SampleBuffer(); | 67 sample_buffer_ = new SampleBuffer(); |
68 NativeSymbolResolver::InitOnce(); | 68 NativeSymbolResolver::InitOnce(); |
69 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period); | 69 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period); |
70 ThreadInterrupter::Startup(); | 70 ThreadInterrupter::Startup(); |
| 71 // Zero counters. |
| 72 memset(&counters_, 0, sizeof(counters_)); |
71 initialized_ = true; | 73 initialized_ = true; |
72 } | 74 } |
73 | 75 |
74 | 76 |
75 void Profiler::Shutdown() { | 77 void Profiler::Shutdown() { |
76 if (!FLAG_profiler) { | 78 if (!FLAG_profiler) { |
77 return; | 79 return; |
78 } | 80 } |
79 ASSERT(initialized_); | 81 ASSERT(initialized_); |
80 ThreadInterrupter::Shutdown(); | 82 ThreadInterrupter::Shutdown(); |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 // All memory access done to collect the sample is performed in CollectSample. | 764 // All memory access done to collect the sample is performed in CollectSample. |
763 static void CollectSample(Isolate* isolate, | 765 static void CollectSample(Isolate* isolate, |
764 bool exited_dart_code, | 766 bool exited_dart_code, |
765 bool in_dart_code, | 767 bool in_dart_code, |
766 Sample* sample, | 768 Sample* sample, |
767 ProfilerNativeStackWalker* native_stack_walker, | 769 ProfilerNativeStackWalker* native_stack_walker, |
768 ProfilerDartExitStackWalker* dart_exit_stack_walker, | 770 ProfilerDartExitStackWalker* dart_exit_stack_walker, |
769 ProfilerDartStackWalker* dart_stack_walker, | 771 ProfilerDartStackWalker* dart_stack_walker, |
770 uword pc, | 772 uword pc, |
771 uword fp, | 773 uword fp, |
772 uword sp) { | 774 uword sp, |
| 775 ProfilerCounters* counters) { |
| 776 ASSERT(counters != NULL); |
773 #if defined(TARGET_OS_WINDOWS) | 777 #if defined(TARGET_OS_WINDOWS) |
774 // Use structured exception handling to trap guard page access on Windows. | 778 // Use structured exception handling to trap guard page access on Windows. |
775 __try { | 779 __try { |
776 #endif | 780 #endif |
777 | 781 |
778 if (in_dart_code) { | 782 if (in_dart_code) { |
779 // We can only trust the stack pointer if we are executing Dart code. | 783 // We can only trust the stack pointer if we are executing Dart code. |
780 // See http://dartbug.com/20421 for details. | 784 // See http://dartbug.com/20421 for details. |
781 CopyStackBuffer(sample, sp); | 785 CopyStackBuffer(sample, sp); |
782 } | 786 } |
783 | 787 |
784 if (FLAG_profile_vm) { | 788 if (FLAG_profile_vm) { |
785 // Always walk the native stack collecting both native and Dart frames. | 789 // Always walk the native stack collecting both native and Dart frames. |
| 790 counters->stack_walker_native++; |
786 native_stack_walker->walk(); | 791 native_stack_walker->walk(); |
787 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { | 792 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { |
| 793 counters->stack_walker_dart_exit++; |
788 // We have a valid exit frame info, use the Dart stack walker. | 794 // We have a valid exit frame info, use the Dart stack walker. |
789 dart_exit_stack_walker->walk(); | 795 dart_exit_stack_walker->walk(); |
790 } else if (StubCode::HasBeenInitialized() && in_dart_code) { | 796 } else if (StubCode::HasBeenInitialized() && in_dart_code) { |
| 797 counters->stack_walker_dart++; |
791 // We are executing Dart code. We have frame pointers. | 798 // We are executing Dart code. We have frame pointers. |
792 dart_stack_walker->walk(); | 799 dart_stack_walker->walk(); |
793 } else { | 800 } else { |
| 801 counters->stack_walker_none++; |
794 sample->SetAt(0, pc); | 802 sample->SetAt(0, pc); |
795 } | 803 } |
796 | 804 |
797 #if defined(TARGET_OS_WINDOWS) | 805 #if defined(TARGET_OS_WINDOWS) |
798 // Use structured exception handling to trap guard page access. | 806 // Use structured exception handling to trap guard page access. |
799 } __except(GuardPageExceptionFilter(GetExceptionInformation())) { | 807 } __except(GuardPageExceptionFilter(GetExceptionInformation())) { |
800 // Sample collection triggered a guard page fault: | 808 // Sample collection triggered a guard page fault: |
801 // 1) discard entire sample. | 809 // 1) discard entire sample. |
802 sample->set_ignore_sample(true); | 810 sample->set_ignore_sample(true); |
803 | 811 |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 return; | 1120 return; |
1113 #endif | 1121 #endif |
1114 | 1122 |
1115 ASSERT(thread != NULL); | 1123 ASSERT(thread != NULL); |
1116 OSThread* os_thread = thread->os_thread(); | 1124 OSThread* os_thread = thread->os_thread(); |
1117 ASSERT(os_thread != NULL); | 1125 ASSERT(os_thread != NULL); |
1118 Isolate* isolate = thread->isolate(); | 1126 Isolate* isolate = thread->isolate(); |
1119 | 1127 |
1120 // Thread is not doing VM work. | 1128 // Thread is not doing VM work. |
1121 if (thread->task_kind() == Thread::kUnknownTask) { | 1129 if (thread->task_kind() == Thread::kUnknownTask) { |
| 1130 counters_.bail_out_unknown_task++; |
1122 return; | 1131 return; |
1123 } | 1132 } |
1124 | 1133 |
1125 if (StubCode::HasBeenInitialized() && | 1134 if (StubCode::HasBeenInitialized() && |
1126 StubCode::InJumpToExceptionHandlerStub(state.pc)) { | 1135 StubCode::InJumpToExceptionHandlerStub(state.pc)) { |
1127 // The JumpToExceptionHandler stub manually adjusts the stack pointer, | 1136 // The JumpToExceptionHandler stub manually adjusts the stack pointer, |
1128 // frame pointer, and some isolate state before jumping to a catch entry. | 1137 // frame pointer, and some isolate state before jumping to a catch entry. |
1129 // It is not safe to walk the stack when executing this stub. | 1138 // It is not safe to walk the stack when executing this stub. |
| 1139 counters_.bail_out_jump_to_exception_handler++; |
1130 return; | 1140 return; |
1131 } | 1141 } |
1132 | 1142 |
1133 const bool in_dart_code = thread->IsExecutingDartCode(); | 1143 const bool in_dart_code = thread->IsExecutingDartCode(); |
1134 | 1144 |
1135 uintptr_t sp = 0; | 1145 uintptr_t sp = 0; |
1136 uintptr_t fp = state.fp; | 1146 uintptr_t fp = state.fp; |
1137 uintptr_t pc = state.pc; | 1147 uintptr_t pc = state.pc; |
1138 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) | 1148 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) |
1139 Simulator* simulator = NULL; | 1149 Simulator* simulator = NULL; |
(...skipping 10 matching lines...) Expand all Loading... |
1150 pc = simulator->get_pc(); | 1160 pc = simulator->get_pc(); |
1151 #else | 1161 #else |
1152 sp = state.dsp; | 1162 sp = state.dsp; |
1153 #endif | 1163 #endif |
1154 } else { | 1164 } else { |
1155 // If we're in runtime code, use the C stack pointer. | 1165 // If we're in runtime code, use the C stack pointer. |
1156 sp = state.csp; | 1166 sp = state.csp; |
1157 } | 1167 } |
1158 | 1168 |
1159 if (!CheckIsolate(isolate)) { | 1169 if (!CheckIsolate(isolate)) { |
| 1170 counters_.bail_out_check_isolate++; |
1160 return; | 1171 return; |
1161 } | 1172 } |
1162 | 1173 |
1163 if (thread->IsMutatorThread() && isolate->IsDeoptimizing()) { | 1174 if (thread->IsMutatorThread() && isolate->IsDeoptimizing()) { |
| 1175 counters_.single_frame_sample_deoptimizing++; |
1164 SampleThreadSingleFrame(thread, pc); | 1176 SampleThreadSingleFrame(thread, pc); |
1165 return; | 1177 return; |
1166 } | 1178 } |
1167 | 1179 |
1168 if (!InitialRegisterCheck(pc, fp, sp)) { | 1180 if (!InitialRegisterCheck(pc, fp, sp)) { |
| 1181 counters_.single_frame_sample_register_check++; |
1169 SampleThreadSingleFrame(thread, pc); | 1182 SampleThreadSingleFrame(thread, pc); |
1170 return; | 1183 return; |
1171 } | 1184 } |
1172 | 1185 |
1173 uword stack_lower = 0; | 1186 uword stack_lower = 0; |
1174 uword stack_upper = 0; | 1187 uword stack_upper = 0; |
1175 if (!GetAndValidateIsolateStackBounds(thread, | 1188 if (!GetAndValidateIsolateStackBounds(thread, |
1176 fp, | 1189 fp, |
1177 sp, | 1190 sp, |
1178 &stack_lower, | 1191 &stack_lower, |
1179 &stack_upper)) { | 1192 &stack_upper)) { |
| 1193 counters_.single_frame_sample_get_and_validate_stack_bounds++; |
1180 // Could not get stack boundary. | 1194 // Could not get stack boundary. |
1181 SampleThreadSingleFrame(thread, pc); | 1195 SampleThreadSingleFrame(thread, pc); |
1182 return; | 1196 return; |
1183 } | 1197 } |
1184 | 1198 |
1185 // At this point we have a valid stack boundary for this isolate and | 1199 // At this point we have a valid stack boundary for this isolate and |
1186 // know that our initial stack and frame pointers are within the boundary. | 1200 // know that our initial stack and frame pointers are within the boundary. |
1187 SampleBuffer* sample_buffer = Profiler::sample_buffer(); | 1201 SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
1188 if (sample_buffer == NULL) { | 1202 if (sample_buffer == NULL) { |
1189 // Profiler not initialized. | 1203 // Profiler not initialized. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1227 // All memory access is done inside CollectSample. | 1241 // All memory access is done inside CollectSample. |
1228 CollectSample(isolate, | 1242 CollectSample(isolate, |
1229 exited_dart_code, | 1243 exited_dart_code, |
1230 in_dart_code, | 1244 in_dart_code, |
1231 sample, | 1245 sample, |
1232 &native_stack_walker, | 1246 &native_stack_walker, |
1233 &dart_exit_stack_walker, | 1247 &dart_exit_stack_walker, |
1234 &dart_stack_walker, | 1248 &dart_stack_walker, |
1235 pc, | 1249 pc, |
1236 fp, | 1250 fp, |
1237 sp); | 1251 sp, |
| 1252 &counters_); |
1238 } | 1253 } |
1239 | 1254 |
1240 | 1255 |
1241 | 1256 |
1242 CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) { | 1257 CodeDescriptor::CodeDescriptor(const Code& code) : code_(code) { |
1243 ASSERT(!code_.IsNull()); | 1258 ASSERT(!code_.IsNull()); |
1244 } | 1259 } |
1245 | 1260 |
1246 | 1261 |
1247 uword CodeDescriptor::Entry() const { | 1262 uword CodeDescriptor::Entry() const { |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1564 | 1579 |
1565 | 1580 |
1566 ProcessedSampleBuffer::ProcessedSampleBuffer() | 1581 ProcessedSampleBuffer::ProcessedSampleBuffer() |
1567 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { | 1582 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { |
1568 ASSERT(code_lookup_table_ != NULL); | 1583 ASSERT(code_lookup_table_ != NULL); |
1569 } | 1584 } |
1570 | 1585 |
1571 #endif // !PRODUCT | 1586 #endif // !PRODUCT |
1572 | 1587 |
1573 } // namespace dart | 1588 } // namespace dart |
OLD | NEW |