| 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 |