| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 // Zero counters. |
| 69 memset(&counters_, 0, sizeof(counters_)); |
| 68 NativeSymbolResolver::InitOnce(); | 70 NativeSymbolResolver::InitOnce(); |
| 69 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period); | 71 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period); |
| 70 ThreadInterrupter::Startup(); | 72 ThreadInterrupter::Startup(); |
| 71 // Zero counters. | |
| 72 memset(&counters_, 0, sizeof(counters_)); | |
| 73 initialized_ = true; | 73 initialized_ = true; |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 void Profiler::Shutdown() { | 77 void Profiler::Shutdown() { |
| 78 if (!FLAG_profiler) { | 78 if (!FLAG_profiler) { |
| 79 return; | 79 return; |
| 80 } | 80 } |
| 81 ASSERT(initialized_); | 81 ASSERT(initialized_); |
| 82 ThreadInterrupter::Shutdown(); | 82 ThreadInterrupter::Shutdown(); |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 #endif | 779 #endif |
| 780 | 780 |
| 781 if (in_dart_code) { | 781 if (in_dart_code) { |
| 782 // We can only trust the stack pointer if we are executing Dart code. | 782 // We can only trust the stack pointer if we are executing Dart code. |
| 783 // See http://dartbug.com/20421 for details. | 783 // See http://dartbug.com/20421 for details. |
| 784 CopyStackBuffer(sample, sp); | 784 CopyStackBuffer(sample, sp); |
| 785 } | 785 } |
| 786 | 786 |
| 787 if (FLAG_profile_vm) { | 787 if (FLAG_profile_vm) { |
| 788 // Always walk the native stack collecting both native and Dart frames. | 788 // Always walk the native stack collecting both native and Dart frames. |
| 789 counters->stack_walker_native++; | 789 AtomicOperations::IncrementInt64By(&counters->stack_walker_native, 1); |
| 790 native_stack_walker->walk(); | 790 native_stack_walker->walk(); |
| 791 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { | 791 } else if (StubCode::HasBeenInitialized() && exited_dart_code) { |
| 792 counters->stack_walker_dart_exit++; | 792 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart_exit, 1); |
| 793 // We have a valid exit frame info, use the Dart stack walker. | 793 // We have a valid exit frame info, use the Dart stack walker. |
| 794 dart_exit_stack_walker->walk(); | 794 dart_exit_stack_walker->walk(); |
| 795 } else if (StubCode::HasBeenInitialized() && in_dart_code) { | 795 } else if (StubCode::HasBeenInitialized() && in_dart_code) { |
| 796 counters->stack_walker_dart++; | 796 AtomicOperations::IncrementInt64By(&counters->stack_walker_dart, 1); |
| 797 // We are executing Dart code. We have frame pointers. | 797 // We are executing Dart code. We have frame pointers. |
| 798 dart_stack_walker->walk(); | 798 dart_stack_walker->walk(); |
| 799 } else { | 799 } else { |
| 800 counters->stack_walker_none++; | 800 AtomicOperations::IncrementInt64By(&counters->stack_walker_none, 1); |
| 801 sample->SetAt(0, pc); | 801 sample->SetAt(0, pc); |
| 802 } | 802 } |
| 803 | 803 |
| 804 #if defined(TARGET_OS_WINDOWS) | 804 #if defined(TARGET_OS_WINDOWS) |
| 805 // Use structured exception handling to trap guard page access. | 805 // Use structured exception handling to trap guard page access. |
| 806 } __except(GuardPageExceptionFilter(GetExceptionInformation())) { | 806 } __except(GuardPageExceptionFilter(GetExceptionInformation())) { |
| 807 // Sample collection triggered a guard page fault: | 807 // Sample collection triggered a guard page fault: |
| 808 // 1) discard entire sample. | 808 // 1) discard entire sample. |
| 809 sample->set_ignore_sample(true); | 809 sample->set_ignore_sample(true); |
| 810 | 810 |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 | 1132 |
| 1133 void Profiler::SampleThread(Thread* thread, | 1133 void Profiler::SampleThread(Thread* thread, |
| 1134 const InterruptedThreadState& state) { | 1134 const InterruptedThreadState& state) { |
| 1135 ASSERT(thread != NULL); | 1135 ASSERT(thread != NULL); |
| 1136 OSThread* os_thread = thread->os_thread(); | 1136 OSThread* os_thread = thread->os_thread(); |
| 1137 ASSERT(os_thread != NULL); | 1137 ASSERT(os_thread != NULL); |
| 1138 Isolate* isolate = thread->isolate(); | 1138 Isolate* isolate = thread->isolate(); |
| 1139 | 1139 |
| 1140 // Thread is not doing VM work. | 1140 // Thread is not doing VM work. |
| 1141 if (thread->task_kind() == Thread::kUnknownTask) { | 1141 if (thread->task_kind() == Thread::kUnknownTask) { |
| 1142 counters_.bail_out_unknown_task++; | 1142 AtomicOperations::IncrementInt64By(&counters_.bail_out_unknown_task, 1); |
| 1143 return; | 1143 return; |
| 1144 } | 1144 } |
| 1145 | 1145 |
| 1146 if (StubCode::HasBeenInitialized() && | 1146 if (StubCode::HasBeenInitialized() && |
| 1147 StubCode::InJumpToExceptionHandlerStub(state.pc)) { | 1147 StubCode::InJumpToExceptionHandlerStub(state.pc)) { |
| 1148 // The JumpToExceptionHandler stub manually adjusts the stack pointer, | 1148 // The JumpToExceptionHandler stub manually adjusts the stack pointer, |
| 1149 // frame pointer, and some isolate state before jumping to a catch entry. | 1149 // frame pointer, and some isolate state before jumping to a catch entry. |
| 1150 // It is not safe to walk the stack when executing this stub. | 1150 // It is not safe to walk the stack when executing this stub. |
| 1151 counters_.bail_out_jump_to_exception_handler++; | 1151 AtomicOperations::IncrementInt64By( |
| 1152 &counters_.bail_out_jump_to_exception_handler, 1); |
| 1152 return; | 1153 return; |
| 1153 } | 1154 } |
| 1154 | 1155 |
| 1155 const bool in_dart_code = thread->IsExecutingDartCode(); | 1156 const bool in_dart_code = thread->IsExecutingDartCode(); |
| 1156 | 1157 |
| 1157 uintptr_t sp = 0; | 1158 uintptr_t sp = 0; |
| 1158 uintptr_t fp = state.fp; | 1159 uintptr_t fp = state.fp; |
| 1159 uintptr_t pc = state.pc; | 1160 uintptr_t pc = state.pc; |
| 1160 #if defined(USING_SIMULATOR) | 1161 #if defined(USING_SIMULATOR) |
| 1161 Simulator* simulator = NULL; | 1162 Simulator* simulator = NULL; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1175 pc = simulator->get_pc(); | 1176 pc = simulator->get_pc(); |
| 1176 #else | 1177 #else |
| 1177 sp = state.dsp; | 1178 sp = state.dsp; |
| 1178 #endif | 1179 #endif |
| 1179 } else { | 1180 } else { |
| 1180 // If we're in runtime code, use the C stack pointer. | 1181 // If we're in runtime code, use the C stack pointer. |
| 1181 sp = state.csp; | 1182 sp = state.csp; |
| 1182 } | 1183 } |
| 1183 | 1184 |
| 1184 if (!CheckIsolate(isolate)) { | 1185 if (!CheckIsolate(isolate)) { |
| 1185 counters_.bail_out_check_isolate++; | 1186 AtomicOperations::IncrementInt64By(&counters_.bail_out_check_isolate, 1); |
| 1186 return; | 1187 return; |
| 1187 } | 1188 } |
| 1188 | 1189 |
| 1189 if (thread->IsMutatorThread() && isolate->IsDeoptimizing()) { | 1190 if (thread->IsMutatorThread() && isolate->IsDeoptimizing()) { |
| 1190 counters_.single_frame_sample_deoptimizing++; | 1191 AtomicOperations::IncrementInt64By( |
| 1192 &counters_.single_frame_sample_deoptimizing, 1); |
| 1191 SampleThreadSingleFrame(thread, pc); | 1193 SampleThreadSingleFrame(thread, pc); |
| 1192 return; | 1194 return; |
| 1193 } | 1195 } |
| 1194 | 1196 |
| 1195 if (!InitialRegisterCheck(pc, fp, sp)) { | 1197 if (!InitialRegisterCheck(pc, fp, sp)) { |
| 1196 counters_.single_frame_sample_register_check++; | 1198 AtomicOperations::IncrementInt64By( |
| 1199 &counters_.single_frame_sample_register_check, 1); |
| 1197 SampleThreadSingleFrame(thread, pc); | 1200 SampleThreadSingleFrame(thread, pc); |
| 1198 return; | 1201 return; |
| 1199 } | 1202 } |
| 1200 | 1203 |
| 1201 uword stack_lower = 0; | 1204 uword stack_lower = 0; |
| 1202 uword stack_upper = 0; | 1205 uword stack_upper = 0; |
| 1203 if (!GetAndValidateIsolateStackBounds(thread, | 1206 if (!GetAndValidateIsolateStackBounds(thread, |
| 1204 fp, | 1207 fp, |
| 1205 sp, | 1208 sp, |
| 1206 &stack_lower, | 1209 &stack_lower, |
| 1207 &stack_upper)) { | 1210 &stack_upper)) { |
| 1208 counters_.single_frame_sample_get_and_validate_stack_bounds++; | 1211 AtomicOperations::IncrementInt64By( |
| 1212 &counters_.single_frame_sample_get_and_validate_stack_bounds, 1); |
| 1209 // Could not get stack boundary. | 1213 // Could not get stack boundary. |
| 1210 SampleThreadSingleFrame(thread, pc); | 1214 SampleThreadSingleFrame(thread, pc); |
| 1211 return; | 1215 return; |
| 1212 } | 1216 } |
| 1213 | 1217 |
| 1214 // At this point we have a valid stack boundary for this isolate and | 1218 // At this point we have a valid stack boundary for this isolate and |
| 1215 // know that our initial stack and frame pointers are within the boundary. | 1219 // know that our initial stack and frame pointers are within the boundary. |
| 1216 SampleBuffer* sample_buffer = Profiler::sample_buffer(); | 1220 SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
| 1217 if (sample_buffer == NULL) { | 1221 if (sample_buffer == NULL) { |
| 1218 // Profiler not initialized. | 1222 // Profiler not initialized. |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 | 1598 |
| 1595 | 1599 |
| 1596 ProcessedSampleBuffer::ProcessedSampleBuffer() | 1600 ProcessedSampleBuffer::ProcessedSampleBuffer() |
| 1597 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { | 1601 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { |
| 1598 ASSERT(code_lookup_table_ != NULL); | 1602 ASSERT(code_lookup_table_ != NULL); |
| 1599 } | 1603 } |
| 1600 | 1604 |
| 1601 #endif // !PRODUCT | 1605 #endif // !PRODUCT |
| 1602 | 1606 |
| 1603 } // namespace dart | 1607 } // namespace dart |
| OLD | NEW |