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 |