Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(449)

Side by Side Diff: runtime/vm/profiler.cc

Issue 973553005: Fix memory leak in CPU Profile page (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/profiler.h ('k') | runtime/vm/profiler_service.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/address_sanitizer.h" 5 #include "platform/address_sanitizer.h"
6 #include "platform/memory_sanitizer.h" 6 #include "platform/memory_sanitizer.h"
7 #include "platform/utils.h" 7 #include "platform/utils.h"
8 8
9 #include "vm/allocation.h" 9 #include "vm/allocation.h"
10 #include "vm/atomic.h" 10 #include "vm/atomic.h"
(...skipping 28 matching lines...) Expand all
39 DEFINE_FLAG(bool, profile_vm, true, 39 DEFINE_FLAG(bool, profile_vm, true,
40 "Always collect native stack traces."); 40 "Always collect native stack traces.");
41 #else 41 #else
42 DEFINE_FLAG(bool, profile_vm, false, 42 DEFINE_FLAG(bool, profile_vm, false,
43 "Always collect native stack traces."); 43 "Always collect native stack traces.");
44 #endif 44 #endif
45 45
46 bool Profiler::initialized_ = false; 46 bool Profiler::initialized_ = false;
47 SampleBuffer* Profiler::sample_buffer_ = NULL; 47 SampleBuffer* Profiler::sample_buffer_ = NULL;
48 48
49 static intptr_t NumberOfFramesToCollect() {
50 if (FLAG_profile_depth <= 0) {
51 return 0;
52 }
53 // Subtract to reserve space for the possible missing frame.
54 return FLAG_profile_depth - 1;
55 }
56
49 void Profiler::InitOnce() { 57 void Profiler::InitOnce() {
50 // Place some sane restrictions on user controlled flags. 58 // Place some sane restrictions on user controlled flags.
51 SetSamplePeriod(FLAG_profile_period); 59 SetSamplePeriod(FLAG_profile_period);
52 SetSampleDepth(FLAG_profile_depth); 60 SetSampleDepth(FLAG_profile_depth);
53 Sample::InitOnce(); 61 Sample::InitOnce();
54 if (!FLAG_profile) { 62 if (!FLAG_profile) {
55 return; 63 return;
56 } 64 }
57 ASSERT(!initialized_); 65 ASSERT(!initialized_);
58 sample_buffer_ = new SampleBuffer(); 66 sample_buffer_ = new SampleBuffer();
59 NativeSymbolResolver::InitOnce(); 67 NativeSymbolResolver::InitOnce();
60 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period); 68 ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period);
61 ThreadInterrupter::Startup(); 69 ThreadInterrupter::Startup();
62 initialized_ = true; 70 initialized_ = true;
63 } 71 }
64 72
65 73
66 void Profiler::Shutdown() { 74 void Profiler::Shutdown() {
67 if (!FLAG_profile) { 75 if (!FLAG_profile) {
68 return; 76 return;
69 } 77 }
70 ASSERT(initialized_); 78 ASSERT(initialized_);
71 ThreadInterrupter::Shutdown(); 79 ThreadInterrupter::Shutdown();
72 NativeSymbolResolver::ShutdownOnce(); 80 NativeSymbolResolver::ShutdownOnce();
73 } 81 }
74 82
75 83
76 void Profiler::SetSampleDepth(intptr_t depth) { 84 void Profiler::SetSampleDepth(intptr_t depth) {
77 const int kMinimumDepth = 1; 85 const int kMinimumDepth = 2;
78 const int kMaximumDepth = 255; 86 const int kMaximumDepth = 255;
79 if (depth < kMinimumDepth) { 87 if (depth < kMinimumDepth) {
80 FLAG_profile_depth = kMinimumDepth; 88 FLAG_profile_depth = kMinimumDepth;
81 } else if (depth > kMaximumDepth) { 89 } else if (depth > kMaximumDepth) {
82 FLAG_profile_depth = kMaximumDepth; 90 FLAG_profile_depth = kMaximumDepth;
83 } else { 91 } else {
84 FLAG_profile_depth = depth; 92 FLAG_profile_depth = depth;
85 } 93 }
86 } 94 }
87 95
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 ThreadInterrupter::WakeUp(); 214 ThreadInterrupter::WakeUp();
207 } 215 }
208 } 216 }
209 217
210 218
211 intptr_t Sample::pcs_length_ = 0; 219 intptr_t Sample::pcs_length_ = 0;
212 intptr_t Sample::instance_size_ = 0; 220 intptr_t Sample::instance_size_ = 0;
213 221
214 222
215 void Sample::InitOnce() { 223 void Sample::InitOnce() {
216 ASSERT(FLAG_profile_depth >= 1); 224 ASSERT(FLAG_profile_depth >= 2);
217 pcs_length_ = FLAG_profile_depth; 225 pcs_length_ = FLAG_profile_depth;
218 instance_size_ = 226 instance_size_ =
219 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT. 227 sizeof(Sample) + (sizeof(uword) * pcs_length_); // NOLINT.
220 } 228 }
221 229
222 230
223 uword* Sample::GetPCArray() const { 231 uword* Sample::GetPCArray() const {
224 return reinterpret_cast<uword*>( 232 return reinterpret_cast<uword*>(
225 reinterpret_cast<uintptr_t>(this) + sizeof(*this)); 233 reinterpret_cast<uintptr_t>(this) + sizeof(*this));
226 } 234 }
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 // Mark that this sample was collected from an exit frame. 593 // Mark that this sample was collected from an exit frame.
586 sample_->set_exit_frame_sample(true); 594 sample_->set_exit_frame_sample(true);
587 } 595 }
588 596
589 void walk() { 597 void walk() {
590 intptr_t frame_index = 0; 598 intptr_t frame_index = 0;
591 StackFrame* frame = frame_iterator_.NextFrame(); 599 StackFrame* frame = frame_iterator_.NextFrame();
592 while (frame != NULL) { 600 while (frame != NULL) {
593 sample_->SetAt(frame_index, frame->pc()); 601 sample_->SetAt(frame_index, frame->pc());
594 frame_index++; 602 frame_index++;
595 if (frame_index >= FLAG_profile_depth) { 603 if (frame_index >= NumberOfFramesToCollect()) {
604 sample_->set_truncated_trace(true);
596 break; 605 break;
597 } 606 }
598 frame = frame_iterator_.NextFrame(); 607 frame = frame_iterator_.NextFrame();
599 } 608 }
600 } 609 }
601 610
602 private: 611 private:
603 Sample* sample_; 612 Sample* sample_;
604 DartFrameIterator frame_iterator_; 613 DartFrameIterator frame_iterator_;
605 }; 614 };
(...skipping 29 matching lines...) Expand all
635 if (StubCode::InInvocationStubForIsolate(isolate_, return_pc)) { 644 if (StubCode::InInvocationStubForIsolate(isolate_, return_pc)) {
636 // Edge case- we have called out from the Invocation Stub but have not 645 // Edge case- we have called out from the Invocation Stub but have not
637 // created the stack frame of the callee. Attempt to locate the exit 646 // created the stack frame of the callee. Attempt to locate the exit
638 // frame before walking the stack. 647 // frame before walking the stack.
639 if (!NextExit() || !ValidFramePointer()) { 648 if (!NextExit() || !ValidFramePointer()) {
640 // Nothing to sample. 649 // Nothing to sample.
641 sample_->set_ignore_sample(true); 650 sample_->set_ignore_sample(true);
642 return; 651 return;
643 } 652 }
644 } 653 }
645 for (int i = 0; i < FLAG_profile_depth; i++) { 654 for (int i = 0; i < NumberOfFramesToCollect(); i++) {
646 sample_->SetAt(i, reinterpret_cast<uword>(pc_)); 655 sample_->SetAt(i, reinterpret_cast<uword>(pc_));
647 if (!Next()) { 656 if (!Next()) {
648 return; 657 return;
649 } 658 }
650 } 659 }
660 sample_->set_truncated_trace(true);
651 } 661 }
652 662
653 private: 663 private:
654 bool Next() { 664 bool Next() {
655 if (!ValidFramePointer()) { 665 if (!ValidFramePointer()) {
656 return false; 666 return false;
657 } 667 }
658 if (StubCode::InInvocationStubForIsolate(isolate_, 668 if (StubCode::InInvocationStubForIsolate(isolate_,
659 reinterpret_cast<uword>(pc_))) { 669 reinterpret_cast<uword>(pc_))) {
660 // In invocation stub. 670 // In invocation stub.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 if (gap >= kMaxStep) { 803 if (gap >= kMaxStep) {
794 // Gap between frame pointer and stack pointer is 804 // Gap between frame pointer and stack pointer is
795 // too large. 805 // too large.
796 return; 806 return;
797 } 807 }
798 808
799 if (!ValidFramePointer(fp)) { 809 if (!ValidFramePointer(fp)) {
800 return; 810 return;
801 } 811 }
802 812
803 for (int i = 0; i < FLAG_profile_depth; i++) { 813 for (int i = 0; i < NumberOfFramesToCollect(); i++) {
804 sample_->SetAt(i, reinterpret_cast<uword>(pc)); 814 sample_->SetAt(i, reinterpret_cast<uword>(pc));
805 815
806 pc = CallerPC(fp); 816 pc = CallerPC(fp);
807 previous_fp = fp; 817 previous_fp = fp;
808 fp = CallerFP(fp); 818 fp = CallerFP(fp);
809 819
810 if (fp == NULL) { 820 if (fp == NULL) {
811 return; 821 return;
812 } 822 }
813 823
814 if (fp <= previous_fp) { 824 if (fp <= previous_fp) {
815 // Frame pointer did not move to a higher address. 825 // Frame pointer did not move to a higher address.
816 return; 826 return;
817 } 827 }
818 828
819 gap = fp - previous_fp; 829 gap = fp - previous_fp;
820 if (gap >= kMaxStep) { 830 if (gap >= kMaxStep) {
821 // Frame pointer step is too large. 831 // Frame pointer step is too large.
822 return; 832 return;
823 } 833 }
824 834
825 if (!ValidFramePointer(fp)) { 835 if (!ValidFramePointer(fp)) {
826 // Frame pointer is outside of isolate stack boundary. 836 // Frame pointer is outside of isolate stack boundary.
827 return; 837 return;
828 } 838 }
829 839
830 // Move the lower bound up. 840 // Move the lower bound up.
831 lower_bound_ = reinterpret_cast<uword>(fp); 841 lower_bound_ = reinterpret_cast<uword>(fp);
832 } 842 }
843
844 sample_->set_truncated_trace(true);
833 } 845 }
834 846
835 private: 847 private:
836 uword* CallerPC(uword* fp) const { 848 uword* CallerPC(uword* fp) const {
837 ASSERT(fp != NULL); 849 ASSERT(fp != NULL);
838 uword* caller_pc_ptr = fp + kSavedCallerPcSlotFromFp; 850 uword* caller_pc_ptr = fp + kSavedCallerPcSlotFromFp;
839 // This may actually be uninitialized, by design (see class comment above). 851 // This may actually be uninitialized, by design (see class comment above).
840 MSAN_UNPOISON(caller_pc_ptr, kWordSize); 852 MSAN_UNPOISON(caller_pc_ptr, kWordSize);
841 ASAN_UNPOISON(caller_pc_ptr, kWordSize); 853 ASAN_UNPOISON(caller_pc_ptr, kWordSize);
842 return reinterpret_cast<uword*>(*caller_pc_ptr); 854 return reinterpret_cast<uword*>(*caller_pc_ptr);
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 state.fp, 1072 state.fp,
1061 sp); 1073 sp);
1062 stackWalker.walk(); 1074 stackWalker.walk();
1063 } else { 1075 } else {
1064 sample->set_vm_tag(VMTag::kEmbedderTagId); 1076 sample->set_vm_tag(VMTag::kEmbedderTagId);
1065 sample->SetAt(0, state.pc); 1077 sample->SetAt(0, state.pc);
1066 } 1078 }
1067 } 1079 }
1068 1080
1069 } // namespace dart 1081 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler.h ('k') | runtime/vm/profiler_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698