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 <cstdio> | 5 #include <cstdio> |
6 | 6 |
7 #include "platform/utils.h" | 7 #include "platform/utils.h" |
8 | 8 |
9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
10 #include "vm/json_stream.h" | 10 #include "vm/json_stream.h" |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 void ProfilerManager::Shutdown() { | 96 void ProfilerManager::Shutdown() { |
97 if (!FLAG_profile) { | 97 if (!FLAG_profile) { |
98 return; | 98 return; |
99 } | 99 } |
100 ASSERT(initialized_); | 100 ASSERT(initialized_); |
101 { | 101 { |
102 ScopedSignalBlocker ssb; | 102 ScopedSignalBlocker ssb; |
103 { | 103 { |
104 ScopedMonitor lock(monitor_); | 104 ScopedMonitor lock(monitor_); |
105 shutdown_ = true; | 105 shutdown_ = true; |
106 for (intptr_t i = 0; i < isolates_size_; i++) { | |
107 Isolate* isolate = isolates_[i]; | |
108 ASSERT(isolate != NULL); | |
109 FreeIsolateProfilingData(isolate); | |
110 } | |
111 isolates_size_ = 0; | 106 isolates_size_ = 0; |
112 free(isolates_); | 107 free(isolates_); |
113 isolates_ = NULL; | 108 isolates_ = NULL; |
114 lock.Notify(); | 109 lock.Notify(); |
115 } | 110 } |
116 } | 111 } |
117 NativeSymbolResolver::ShutdownOnce(); | 112 NativeSymbolResolver::ShutdownOnce(); |
118 } | 113 } |
119 | 114 |
120 | 115 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 168 } |
174 } | 169 } |
175 | 170 |
176 | 171 |
177 void ProfilerManager::ScheduleIsolate(Isolate* isolate, bool inside_signal) { | 172 void ProfilerManager::ScheduleIsolate(Isolate* isolate, bool inside_signal) { |
178 if (!FLAG_profile) { | 173 if (!FLAG_profile) { |
179 return; | 174 return; |
180 } | 175 } |
181 ASSERT(initialized_); | 176 ASSERT(initialized_); |
182 ASSERT(isolate != NULL); | 177 ASSERT(isolate != NULL); |
183 { | 178 if (!inside_signal) { |
184 ScopedSignalBlocker ssb; | 179 ScopedSignalBlocker ssb; |
185 { | 180 { |
186 ScopedMonitor lock(monitor_); | 181 ScopedMonitor lock(monitor_); |
187 { | 182 { |
188 ScopedMutex profiler_data_lock(isolate->profiler_data_mutex()); | 183 ScopedMutex profiler_data_lock(isolate->profiler_data_mutex()); |
189 IsolateProfilerData* profiler_data = isolate->profiler_data(); | 184 IsolateProfilerData* profiler_data = isolate->profiler_data(); |
190 if (profiler_data == NULL) { | 185 if (profiler_data == NULL) { |
191 return; | 186 return; |
192 } | 187 } |
193 profiler_data->Scheduled(OS::GetCurrentTimeMicros(), | 188 profiler_data->Scheduled(OS::GetCurrentTimeMicros(), |
194 Thread::GetCurrentThreadId()); | 189 Thread::GetCurrentThreadId()); |
195 AddIsolate(isolate); | |
196 lock.Notify(); | |
197 } | 190 } |
| 191 AddIsolate(isolate); |
| 192 lock.Notify(); |
| 193 } |
| 194 } else { |
| 195 // Do not need a signal blocker inside a signal handler. |
| 196 { |
| 197 ScopedMonitor lock(monitor_); |
| 198 { |
| 199 ScopedMutex profiler_data_lock(isolate->profiler_data_mutex()); |
| 200 IsolateProfilerData* profiler_data = isolate->profiler_data(); |
| 201 if (profiler_data == NULL) { |
| 202 return; |
| 203 } |
| 204 profiler_data->Scheduled(OS::GetCurrentTimeMicros(), |
| 205 Thread::GetCurrentThreadId()); |
| 206 } |
| 207 AddIsolate(isolate); |
| 208 lock.Notify(); |
198 } | 209 } |
199 } | 210 } |
200 } | 211 } |
201 | 212 |
202 | 213 |
203 void ProfilerManager::DescheduleIsolate(Isolate* isolate) { | 214 void ProfilerManager::DescheduleIsolate(Isolate* isolate) { |
204 if (!FLAG_profile) { | 215 if (!FLAG_profile) { |
205 return; | 216 return; |
206 } | 217 } |
207 ASSERT(initialized_); | 218 ASSERT(initialized_); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 if (isolates_size_ == isolates_capacity_) { | 268 if (isolates_size_ == isolates_capacity_) { |
258 ResizeIsolates(isolates_capacity_ == 0 ? 16 : isolates_capacity_ * 2); | 269 ResizeIsolates(isolates_capacity_ == 0 ? 16 : isolates_capacity_ * 2); |
259 } | 270 } |
260 isolates_[isolates_size_] = isolate; | 271 isolates_[isolates_size_] = isolate; |
261 isolates_size_++; | 272 isolates_size_++; |
262 } | 273 } |
263 | 274 |
264 | 275 |
265 intptr_t ProfilerManager::FindIsolate(Isolate* isolate) { | 276 intptr_t ProfilerManager::FindIsolate(Isolate* isolate) { |
266 // Must be called with monitor_ locked. | 277 // Must be called with monitor_ locked. |
| 278 if (isolates_ == NULL) { |
| 279 // We are shutting down. |
| 280 return -1; |
| 281 } |
267 for (intptr_t i = 0; i < isolates_size_; i++) { | 282 for (intptr_t i = 0; i < isolates_size_; i++) { |
268 if (isolates_[i] == isolate) { | 283 if (isolates_[i] == isolate) { |
269 return i; | 284 return i; |
270 } | 285 } |
271 } | 286 } |
272 return -1; | 287 return -1; |
273 } | 288 } |
274 | 289 |
275 | 290 |
276 void ProfilerManager::RemoveIsolate(intptr_t i) { | 291 void ProfilerManager::RemoveIsolate(intptr_t i) { |
277 // Must be called with monitor_ locked. | 292 // Must be called with monitor_ locked. |
| 293 if (isolates_ == NULL) { |
| 294 // We are shutting down. |
| 295 return; |
| 296 } |
278 ASSERT(i < isolates_size_); | 297 ASSERT(i < isolates_size_); |
279 intptr_t last = isolates_size_ - 1; | 298 intptr_t last = isolates_size_ - 1; |
280 if (i != last) { | 299 if (i != last) { |
281 isolates_[i] = isolates_[last]; | 300 isolates_[i] = isolates_[last]; |
282 } | 301 } |
283 // Mark last as NULL. | 302 // Mark last as NULL. |
284 isolates_[last] = NULL; | 303 isolates_[last] = NULL; |
285 // Pop. | 304 // Pop. |
286 isolates_size_--; | 305 isolates_size_--; |
287 } | 306 } |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 original_pc_(pc), | 589 original_pc_(pc), |
571 original_fp_(fp), | 590 original_fp_(fp), |
572 original_sp_(sp), | 591 original_sp_(sp), |
573 lower_bound_(stack_lower) { | 592 lower_bound_(stack_lower) { |
574 ASSERT(sample_ != NULL); | 593 ASSERT(sample_ != NULL); |
575 } | 594 } |
576 | 595 |
577 | 596 |
578 int ProfilerSampleStackWalker::walk() { | 597 int ProfilerSampleStackWalker::walk() { |
579 uword* pc = reinterpret_cast<uword*>(original_pc_); | 598 uword* pc = reinterpret_cast<uword*>(original_pc_); |
| 599 #if defined(WALK_STACK) |
580 uword* fp = reinterpret_cast<uword*>(original_fp_); | 600 uword* fp = reinterpret_cast<uword*>(original_fp_); |
581 uword* previous_fp = fp; | 601 uword* previous_fp = fp; |
582 if (original_sp_ < lower_bound_) { | 602 if (original_sp_ < lower_bound_) { |
583 // The stack pointer gives us a better lower bound than | 603 // The stack pointer gives us a better lower bound than |
584 // the isolates stack limit. | 604 // the isolates stack limit. |
585 lower_bound_ = original_sp_; | 605 lower_bound_ = original_sp_; |
586 } | 606 } |
587 int i = 0; | 607 int i = 0; |
588 for (; i < Sample::kNumStackFrames; i++) { | 608 for (; i < Sample::kNumStackFrames; i++) { |
589 sample_->pcs[i] = reinterpret_cast<uintptr_t>(pc); | 609 sample_->pcs[i] = reinterpret_cast<uintptr_t>(pc); |
590 if (!ValidFramePointer(fp)) { | 610 if (!ValidFramePointer(fp)) { |
591 break; | 611 break; |
592 } | 612 } |
593 pc = CallerPC(fp); | 613 pc = CallerPC(fp); |
594 previous_fp = fp; | 614 previous_fp = fp; |
595 fp = CallerFP(fp); | 615 fp = CallerFP(fp); |
596 if ((fp <= previous_fp) || !ValidFramePointer(fp)) { | 616 if ((fp <= previous_fp) || !ValidFramePointer(fp)) { |
597 // Frame pointers should only move to higher addresses. | 617 // Frame pointers should only move to higher addresses. |
598 break; | 618 break; |
599 } | 619 } |
600 // Move the lower bound up. | 620 // Move the lower bound up. |
601 lower_bound_ = reinterpret_cast<uintptr_t>(fp); | 621 lower_bound_ = reinterpret_cast<uintptr_t>(fp); |
602 } | 622 } |
603 return i; | 623 return i; |
| 624 #else |
| 625 sample_->pcs[0] = reinterpret_cast<uintptr_t>(pc); |
| 626 return 0; |
| 627 #endif |
604 } | 628 } |
605 | 629 |
606 | 630 |
607 uword* ProfilerSampleStackWalker::CallerPC(uword* fp) { | 631 uword* ProfilerSampleStackWalker::CallerPC(uword* fp) { |
608 ASSERT(fp != NULL); | 632 ASSERT(fp != NULL); |
609 return reinterpret_cast<uword*>(*(fp + 1)); | 633 return reinterpret_cast<uword*>(*(fp + 1)); |
610 } | 634 } |
611 | 635 |
612 | 636 |
613 uword* ProfilerSampleStackWalker::CallerFP(uword* fp) { | 637 uword* ProfilerSampleStackWalker::CallerFP(uword* fp) { |
614 ASSERT(fp != NULL); | 638 ASSERT(fp != NULL); |
615 return reinterpret_cast<uword*>(*fp); | 639 return reinterpret_cast<uword*>(*fp); |
616 } | 640 } |
617 | 641 |
618 | 642 |
619 bool ProfilerSampleStackWalker::ValidFramePointer(uword* fp) { | 643 bool ProfilerSampleStackWalker::ValidFramePointer(uword* fp) { |
620 if (fp == NULL) { | 644 if (fp == NULL) { |
621 return false; | 645 return false; |
622 } | 646 } |
623 uintptr_t cursor = reinterpret_cast<uintptr_t>(fp); | 647 uintptr_t cursor = reinterpret_cast<uintptr_t>(fp); |
624 cursor += sizeof(fp); | 648 cursor += sizeof(fp); |
625 bool r = cursor >= lower_bound_ && cursor < stack_upper_; | 649 bool r = cursor >= lower_bound_ && cursor < stack_upper_; |
626 return r; | 650 return r; |
627 } | 651 } |
628 | 652 |
629 | 653 |
630 } // namespace dart | 654 } // namespace dart |
OLD | NEW |