| 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/atomic.h" | 9 #include "vm/atomic.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 if (profiler_data == NULL) { | 126 if (profiler_data == NULL) { |
| 127 return; | 127 return; |
| 128 } | 128 } |
| 129 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); | 129 SampleBuffer* sample_buffer = profiler_data->sample_buffer(); |
| 130 if (sample_buffer == NULL) { | 130 if (sample_buffer == NULL) { |
| 131 return; | 131 return; |
| 132 } | 132 } |
| 133 Sample* sample = sample_buffer->ReserveSample(); | 133 Sample* sample = sample_buffer->ReserveSample(); |
| 134 sample->Init(Sample::kIsolateStart, isolate, OS::GetCurrentTimeMicros(), | 134 sample->Init(Sample::kIsolateStart, isolate, OS::GetCurrentTimeMicros(), |
| 135 Thread::GetCurrentThreadId()); | 135 Thread::GetCurrentThreadId()); |
| 136 ThreadInterrupter::Register(ThreadInterruptNoOp, isolate); | 136 ThreadInterrupter::Register(RecordSampleInterruptCallback, isolate); |
| 137 } | 137 } |
| 138 | 138 |
| 139 | 139 |
| 140 void Profiler::EndExecution(Isolate* isolate) { | 140 void Profiler::EndExecution(Isolate* isolate) { |
| 141 if (isolate == NULL) { | 141 if (isolate == NULL) { |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 if (!FLAG_profile) { | 144 if (!FLAG_profile) { |
| 145 return; | 145 return; |
| 146 } | 146 } |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 stack_upper_(stack_upper), | 455 stack_upper_(stack_upper), |
| 456 original_pc_(pc), | 456 original_pc_(pc), |
| 457 original_fp_(fp), | 457 original_fp_(fp), |
| 458 original_sp_(sp), | 458 original_sp_(sp), |
| 459 lower_bound_(stack_lower) { | 459 lower_bound_(stack_lower) { |
| 460 ASSERT(sample_ != NULL); | 460 ASSERT(sample_ != NULL); |
| 461 } | 461 } |
| 462 | 462 |
| 463 | 463 |
| 464 int ProfilerSampleStackWalker::walk() { | 464 int ProfilerSampleStackWalker::walk() { |
| 465 const intptr_t kMaxStep = 0x1000; // 4K. |
| 465 uword* pc = reinterpret_cast<uword*>(original_pc_); | 466 uword* pc = reinterpret_cast<uword*>(original_pc_); |
| 466 #define WALK_STACK | 467 #define WALK_STACK |
| 467 #if defined(WALK_STACK) | 468 #if defined(WALK_STACK) |
| 468 uword* fp = reinterpret_cast<uword*>(original_fp_); | 469 uword* fp = reinterpret_cast<uword*>(original_fp_); |
| 469 uword* previous_fp = fp; | 470 uword* previous_fp = fp; |
| 471 if (original_sp_ > original_fp_) { |
| 472 // Stack pointer should not be above frame pointer. |
| 473 return 0; |
| 474 } |
| 475 if ((original_fp_ - original_sp_) >= kMaxStep) { |
| 476 // Gap between frame pointer and stack pointer is |
| 477 // too large. |
| 478 return 0; |
| 479 } |
| 470 if (original_sp_ < lower_bound_) { | 480 if (original_sp_ < lower_bound_) { |
| 471 // The stack pointer gives us a better lower bound than | 481 // The stack pointer gives us a better lower bound than |
| 472 // the isolates stack limit. | 482 // the isolates stack limit. |
| 473 lower_bound_ = original_sp_; | 483 lower_bound_ = original_sp_; |
| 474 } | 484 } |
| 475 int i = 0; | 485 int i = 0; |
| 476 for (; i < Sample::kNumStackFrames; i++) { | 486 for (; i < Sample::kNumStackFrames; i++) { |
| 477 sample_->pcs[i] = reinterpret_cast<uintptr_t>(pc); | 487 sample_->pcs[i] = reinterpret_cast<uintptr_t>(pc); |
| 478 if (!ValidFramePointer(fp)) { | 488 if (!ValidFramePointer(fp)) { |
| 479 break; | 489 break; |
| 480 } | 490 } |
| 481 pc = CallerPC(fp); | 491 pc = CallerPC(fp); |
| 482 previous_fp = fp; | 492 previous_fp = fp; |
| 483 fp = CallerFP(fp); | 493 fp = CallerFP(fp); |
| 484 if ((fp <= previous_fp) || !ValidFramePointer(fp)) { | 494 intptr_t step = fp - previous_fp; |
| 485 // Frame pointers should only move to higher addresses. | 495 if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) { |
| 496 // Frame pointer step is too large. |
| 497 // Frame pointer did not move to a higher address. |
| 498 // Frame pointer is outside of isolate stack bounds. |
| 486 break; | 499 break; |
| 487 } | 500 } |
| 488 // Move the lower bound up. | 501 // Move the lower bound up. |
| 489 lower_bound_ = reinterpret_cast<uintptr_t>(fp); | 502 lower_bound_ = reinterpret_cast<uintptr_t>(fp); |
| 490 } | 503 } |
| 491 return i; | 504 return i; |
| 492 #else | 505 #else |
| 493 sample_->pcs[0] = reinterpret_cast<uintptr_t>(pc); | 506 sample_->pcs[0] = reinterpret_cast<uintptr_t>(pc); |
| 494 return 0; | 507 return 0; |
| 495 #endif | 508 #endif |
| (...skipping 17 matching lines...) Expand all Loading... |
| 513 return false; | 526 return false; |
| 514 } | 527 } |
| 515 uintptr_t cursor = reinterpret_cast<uintptr_t>(fp); | 528 uintptr_t cursor = reinterpret_cast<uintptr_t>(fp); |
| 516 cursor += sizeof(fp); | 529 cursor += sizeof(fp); |
| 517 bool r = cursor >= lower_bound_ && cursor < stack_upper_; | 530 bool r = cursor >= lower_bound_ && cursor < stack_upper_; |
| 518 return r; | 531 return r; |
| 519 } | 532 } |
| 520 | 533 |
| 521 | 534 |
| 522 } // namespace dart | 535 } // namespace dart |
| OLD | NEW |