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

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

Issue 2771293003: Resubmission of native memory allocation info surfacing in Observatory. Fixed crashing tests and st… (Closed)
Patch Set: Added page to Observatory to display native memory allocation information. Created 3 years, 8 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/malloc_hooks_x64.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"
11 #include "vm/globals.h" 11 #include "vm/globals.h"
12 #include "vm/growable_array.h" 12 #include "vm/growable_array.h"
13 #include "vm/malloc_hooks.h"
14 #include "vm/native_symbol.h"
13 #include "vm/object.h" 15 #include "vm/object.h"
14 #include "vm/tags.h" 16 #include "vm/tags.h"
15 #include "vm/thread_interrupter.h" 17 #include "vm/thread_interrupter.h"
16 18
17 // Profiler sampling and stack walking support. 19 // Profiler sampling and stack walking support.
18 // NOTE: For service related code, see profile_service.h. 20 // NOTE: For service related code, see profile_service.h.
19 21
20 namespace dart { 22 namespace dart {
21 23
22 // Forward declarations. 24 // Forward declarations.
(...skipping 30 matching lines...) Expand all
53 55
54 static void SetSampleDepth(intptr_t depth); 56 static void SetSampleDepth(intptr_t depth);
55 static void SetSamplePeriod(intptr_t period); 57 static void SetSamplePeriod(intptr_t period);
56 58
57 static SampleBuffer* sample_buffer() { return sample_buffer_; } 59 static SampleBuffer* sample_buffer() { return sample_buffer_; }
58 60
59 static void DumpStackTrace(void* context); 61 static void DumpStackTrace(void* context);
60 static void DumpStackTrace(); 62 static void DumpStackTrace();
61 63
62 static void SampleAllocation(Thread* thread, intptr_t cid); 64 static void SampleAllocation(Thread* thread, intptr_t cid);
63 static Sample* SampleNativeAllocation(intptr_t skip_count); 65 static Sample* SampleNativeAllocation(intptr_t skip_count,
66 uword address,
67 uintptr_t allocation_size);
64 68
65 // SampleThread is called from inside the signal handler and hence it is very 69 // SampleThread is called from inside the signal handler and hence it is very
66 // critical that the implementation of SampleThread does not do any of the 70 // critical that the implementation of SampleThread does not do any of the
67 // following: 71 // following:
68 // * Accessing TLS -- Because on Windows the callback will be running in a 72 // * Accessing TLS -- Because on Windows the callback will be running in a
69 // different thread. 73 // different thread.
70 // * Allocating memory -- Because this takes locks which may already be 74 // * Allocating memory -- Because this takes locks which may already be
71 // held, resulting in a dead lock. 75 // held, resulting in a dead lock.
72 // * Taking a lock -- See above. 76 // * Taking a lock -- See above.
73 static void SampleThread(Thread* thread, const InterruptedThreadState& state); 77 static void SampleThread(Thread* thread, const InterruptedThreadState& state);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 virtual bool FilterSample(Sample* sample) { return true; } 138 virtual bool FilterSample(Sample* sample) { return true; }
135 139
136 Dart_Port port() const { return port_; } 140 Dart_Port port() const { return port_; }
137 141
138 // Returns |true| if |sample| passes the time filter. 142 // Returns |true| if |sample| passes the time filter.
139 bool TimeFilterSample(Sample* sample); 143 bool TimeFilterSample(Sample* sample);
140 144
141 // Returns |true| if |sample| passes the thread task filter. 145 // Returns |true| if |sample| passes the thread task filter.
142 bool TaskFilterSample(Sample* sample); 146 bool TaskFilterSample(Sample* sample);
143 147
148 static const intptr_t kNoTaskFilter = -1;
149
144 private: 150 private:
145 Dart_Port port_; 151 Dart_Port port_;
146 intptr_t thread_task_mask_; 152 intptr_t thread_task_mask_;
147 int64_t time_origin_micros_; 153 int64_t time_origin_micros_;
148 int64_t time_extent_micros_; 154 int64_t time_extent_micros_;
149 }; 155 };
150 156
151 157
152 class ClearProfileVisitor : public SampleVisitor { 158 class ClearProfileVisitor : public SampleVisitor {
153 public: 159 public:
(...skipping 22 matching lines...) Expand all
176 port_ = ILLEGAL_PORT; 182 port_ = ILLEGAL_PORT;
177 pc_marker_ = 0; 183 pc_marker_ = 0;
178 for (intptr_t i = 0; i < kStackBufferSizeInWords; i++) { 184 for (intptr_t i = 0; i < kStackBufferSizeInWords; i++) {
179 stack_buffer_[i] = 0; 185 stack_buffer_[i] = 0;
180 } 186 }
181 vm_tag_ = VMTag::kInvalidTagId; 187 vm_tag_ = VMTag::kInvalidTagId;
182 user_tag_ = UserTags::kDefaultUserTag; 188 user_tag_ = UserTags::kDefaultUserTag;
183 lr_ = 0; 189 lr_ = 0;
184 metadata_ = 0; 190 metadata_ = 0;
185 state_ = 0; 191 state_ = 0;
192 native_allocation_address_ = 0;
193 native_allocation_size_bytes_ = 0;
186 continuation_index_ = -1; 194 continuation_index_ = -1;
187 uword* pcs = GetPCArray(); 195 uword* pcs = GetPCArray();
188 for (intptr_t i = 0; i < pcs_length_; i++) { 196 for (intptr_t i = 0; i < pcs_length_; i++) {
189 pcs[i] = 0; 197 pcs[i] = 0;
190 } 198 }
191 set_head_sample(true); 199 set_head_sample(true);
192 } 200 }
193 201
194 // Timestamp sample was taken at. 202 // Timestamp sample was taken at.
195 int64_t timestamp() const { return timestamp_; } 203 int64_t timestamp() const { return timestamp_; }
(...skipping 10 matching lines...) Expand all
206 } 214 }
207 215
208 // Set stack trace entry. 216 // Set stack trace entry.
209 void SetAt(intptr_t i, uword pc) { 217 void SetAt(intptr_t i, uword pc) {
210 ASSERT(i >= 0); 218 ASSERT(i >= 0);
211 ASSERT(i < pcs_length_); 219 ASSERT(i < pcs_length_);
212 uword* pcs = GetPCArray(); 220 uword* pcs = GetPCArray();
213 pcs[i] = pc; 221 pcs[i] = pc;
214 } 222 }
215 223
224 void DumpStackTrace() {
225 for (intptr_t i = 0; i < pcs_length_; ++i) {
226 uintptr_t start = 0;
227 uword pc = At(i);
228 char* native_symbol_name =
229 NativeSymbolResolver::LookupSymbolName(pc, &start);
230 if (native_symbol_name == NULL) {
231 OS::PrintErr(" [0x%" Pp "] Unknown symbol\n", pc);
232 } else {
233 OS::PrintErr(" [0x%" Pp "] %s\n", pc, native_symbol_name);
234 NativeSymbolResolver::FreeSymbolName(native_symbol_name);
235 }
236 }
237 }
238
216 uword vm_tag() const { return vm_tag_; } 239 uword vm_tag() const { return vm_tag_; }
217 void set_vm_tag(uword tag) { 240 void set_vm_tag(uword tag) {
218 ASSERT(tag != VMTag::kInvalidTagId); 241 ASSERT(tag != VMTag::kInvalidTagId);
219 vm_tag_ = tag; 242 vm_tag_ = tag;
220 } 243 }
221 244
222 uword user_tag() const { return user_tag_; } 245 uword user_tag() const { return user_tag_; }
223 void set_user_tag(uword tag) { user_tag_ = tag; } 246 void set_user_tag(uword tag) { user_tag_ = tag; }
224 247
225 uword pc_marker() const { return pc_marker_; } 248 uword pc_marker() const { return pc_marker_; }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 295
273 bool is_native_allocation_sample() const { 296 bool is_native_allocation_sample() const {
274 return NativeAllocationSampleBit::decode(state_); 297 return NativeAllocationSampleBit::decode(state_);
275 } 298 }
276 299
277 void set_is_native_allocation_sample(bool native_allocation_sample) { 300 void set_is_native_allocation_sample(bool native_allocation_sample) {
278 state_ = 301 state_ =
279 NativeAllocationSampleBit::update(native_allocation_sample, state_); 302 NativeAllocationSampleBit::update(native_allocation_sample, state_);
280 } 303 }
281 304
305 void set_native_allocation_address(uword address) {
306 native_allocation_address_ = address;
307 }
308
309 uword native_allocation_address() const { return native_allocation_address_; }
310
311 uintptr_t native_allocation_size_bytes() const {
312 return native_allocation_size_bytes_;
313 }
314
315 void set_native_allocation_size_bytes(uintptr_t size) {
316 native_allocation_size_bytes_ = size;
317 }
318
282 Thread::TaskKind thread_task() const { return ThreadTaskBit::decode(state_); } 319 Thread::TaskKind thread_task() const { return ThreadTaskBit::decode(state_); }
283 320
284 void set_thread_task(Thread::TaskKind task) { 321 void set_thread_task(Thread::TaskKind task) {
285 state_ = ThreadTaskBit::update(task, state_); 322 state_ = ThreadTaskBit::update(task, state_);
286 } 323 }
287 324
288 bool is_continuation_sample() const { 325 bool is_continuation_sample() const {
289 return ContinuationSampleBit::decode(state_); 326 return ContinuationSampleBit::decode(state_);
290 } 327 }
291 328
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 int64_t timestamp_; 403 int64_t timestamp_;
367 ThreadId tid_; 404 ThreadId tid_;
368 Dart_Port port_; 405 Dart_Port port_;
369 uword pc_marker_; 406 uword pc_marker_;
370 uword stack_buffer_[kStackBufferSizeInWords]; 407 uword stack_buffer_[kStackBufferSizeInWords];
371 uword vm_tag_; 408 uword vm_tag_;
372 uword user_tag_; 409 uword user_tag_;
373 uword metadata_; 410 uword metadata_;
374 uword lr_; 411 uword lr_;
375 uword state_; 412 uword state_;
413 uword native_allocation_address_;
414 uintptr_t native_allocation_size_bytes_;
376 intptr_t continuation_index_; 415 intptr_t continuation_index_;
377 416
378 /* There are a variable number of words that follow, the words hold the 417 /* There are a variable number of words that follow, the words hold the
379 * sampled pc values. Access via GetPCArray() */ 418 * sampled pc values. Access via GetPCArray() */
380 419
381 DISALLOW_COPY_AND_ASSIGN(Sample); 420 DISALLOW_COPY_AND_ASSIGN(Sample);
382 }; 421 };
383 422
384 423
424 class NativeAllocationSampleFilter : public SampleFilter {
425 public:
426 NativeAllocationSampleFilter(int64_t time_origin_micros,
427 int64_t time_extent_micros)
428 : SampleFilter(ILLEGAL_PORT,
429 SampleFilter::kNoTaskFilter,
430 time_origin_micros,
431 time_extent_micros) {}
432
433 bool FilterSample(Sample* sample) {
434 if (!sample->is_native_allocation_sample()) {
435 return false;
436 }
437 // If the sample is an allocation sample, we need to check that the
438 // memory at the address hasn't been freed, and if the address associated
439 // with the allocation has been freed and then reissued.
440 void* alloc_address =
441 reinterpret_cast<void*>(sample->native_allocation_address());
442 Sample* recorded_sample = MallocHooks::GetSample(alloc_address);
443 return (sample == recorded_sample);
444 }
445 };
446
447
385 // A Code object descriptor. 448 // A Code object descriptor.
386 class CodeDescriptor : public ZoneAllocated { 449 class CodeDescriptor : public ZoneAllocated {
387 public: 450 public:
388 explicit CodeDescriptor(const Code& code); 451 explicit CodeDescriptor(const Code& code);
389 452
390 uword Start() const; 453 uword Start() const;
391 454
392 uword Size() const; 455 uword Size() const;
393 456
394 int64_t CompileTimestamp() const; 457 int64_t CompileTimestamp() const;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 // The user tag. 620 // The user tag.
558 uword user_tag() const { return user_tag_; } 621 uword user_tag() const { return user_tag_; }
559 void set_user_tag(uword tag) { user_tag_ = tag; } 622 void set_user_tag(uword tag) { user_tag_ = tag; }
560 623
561 // The class id if this is an allocation profile sample. -1 otherwise. 624 // The class id if this is an allocation profile sample. -1 otherwise.
562 intptr_t allocation_cid() const { return allocation_cid_; } 625 intptr_t allocation_cid() const { return allocation_cid_; }
563 void set_allocation_cid(intptr_t cid) { allocation_cid_ = cid; } 626 void set_allocation_cid(intptr_t cid) { allocation_cid_ = cid; }
564 627
565 bool IsAllocationSample() const { return allocation_cid_ > 0; } 628 bool IsAllocationSample() const { return allocation_cid_ > 0; }
566 629
630 bool is_native_allocation_sample() const {
631 return native_allocation_size_bytes_ != 0;
632 }
633
634 uintptr_t native_allocation_size_bytes() const {
635 return native_allocation_size_bytes_;
636 }
637 void set_native_allocation_size_bytes(uintptr_t allocation_size) {
638 native_allocation_size_bytes_ = allocation_size;
639 }
640
567 // Was the stack trace truncated? 641 // Was the stack trace truncated?
568 bool truncated() const { return truncated_; } 642 bool truncated() const { return truncated_; }
569 void set_truncated(bool truncated) { truncated_ = truncated; } 643 void set_truncated(bool truncated) { truncated_ = truncated; }
570 644
571 // Was the first frame in the stack trace executing? 645 // Was the first frame in the stack trace executing?
572 bool first_frame_executing() const { return first_frame_executing_; } 646 bool first_frame_executing() const { return first_frame_executing_; }
573 void set_first_frame_executing(bool first_frame_executing) { 647 void set_first_frame_executing(bool first_frame_executing) {
574 first_frame_executing_ = first_frame_executing; 648 first_frame_executing_ = first_frame_executing;
575 } 649 }
576 650
(...skipping 14 matching lines...) Expand all
591 uword* stack_buffer); 665 uword* stack_buffer);
592 666
593 ZoneGrowableArray<uword> pcs_; 667 ZoneGrowableArray<uword> pcs_;
594 int64_t timestamp_; 668 int64_t timestamp_;
595 ThreadId tid_; 669 ThreadId tid_;
596 uword vm_tag_; 670 uword vm_tag_;
597 uword user_tag_; 671 uword user_tag_;
598 intptr_t allocation_cid_; 672 intptr_t allocation_cid_;
599 bool truncated_; 673 bool truncated_;
600 bool first_frame_executing_; 674 bool first_frame_executing_;
675 uword native_allocation_address_;
676 uintptr_t native_allocation_size_bytes_;
601 ProfileTrieNode* timeline_trie_; 677 ProfileTrieNode* timeline_trie_;
602 678
603 friend class SampleBuffer; 679 friend class SampleBuffer;
604 DISALLOW_COPY_AND_ASSIGN(ProcessedSample); 680 DISALLOW_COPY_AND_ASSIGN(ProcessedSample);
605 }; 681 };
606 682
607 683
608 // A collection of |ProcessedSample|s. 684 // A collection of |ProcessedSample|s.
609 class ProcessedSampleBuffer : public ZoneAllocated { 685 class ProcessedSampleBuffer : public ZoneAllocated {
610 public: 686 public:
(...skipping 12 matching lines...) Expand all
623 private: 699 private:
624 ZoneGrowableArray<ProcessedSample*> samples_; 700 ZoneGrowableArray<ProcessedSample*> samples_;
625 CodeLookupTable* code_lookup_table_; 701 CodeLookupTable* code_lookup_table_;
626 702
627 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer); 703 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer);
628 }; 704 };
629 705
630 } // namespace dart 706 } // namespace dart
631 707
632 #endif // RUNTIME_VM_PROFILER_H_ 708 #endif // RUNTIME_VM_PROFILER_H_
OLDNEW
« no previous file with comments | « runtime/vm/malloc_hooks_x64.cc ('k') | runtime/vm/profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698