| 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 #ifndef VM_PROFILER_H_ | 5 #ifndef VM_PROFILER_H_ |
| 6 #define VM_PROFILER_H_ | 6 #define 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/object.h" |
| 13 #include "vm/tags.h" | 14 #include "vm/tags.h" |
| 14 #include "vm/thread_interrupter.h" | 15 #include "vm/thread_interrupter.h" |
| 15 | 16 |
| 16 // Profiler sampling and stack walking support. | 17 // Profiler sampling and stack walking support. |
| 17 // NOTE: For service related code, see profile_service.h. | 18 // NOTE: For service related code, see profile_service.h. |
| 18 | 19 |
| 19 namespace dart { | 20 namespace dart { |
| 20 | 21 |
| 21 // Forward declarations. | 22 // Forward declarations. |
| 22 class ProcessedSample; | 23 class ProcessedSample; |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 uword state_; | 349 uword state_; |
| 349 intptr_t continuation_index_; | 350 intptr_t continuation_index_; |
| 350 | 351 |
| 351 /* There are a variable number of words that follow, the words hold the | 352 /* There are a variable number of words that follow, the words hold the |
| 352 * sampled pc values. Access via GetPCArray() */ | 353 * sampled pc values. Access via GetPCArray() */ |
| 353 | 354 |
| 354 DISALLOW_COPY_AND_ASSIGN(Sample); | 355 DISALLOW_COPY_AND_ASSIGN(Sample); |
| 355 }; | 356 }; |
| 356 | 357 |
| 357 | 358 |
| 359 // A Code object descriptor. |
| 360 class CodeDescriptor : public ZoneAllocated { |
| 361 public: |
| 362 explicit CodeDescriptor(const Code& code); |
| 363 |
| 364 uword Entry() const; |
| 365 |
| 366 uword Size() const; |
| 367 |
| 368 int64_t CompileTimestamp() const; |
| 369 |
| 370 RawCode* code() const { |
| 371 return code_.raw(); |
| 372 } |
| 373 |
| 374 const char* Name() const { |
| 375 const String& name = String::Handle(code_.Name()); |
| 376 return name.ToCString(); |
| 377 } |
| 378 |
| 379 bool Contains(uword pc) const { |
| 380 uword end = Entry() + Size(); |
| 381 return (pc >= Entry()) && (pc < end); |
| 382 } |
| 383 |
| 384 static int Compare(CodeDescriptor* const* a, |
| 385 CodeDescriptor* const* b) { |
| 386 ASSERT(a != NULL); |
| 387 ASSERT(b != NULL); |
| 388 |
| 389 uword a_entry = (*a)->Entry(); |
| 390 uword b_entry = (*b)->Entry(); |
| 391 |
| 392 if (a_entry < b_entry) { |
| 393 return -1; |
| 394 } else if (a_entry > b_entry) { |
| 395 return 1; |
| 396 } else { |
| 397 return 0; |
| 398 } |
| 399 } |
| 400 |
| 401 private: |
| 402 const Code& code_; |
| 403 |
| 404 DISALLOW_COPY_AND_ASSIGN(CodeDescriptor); |
| 405 }; |
| 406 |
| 407 |
| 408 // Fast lookup of Dart code objects. |
| 409 class CodeLookupTable : public ZoneAllocated { |
| 410 public: |
| 411 explicit CodeLookupTable(Thread* thread); |
| 412 |
| 413 intptr_t length() const { |
| 414 return code_objects_.length(); |
| 415 } |
| 416 |
| 417 const CodeDescriptor* At(intptr_t index) const { |
| 418 return code_objects_.At(index); |
| 419 } |
| 420 |
| 421 const CodeDescriptor* FindCode(uword pc) const; |
| 422 |
| 423 private: |
| 424 void Build(Thread* thread); |
| 425 |
| 426 void Add(const Code& code); |
| 427 |
| 428 // Code objects sorted by entry. |
| 429 ZoneGrowableArray<CodeDescriptor*> code_objects_; |
| 430 |
| 431 friend class CodeLookupTableBuilder; |
| 432 |
| 433 DISALLOW_COPY_AND_ASSIGN(CodeLookupTable); |
| 434 }; |
| 435 |
| 436 |
| 358 // Ring buffer of Samples that is (usually) shared by many isolates. | 437 // Ring buffer of Samples that is (usually) shared by many isolates. |
| 359 class SampleBuffer { | 438 class SampleBuffer { |
| 360 public: | 439 public: |
| 361 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. | 440 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. |
| 362 | 441 |
| 363 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity); | 442 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity); |
| 364 | 443 |
| 365 ~SampleBuffer() { | 444 ~SampleBuffer() { |
| 366 if (samples_ != NULL) { | 445 if (samples_ != NULL) { |
| 367 free(samples_); | 446 free(samples_); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 continue; | 483 continue; |
| 405 } | 484 } |
| 406 visitor->IncrementVisited(); | 485 visitor->IncrementVisited(); |
| 407 visitor->VisitSample(sample); | 486 visitor->VisitSample(sample); |
| 408 } | 487 } |
| 409 } | 488 } |
| 410 | 489 |
| 411 ProcessedSampleBuffer* BuildProcessedSampleBuffer(SampleFilter* filter); | 490 ProcessedSampleBuffer* BuildProcessedSampleBuffer(SampleFilter* filter); |
| 412 | 491 |
| 413 private: | 492 private: |
| 414 ProcessedSample* BuildProcessedSample(Sample* sample); | 493 ProcessedSample* BuildProcessedSample(Sample* sample, |
| 494 const CodeLookupTable& clt); |
| 415 Sample* Next(Sample* sample); | 495 Sample* Next(Sample* sample); |
| 416 | 496 |
| 417 Sample* samples_; | 497 Sample* samples_; |
| 418 intptr_t capacity_; | 498 intptr_t capacity_; |
| 419 uintptr_t cursor_; | 499 uintptr_t cursor_; |
| 420 | 500 |
| 421 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); | 501 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); |
| 422 }; | 502 }; |
| 423 | 503 |
| 424 | 504 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 bool truncated() const { return truncated_; } | 553 bool truncated() const { return truncated_; } |
| 474 void set_truncated(bool truncated) { truncated_ = truncated; } | 554 void set_truncated(bool truncated) { truncated_ = truncated; } |
| 475 | 555 |
| 476 // Was the first frame in the stack trace executing? | 556 // Was the first frame in the stack trace executing? |
| 477 bool first_frame_executing() const { return first_frame_executing_; } | 557 bool first_frame_executing() const { return first_frame_executing_; } |
| 478 void set_first_frame_executing(bool first_frame_executing) { | 558 void set_first_frame_executing(bool first_frame_executing) { |
| 479 first_frame_executing_ = first_frame_executing; | 559 first_frame_executing_ = first_frame_executing; |
| 480 } | 560 } |
| 481 | 561 |
| 482 private: | 562 private: |
| 483 void FixupCaller(Thread* thread, | 563 void FixupCaller(const CodeLookupTable& clt, |
| 484 Isolate* vm_isolate, | |
| 485 uword pc_marker, | 564 uword pc_marker, |
| 486 uword* stack_buffer); | 565 uword* stack_buffer); |
| 487 | 566 |
| 488 void CheckForMissingDartFrame(Isolate* isolate, | 567 void CheckForMissingDartFrame(const CodeLookupTable& clt, |
| 489 Isolate* vm_isolate, | 568 const CodeDescriptor* code, |
| 490 const Code& code, | |
| 491 uword pc_marker, | 569 uword pc_marker, |
| 492 uword* stack_buffer); | 570 uword* stack_buffer); |
| 493 | 571 |
| 494 static RawCode* FindCodeForPC(Isolate* isolate, | |
| 495 Isolate* vm_isolate, | |
| 496 uword pc); | |
| 497 | |
| 498 static bool ContainedInDartCodeHeaps(Isolate* isolate, | |
| 499 Isolate* vm_isolate, | |
| 500 uword pc); | |
| 501 | |
| 502 ZoneGrowableArray<uword> pcs_; | 572 ZoneGrowableArray<uword> pcs_; |
| 503 int64_t timestamp_; | 573 int64_t timestamp_; |
| 504 uword vm_tag_; | 574 uword vm_tag_; |
| 505 uword user_tag_; | 575 uword user_tag_; |
| 506 intptr_t allocation_cid_; | 576 intptr_t allocation_cid_; |
| 507 bool truncated_; | 577 bool truncated_; |
| 508 bool first_frame_executing_; | 578 bool first_frame_executing_; |
| 509 | 579 |
| 510 friend class SampleBuffer; | 580 friend class SampleBuffer; |
| 511 DISALLOW_COPY_AND_ASSIGN(ProcessedSample); | 581 DISALLOW_COPY_AND_ASSIGN(ProcessedSample); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 522 } | 592 } |
| 523 | 593 |
| 524 intptr_t length() const { | 594 intptr_t length() const { |
| 525 return samples_.length(); | 595 return samples_.length(); |
| 526 } | 596 } |
| 527 | 597 |
| 528 ProcessedSample* At(intptr_t index) { | 598 ProcessedSample* At(intptr_t index) { |
| 529 return samples_.At(index); | 599 return samples_.At(index); |
| 530 } | 600 } |
| 531 | 601 |
| 602 const CodeLookupTable& code_lookup_table() const { |
| 603 return *code_lookup_table_; |
| 604 } |
| 605 |
| 532 private: | 606 private: |
| 533 ZoneGrowableArray<ProcessedSample*> samples_; | 607 ZoneGrowableArray<ProcessedSample*> samples_; |
| 608 CodeLookupTable* code_lookup_table_; |
| 534 | 609 |
| 535 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer); | 610 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer); |
| 536 }; | 611 }; |
| 537 | 612 |
| 538 } // namespace dart | 613 } // namespace dart |
| 539 | 614 |
| 540 #endif // VM_PROFILER_H_ | 615 #endif // VM_PROFILER_H_ |
| OLD | NEW |