| 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/utils.h" | 5 #include "platform/utils.h" |
| 6 | 6 |
| 7 #include "vm/allocation.h" | 7 #include "vm/allocation.h" |
| 8 #include "vm/atomic.h" | 8 #include "vm/atomic.h" |
| 9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 DEFINE_FLAG(bool, profile_native_stack, true, | 39 DEFINE_FLAG(bool, profile_native_stack, true, |
| 40 "Use native stack in profiler."); | 40 "Use native stack in profiler."); |
| 41 | 41 |
| 42 bool Profiler::initialized_ = false; | 42 bool Profiler::initialized_ = false; |
| 43 SampleBuffer* Profiler::sample_buffer_ = NULL; | 43 SampleBuffer* Profiler::sample_buffer_ = NULL; |
| 44 | 44 |
| 45 void Profiler::InitOnce() { | 45 void Profiler::InitOnce() { |
| 46 // Place some sane restrictions on user controlled flags. | 46 // Place some sane restrictions on user controlled flags. |
| 47 SetSamplePeriod(FLAG_profile_period); | 47 SetSamplePeriod(FLAG_profile_period); |
| 48 SetSampleDepth(FLAG_profile_depth); | 48 SetSampleDepth(FLAG_profile_depth); |
| 49 Sample::InitOnce(); |
| 49 if (!FLAG_profile) { | 50 if (!FLAG_profile) { |
| 50 return; | 51 return; |
| 51 } | 52 } |
| 52 ASSERT(!initialized_); | 53 ASSERT(!initialized_); |
| 53 sample_buffer_ = new SampleBuffer(); | 54 sample_buffer_ = new SampleBuffer(); |
| 54 NativeSymbolResolver::InitOnce(); | 55 NativeSymbolResolver::InitOnce(); |
| 55 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period); | 56 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period); |
| 56 ThreadInterrupter::Startup(); | 57 ThreadInterrupter::Startup(); |
| 57 initialized_ = true; | 58 initialized_ = true; |
| 58 } | 59 } |
| 59 | 60 |
| 60 | 61 |
| 61 void Profiler::Shutdown() { | 62 void Profiler::Shutdown() { |
| 62 if (!FLAG_profile) { | 63 if (!FLAG_profile) { |
| 63 return; | 64 return; |
| 64 } | 65 } |
| 65 ASSERT(initialized_); | 66 ASSERT(initialized_); |
| 66 ThreadInterrupter::Shutdown(); | 67 ThreadInterrupter::Shutdown(); |
| 67 NativeSymbolResolver::ShutdownOnce(); | 68 NativeSymbolResolver::ShutdownOnce(); |
| 68 } | 69 } |
| 69 | 70 |
| 70 | 71 |
| 71 void Profiler::SetSampleDepth(intptr_t depth) { | 72 void Profiler::SetSampleDepth(intptr_t depth) { |
| 72 const int kMinimumDepth = 1; | 73 const int kMinimumDepth = 1; |
| 73 const int kMaximumDepth = kSampleFramesSize - 1; | 74 const int kMaximumDepth = 255; |
| 74 if (depth < kMinimumDepth) { | 75 if (depth < kMinimumDepth) { |
| 75 FLAG_profile_depth = kMinimumDepth; | 76 FLAG_profile_depth = kMinimumDepth; |
| 76 } else if (depth > kMaximumDepth) { | 77 } else if (depth > kMaximumDepth) { |
| 77 FLAG_profile_depth = kMaximumDepth; | 78 FLAG_profile_depth = kMaximumDepth; |
| 78 } else { | 79 } else { |
| 79 FLAG_profile_depth = depth; | 80 FLAG_profile_depth = depth; |
| 80 } | 81 } |
| 81 } | 82 } |
| 82 | 83 |
| 83 | 84 |
| (...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 if (block_count_ < 0) { | 1611 if (block_count_ < 0) { |
| 1611 FATAL("Too many calls to Dart_IsolateUnblocked."); | 1612 FATAL("Too many calls to Dart_IsolateUnblocked."); |
| 1612 } | 1613 } |
| 1613 if (!blocked()) { | 1614 if (!blocked()) { |
| 1614 // We just unblocked this isolate, wake up the thread interrupter. | 1615 // We just unblocked this isolate, wake up the thread interrupter. |
| 1615 ThreadInterrupter::WakeUp(); | 1616 ThreadInterrupter::WakeUp(); |
| 1616 } | 1617 } |
| 1617 } | 1618 } |
| 1618 | 1619 |
| 1619 | 1620 |
| 1621 intptr_t Sample::pcs_length_ = 0; |
| 1622 intptr_t Sample::instance_size_ = 0; |
| 1623 |
| 1624 |
| 1625 void Sample::InitOnce() { |
| 1626 ASSERT(FLAG_profile_depth >= 1); |
| 1627 pcs_length_ = FLAG_profile_depth; |
| 1628 instance_size_ = |
| 1629 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT. |
| 1630 } |
| 1631 |
| 1632 |
| 1633 uword* Sample::GetPCArray() const { |
| 1634 return reinterpret_cast<uword*>( |
| 1635 reinterpret_cast<uintptr_t>(this) + sizeof(*this)); |
| 1636 } |
| 1637 |
| 1638 |
| 1639 // Get stack trace entry. |
| 1640 uword Sample::At(intptr_t i) const { |
| 1641 ASSERT(i >= 0); |
| 1642 ASSERT(i < pcs_length_); |
| 1643 uword* pcs = GetPCArray(); |
| 1644 return pcs[i]; |
| 1645 } |
| 1646 |
| 1647 |
| 1648 // Set stack trace entry. |
| 1649 void Sample::SetAt(intptr_t i, uword pc) { |
| 1650 ASSERT(i >= 0); |
| 1651 ASSERT(i < pcs_length_); |
| 1652 uword* pcs = GetPCArray(); |
| 1653 pcs[i] = pc; |
| 1654 } |
| 1655 |
| 1656 |
| 1657 SampleBuffer::SampleBuffer(intptr_t capacity) { |
| 1658 ASSERT(Sample::instance_size() > 0); |
| 1659 samples_ = reinterpret_cast<Sample*>( |
| 1660 calloc(capacity, Sample::instance_size())); |
| 1661 capacity_ = capacity; |
| 1662 cursor_ = 0; |
| 1663 } |
| 1664 |
| 1665 |
| 1666 Sample* SampleBuffer::At(intptr_t idx) const { |
| 1667 ASSERT(idx >= 0); |
| 1668 ASSERT(idx < capacity_); |
| 1669 intptr_t offset = idx * Sample::instance_size(); |
| 1670 uint8_t* samples = reinterpret_cast<uint8_t*>(samples_); |
| 1671 return reinterpret_cast<Sample*>(samples + offset); |
| 1672 } |
| 1673 |
| 1674 |
| 1620 Sample* SampleBuffer::ReserveSample() { | 1675 Sample* SampleBuffer::ReserveSample() { |
| 1621 ASSERT(samples_ != NULL); | 1676 ASSERT(samples_ != NULL); |
| 1622 uintptr_t cursor = AtomicOperations::FetchAndIncrement(&cursor_); | 1677 uintptr_t cursor = AtomicOperations::FetchAndIncrement(&cursor_); |
| 1623 // Map back into sample buffer range. | 1678 // Map back into sample buffer range. |
| 1624 cursor = cursor % capacity_; | 1679 cursor = cursor % capacity_; |
| 1625 return At(cursor); | 1680 return At(cursor); |
| 1626 } | 1681 } |
| 1627 | 1682 |
| 1628 | 1683 |
| 1629 class ProfilerDartStackWalker : public ValueObject { | 1684 class ProfilerDartStackWalker : public ValueObject { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1862 ProfilerDartStackWalker stackWalker(sample); | 1917 ProfilerDartStackWalker stackWalker(sample); |
| 1863 stackWalker.walk(); | 1918 stackWalker.walk(); |
| 1864 } else { | 1919 } else { |
| 1865 // TODO(johnmccutchan): Support collecting only Dart frames with | 1920 // TODO(johnmccutchan): Support collecting only Dart frames with |
| 1866 // ProfilerNativeStackWalker. | 1921 // ProfilerNativeStackWalker. |
| 1867 } | 1922 } |
| 1868 } | 1923 } |
| 1869 } | 1924 } |
| 1870 | 1925 |
| 1871 } // namespace dart | 1926 } // namespace dart |
| OLD | NEW |