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

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

Issue 2680213002: Updated MallocHooks to collect stack traces when memory is allocated. (Closed)
Patch Set: Updated MallocHooks to collect stack traces when memory is allocated. Created 3 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
« no previous file with comments | « runtime/vm/os_win.cc ('k') | runtime/vm/profiler.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 #ifndef RUNTIME_VM_PROFILER_H_ 5 #ifndef RUNTIME_VM_PROFILER_H_
6 #define RUNTIME_VM_PROFILER_H_ 6 #define RUNTIME_VM_PROFILER_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/bitfield.h" 9 #include "vm/bitfield.h"
10 #include "vm/code_observers.h" 10 #include "vm/code_observers.h"
(...skipping 23 matching lines...) Expand all
34 int64_t bail_out_check_isolate; 34 int64_t bail_out_check_isolate;
35 // Count of single frame sampling reasons: 35 // Count of single frame sampling reasons:
36 int64_t single_frame_sample_deoptimizing; 36 int64_t single_frame_sample_deoptimizing;
37 int64_t single_frame_sample_register_check; 37 int64_t single_frame_sample_register_check;
38 int64_t single_frame_sample_get_and_validate_stack_bounds; 38 int64_t single_frame_sample_get_and_validate_stack_bounds;
39 // Count of stack walkers used: 39 // Count of stack walkers used:
40 int64_t stack_walker_native; 40 int64_t stack_walker_native;
41 int64_t stack_walker_dart_exit; 41 int64_t stack_walker_dart_exit;
42 int64_t stack_walker_dart; 42 int64_t stack_walker_dart;
43 int64_t stack_walker_none; 43 int64_t stack_walker_none;
44 // Count of failed checks:
45 int64_t failure_native_allocation_sample;
44 }; 46 };
45 47
46 48
47 class Profiler : public AllStatic { 49 class Profiler : public AllStatic {
48 public: 50 public:
49 static void InitOnce(); 51 static void InitOnce();
50 static void Shutdown(); 52 static void Shutdown();
51 53
52 static void SetSampleDepth(intptr_t depth); 54 static void SetSampleDepth(intptr_t depth);
53 static void SetSamplePeriod(intptr_t period); 55 static void SetSamplePeriod(intptr_t period);
54 56
55 static SampleBuffer* sample_buffer() { return sample_buffer_; } 57 static SampleBuffer* sample_buffer() { return sample_buffer_; }
56 58
57 static void DumpStackTrace(void* context); 59 static void DumpStackTrace(void* context);
58 static void DumpStackTrace(); 60 static void DumpStackTrace();
59 61
60 static void SampleAllocation(Thread* thread, intptr_t cid); 62 static void SampleAllocation(Thread* thread, intptr_t cid);
63 static Sample* SampleNativeAllocation(intptr_t skip_count);
61 64
62 // SampleThread is called from inside the signal handler and hence it is very 65 // SampleThread is called from inside the signal handler and hence it is very
63 // critical that the implementation of SampleThread does not do any of the 66 // critical that the implementation of SampleThread does not do any of the
64 // following: 67 // following:
65 // * Accessing TLS -- Because on Windows the callback will be running in a 68 // * Accessing TLS -- Because on Windows the callback will be running in a
66 // different thread. 69 // different thread.
67 // * Allocating memory -- Because this takes locks which may already be 70 // * Allocating memory -- Because this takes locks which may already be
68 // held, resulting in a dead lock. 71 // held, resulting in a dead lock.
69 // * Taking a lock -- See above. 72 // * Taking a lock -- See above.
70 static void SampleThread(Thread* thread, const InterruptedThreadState& state); 73 static void SampleThread(Thread* thread, const InterruptedThreadState& state);
(...skipping 13 matching lines...) Expand all
84 static SampleBuffer* sample_buffer_; 87 static SampleBuffer* sample_buffer_;
85 88
86 static ProfilerCounters counters_; 89 static ProfilerCounters counters_;
87 90
88 friend class Thread; 91 friend class Thread;
89 }; 92 };
90 93
91 94
92 class SampleVisitor : public ValueObject { 95 class SampleVisitor : public ValueObject {
93 public: 96 public:
94 explicit SampleVisitor(Isolate* isolate) : isolate_(isolate), visited_(0) {} 97 explicit SampleVisitor(Dart_Port port) : port_(port), visited_(0) {}
95 virtual ~SampleVisitor() {} 98 virtual ~SampleVisitor() {}
96 99
97 virtual void VisitSample(Sample* sample) = 0; 100 virtual void VisitSample(Sample* sample) = 0;
98 101
99 intptr_t visited() const { return visited_; } 102 intptr_t visited() const { return visited_; }
100 103
101 void IncrementVisited() { visited_++; } 104 void IncrementVisited() { visited_++; }
102 105
103 Isolate* isolate() const { return isolate_; } 106 Dart_Port port() const { return port_; }
104 107
105 private: 108 private:
106 Isolate* isolate_; 109 Dart_Port port_;
107 intptr_t visited_; 110 intptr_t visited_;
108 111
109 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); 112 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor);
110 }; 113 };
111 114
112 115
113 class SampleFilter : public ValueObject { 116 class SampleFilter : public ValueObject {
114 public: 117 public:
115 SampleFilter(Isolate* isolate, 118 SampleFilter(Dart_Port port,
116 intptr_t thread_task_mask, 119 intptr_t thread_task_mask,
117 int64_t time_origin_micros, 120 int64_t time_origin_micros,
118 int64_t time_extent_micros) 121 int64_t time_extent_micros)
119 : isolate_(isolate), 122 : port_(port),
120 thread_task_mask_(thread_task_mask), 123 thread_task_mask_(thread_task_mask),
121 time_origin_micros_(time_origin_micros), 124 time_origin_micros_(time_origin_micros),
122 time_extent_micros_(time_extent_micros) { 125 time_extent_micros_(time_extent_micros) {
123 ASSERT(thread_task_mask != 0); 126 ASSERT(thread_task_mask != 0);
124 ASSERT(time_origin_micros_ >= -1); 127 ASSERT(time_origin_micros_ >= -1);
125 ASSERT(time_extent_micros_ >= -1); 128 ASSERT(time_extent_micros_ >= -1);
126 } 129 }
127 virtual ~SampleFilter() {} 130 virtual ~SampleFilter() {}
128 131
129 // Override this function. 132 // Override this function.
130 // Return |true| if |sample| passes the filter. 133 // Return |true| if |sample| passes the filter.
131 virtual bool FilterSample(Sample* sample) { return true; } 134 virtual bool FilterSample(Sample* sample) { return true; }
132 135
133 Isolate* isolate() const { return isolate_; } 136 Dart_Port port() const { return port_; }
134 137
135 // Returns |true| if |sample| passes the time filter. 138 // Returns |true| if |sample| passes the time filter.
136 bool TimeFilterSample(Sample* sample); 139 bool TimeFilterSample(Sample* sample);
137 140
138 // Returns |true| if |sample| passes the thread task filter. 141 // Returns |true| if |sample| passes the thread task filter.
139 bool TaskFilterSample(Sample* sample); 142 bool TaskFilterSample(Sample* sample);
140 143
141 private: 144 private:
142 Isolate* isolate_; 145 Dart_Port port_;
143 intptr_t thread_task_mask_; 146 intptr_t thread_task_mask_;
144 int64_t time_origin_micros_; 147 int64_t time_origin_micros_;
145 int64_t time_extent_micros_; 148 int64_t time_extent_micros_;
146 }; 149 };
147 150
148 151
149 class ClearProfileVisitor : public SampleVisitor { 152 class ClearProfileVisitor : public SampleVisitor {
150 public: 153 public:
151 explicit ClearProfileVisitor(Isolate* isolate); 154 explicit ClearProfileVisitor(Isolate* isolate);
152 155
153 virtual void VisitSample(Sample* sample); 156 virtual void VisitSample(Sample* sample);
154 }; 157 };
155 158
156 159
157 // Each Sample holds a stack trace from an isolate. 160 // Each Sample holds a stack trace from an isolate.
158 class Sample { 161 class Sample {
159 public: 162 public:
160 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { 163 void Init(Dart_Port port, int64_t timestamp, ThreadId tid) {
161 Clear(); 164 Clear();
162 timestamp_ = timestamp; 165 timestamp_ = timestamp;
163 tid_ = tid; 166 tid_ = tid;
164 isolate_ = isolate; 167 port_ = port;
165 } 168 }
166 169
167 // Isolate sample was taken from. 170 Dart_Port port() const { return port_; }
168 Isolate* isolate() const { return isolate_; }
169 171
170 // Thread sample was taken on. 172 // Thread sample was taken on.
171 ThreadId tid() const { return tid_; } 173 ThreadId tid() const { return tid_; }
172 174
173 void Clear() { 175 void Clear() {
174 isolate_ = NULL; 176 port_ = ILLEGAL_PORT;
175 pc_marker_ = 0; 177 pc_marker_ = 0;
176 for (intptr_t i = 0; i < kStackBufferSizeInWords; i++) { 178 for (intptr_t i = 0; i < kStackBufferSizeInWords; i++) {
177 stack_buffer_[i] = 0; 179 stack_buffer_[i] = 0;
178 } 180 }
179 vm_tag_ = VMTag::kInvalidTagId; 181 vm_tag_ = VMTag::kInvalidTagId;
180 user_tag_ = UserTags::kDefaultUserTag; 182 user_tag_ = UserTags::kDefaultUserTag;
181 lr_ = 0; 183 lr_ = 0;
182 metadata_ = 0; 184 metadata_ = 0;
183 state_ = 0; 185 state_ = 0;
184 continuation_index_ = -1; 186 continuation_index_ = -1;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 } 263 }
262 264
263 bool is_allocation_sample() const { 265 bool is_allocation_sample() const {
264 return ClassAllocationSampleBit::decode(state_); 266 return ClassAllocationSampleBit::decode(state_);
265 } 267 }
266 268
267 void set_is_allocation_sample(bool allocation_sample) { 269 void set_is_allocation_sample(bool allocation_sample) {
268 state_ = ClassAllocationSampleBit::update(allocation_sample, state_); 270 state_ = ClassAllocationSampleBit::update(allocation_sample, state_);
269 } 271 }
270 272
273 bool is_native_allocation_sample() const {
274 return NativeAllocationSampleBit::decode(state_);
275 }
276
277 void set_is_native_allocation_sample(bool native_allocation_sample) {
278 state_ =
279 NativeAllocationSampleBit::update(native_allocation_sample, state_);
280 }
281
271 Thread::TaskKind thread_task() const { return ThreadTaskBit::decode(state_); } 282 Thread::TaskKind thread_task() const { return ThreadTaskBit::decode(state_); }
272 283
273 void set_thread_task(Thread::TaskKind task) { 284 void set_thread_task(Thread::TaskKind task) {
274 state_ = ThreadTaskBit::update(task, state_); 285 state_ = ThreadTaskBit::update(task, state_);
275 } 286 }
276 287
277 bool is_continuation_sample() const { 288 bool is_continuation_sample() const {
278 return ContinuationSampleBit::decode(state_); 289 return ContinuationSampleBit::decode(state_);
279 } 290 }
280 291
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 enum StateBits { 335 enum StateBits {
325 kHeadSampleBit = 0, 336 kHeadSampleBit = 0,
326 kLeafFrameIsDartBit = 1, 337 kLeafFrameIsDartBit = 1,
327 kIgnoreBit = 2, 338 kIgnoreBit = 2,
328 kExitFrameBit = 3, 339 kExitFrameBit = 3,
329 kMissingFrameInsertedBit = 4, 340 kMissingFrameInsertedBit = 4,
330 kTruncatedTraceBit = 5, 341 kTruncatedTraceBit = 5,
331 kClassAllocationSampleBit = 6, 342 kClassAllocationSampleBit = 6,
332 kContinuationSampleBit = 7, 343 kContinuationSampleBit = 7,
333 kThreadTaskBit = 8, // 5 bits. 344 kThreadTaskBit = 8, // 5 bits.
334 kNextFreeBit = 13, 345 kNativeAllocationSampleBit = 13,
346 kNextFreeBit = 14,
335 }; 347 };
336 class HeadSampleBit : public BitField<uword, bool, kHeadSampleBit, 1> {}; 348 class HeadSampleBit : public BitField<uword, bool, kHeadSampleBit, 1> {};
337 class LeafFrameIsDart : public BitField<uword, bool, kLeafFrameIsDartBit, 1> { 349 class LeafFrameIsDart : public BitField<uword, bool, kLeafFrameIsDartBit, 1> {
338 }; 350 };
339 class IgnoreBit : public BitField<uword, bool, kIgnoreBit, 1> {}; 351 class IgnoreBit : public BitField<uword, bool, kIgnoreBit, 1> {};
340 class ExitFrameBit : public BitField<uword, bool, kExitFrameBit, 1> {}; 352 class ExitFrameBit : public BitField<uword, bool, kExitFrameBit, 1> {};
341 class MissingFrameInsertedBit 353 class MissingFrameInsertedBit
342 : public BitField<uword, bool, kMissingFrameInsertedBit, 1> {}; 354 : public BitField<uword, bool, kMissingFrameInsertedBit, 1> {};
343 class TruncatedTraceBit 355 class TruncatedTraceBit
344 : public BitField<uword, bool, kTruncatedTraceBit, 1> {}; 356 : public BitField<uword, bool, kTruncatedTraceBit, 1> {};
345 class ClassAllocationSampleBit 357 class ClassAllocationSampleBit
346 : public BitField<uword, bool, kClassAllocationSampleBit, 1> {}; 358 : public BitField<uword, bool, kClassAllocationSampleBit, 1> {};
347 class ContinuationSampleBit 359 class ContinuationSampleBit
348 : public BitField<uword, bool, kContinuationSampleBit, 1> {}; 360 : public BitField<uword, bool, kContinuationSampleBit, 1> {};
349 class ThreadTaskBit 361 class ThreadTaskBit
350 : public BitField<uword, Thread::TaskKind, kThreadTaskBit, 5> {}; 362 : public BitField<uword, Thread::TaskKind, kThreadTaskBit, 5> {};
363 class NativeAllocationSampleBit
364 : public BitField<uword, bool, kNativeAllocationSampleBit, 1> {};
351 365
352 int64_t timestamp_; 366 int64_t timestamp_;
353 ThreadId tid_; 367 ThreadId tid_;
354 Isolate* isolate_; 368 Dart_Port port_;
355 uword pc_marker_; 369 uword pc_marker_;
356 uword stack_buffer_[kStackBufferSizeInWords]; 370 uword stack_buffer_[kStackBufferSizeInWords];
357 uword vm_tag_; 371 uword vm_tag_;
358 uword user_tag_; 372 uword user_tag_;
359 uword metadata_; 373 uword metadata_;
360 uword lr_; 374 uword lr_;
361 uword state_; 375 uword state_;
362 intptr_t continuation_index_; 376 intptr_t continuation_index_;
363 377
364 /* There are a variable number of words that follow, the words hold the 378 /* There are a variable number of words that follow, the words hold the
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 for (intptr_t i = 0; i < length; i++) { 481 for (intptr_t i = 0; i < length; i++) {
468 Sample* sample = At(i); 482 Sample* sample = At(i);
469 if (!sample->head_sample()) { 483 if (!sample->head_sample()) {
470 // An inner sample in a chain of samples. 484 // An inner sample in a chain of samples.
471 continue; 485 continue;
472 } 486 }
473 if (sample->ignore_sample()) { 487 if (sample->ignore_sample()) {
474 // Bad sample. 488 // Bad sample.
475 continue; 489 continue;
476 } 490 }
477 if (sample->isolate() != visitor->isolate()) { 491 if (sample->port() != visitor->port()) {
478 // Another isolate. 492 // Another isolate.
479 continue; 493 continue;
480 } 494 }
481 if (sample->timestamp() == 0) { 495 if (sample->timestamp() == 0) {
482 // Empty. 496 // Empty.
483 continue; 497 continue;
484 } 498 }
485 if (sample->At(0) == 0) { 499 if (sample->At(0) == 0) {
486 // No frames. 500 // No frames.
487 continue; 501 continue;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 private: 623 private:
610 ZoneGrowableArray<ProcessedSample*> samples_; 624 ZoneGrowableArray<ProcessedSample*> samples_;
611 CodeLookupTable* code_lookup_table_; 625 CodeLookupTable* code_lookup_table_;
612 626
613 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer); 627 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer);
614 }; 628 };
615 629
616 } // namespace dart 630 } // namespace dart
617 631
618 #endif // RUNTIME_VM_PROFILER_H_ 632 #endif // RUNTIME_VM_PROFILER_H_
OLDNEW
« no previous file with comments | « runtime/vm/os_win.cc ('k') | runtime/vm/profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698