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

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

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

Powered by Google App Engine
This is Rietveld 408576698