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

Side by Side Diff: src/profile-generator.h

Issue 10353010: Split nodes and edges into separate arrays in heap profiler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 7 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 CodeMap code_map_; 439 CodeMap code_map_;
440 CodeEntry* program_entry_; 440 CodeEntry* program_entry_;
441 CodeEntry* gc_entry_; 441 CodeEntry* gc_entry_;
442 SampleRateCalculator sample_rate_calc_; 442 SampleRateCalculator sample_rate_calc_;
443 443
444 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); 444 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
445 }; 445 };
446 446
447 447
448 class HeapEntry; 448 class HeapEntry;
449 class HeapSnapshot;
449 450
450 class HeapGraphEdge BASE_EMBEDDED { 451 class HeapGraphEdge BASE_EMBEDDED {
451 public: 452 public:
452 enum Type { 453 enum Type {
453 kContextVariable = v8::HeapGraphEdge::kContextVariable, 454 kContextVariable = v8::HeapGraphEdge::kContextVariable,
454 kElement = v8::HeapGraphEdge::kElement, 455 kElement = v8::HeapGraphEdge::kElement,
455 kProperty = v8::HeapGraphEdge::kProperty, 456 kProperty = v8::HeapGraphEdge::kProperty,
456 kInternal = v8::HeapGraphEdge::kInternal, 457 kInternal = v8::HeapGraphEdge::kInternal,
457 kHidden = v8::HeapGraphEdge::kHidden, 458 kHidden = v8::HeapGraphEdge::kHidden,
458 kShortcut = v8::HeapGraphEdge::kShortcut, 459 kShortcut = v8::HeapGraphEdge::kShortcut,
459 kWeak = v8::HeapGraphEdge::kWeak 460 kWeak = v8::HeapGraphEdge::kWeak
460 }; 461 };
461 462
462 HeapGraphEdge() { } 463 HeapGraphEdge() { }
463 void Init(int child_index, Type type, const char* name, HeapEntry* to); 464 void Init(Type type, const char* name, int from, int to);
mnaganov (inactive) 2012/05/03 15:44:31 You can make 'Init' to be a constructor now. The r
alexeif 2012/05/07 11:04:35 Done.
464 void Init(int child_index, Type type, int index, HeapEntry* to); 465 void Init(Type type, int index, int from, int to);
465 void Init(int child_index, int index, HeapEntry* to); 466 void UpdateToEntry(HeapSnapshot* snapshot);
mnaganov (inactive) 2012/05/03 15:44:31 Perhaps, rename this method to "ReplaceToIndexWith
alexeif 2012/05/07 11:04:35 Done.
466 467
467 Type type() const { return static_cast<Type>(type_); } 468 Type type() const { return static_cast<Type>(type_); }
468 int index() const { 469 int index() const {
469 ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak); 470 ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak);
470 return index_; 471 return index_;
471 } 472 }
472 const char* name() const { 473 const char* name() const {
473 ASSERT(type_ == kContextVariable 474 ASSERT(type_ == kContextVariable
474 || type_ == kProperty 475 || type_ == kProperty
475 || type_ == kInternal 476 || type_ == kInternal
476 || type_ == kShortcut); 477 || type_ == kShortcut);
477 return name_; 478 return name_;
478 } 479 }
479 HeapEntry* to() const { return to_; }
480 INLINE(HeapEntry* from() const); 480 INLINE(HeapEntry* from() const);
481 HeapEntry* to() const { return to_entry_; }
481 482
482 private: 483 private:
483 int child_index_ : 29; 484 INLINE(HeapSnapshot* snapshot() const);
485
486 int from_ : 29;
484 unsigned type_ : 3; 487 unsigned type_ : 3;
485 union { 488 union {
486 int index_; 489 int index_;
487 const char* name_; 490 const char* name_;
488 }; 491 };
489 HeapEntry* to_; 492 union {
490 493 // During entries population it uses |to_| field to store index,
mnaganov (inactive) 2012/05/03 15:44:31 nit: During entries population |to_| is used for s
alexeif 2012/05/07 11:04:35 Done.
491 DISALLOW_COPY_AND_ASSIGN(HeapGraphEdge); 494 // later on it is replaced with a pointer to entry.
495 int to_;
mnaganov (inactive) 2012/05/03 15:44:31 Perhaps, call this field 'to_index_' for clarity?
alexeif 2012/05/07 11:04:35 Done.
496 HeapEntry* to_entry_;
497 };
492 }; 498 };
493 499
494 500
495 class HeapSnapshot;
496
497 // HeapEntry instances represent an entity from the heap (or a special 501 // HeapEntry instances represent an entity from the heap (or a special
498 // virtual node, e.g. root). To make heap snapshots more compact, 502 // virtual node, e.g. root).
499 // HeapEntries has a special memory layout (no Vectors or Lists used):
500 //
501 // +-----------------+
502 // HeapEntry
503 // +-----------------+
504 // HeapGraphEdge |
505 // ... } children_count
506 // HeapGraphEdge |
507 // +-----------------+
508 // HeapGraphEdge* |
509 // ... } retainers_count
510 // HeapGraphEdge* |
511 // +-----------------+
512 //
513 // In a HeapSnapshot, all entries are hand-allocated in a continuous array
514 // of raw bytes.
515 //
516 class HeapEntry BASE_EMBEDDED { 503 class HeapEntry BASE_EMBEDDED {
517 public: 504 public:
518 enum Type { 505 enum Type {
519 kHidden = v8::HeapGraphNode::kHidden, 506 kHidden = v8::HeapGraphNode::kHidden,
520 kArray = v8::HeapGraphNode::kArray, 507 kArray = v8::HeapGraphNode::kArray,
521 kString = v8::HeapGraphNode::kString, 508 kString = v8::HeapGraphNode::kString,
522 kObject = v8::HeapGraphNode::kObject, 509 kObject = v8::HeapGraphNode::kObject,
523 kCode = v8::HeapGraphNode::kCode, 510 kCode = v8::HeapGraphNode::kCode,
524 kClosure = v8::HeapGraphNode::kClosure, 511 kClosure = v8::HeapGraphNode::kClosure,
525 kRegExp = v8::HeapGraphNode::kRegExp, 512 kRegExp = v8::HeapGraphNode::kRegExp,
526 kHeapNumber = v8::HeapGraphNode::kHeapNumber, 513 kHeapNumber = v8::HeapGraphNode::kHeapNumber,
527 kNative = v8::HeapGraphNode::kNative, 514 kNative = v8::HeapGraphNode::kNative,
528 kSynthetic = v8::HeapGraphNode::kSynthetic 515 kSynthetic = v8::HeapGraphNode::kSynthetic
529 }; 516 };
530 517
531 HeapEntry() { } 518 HeapEntry() { }
532 void Init(HeapSnapshot* snapshot, 519 void Init(HeapSnapshot* snapshot,
mnaganov (inactive) 2012/05/03 15:44:31 Also can be converted into a constructor.
alexeif 2012/05/07 11:04:35 Done.
533 Type type, 520 Type type,
534 const char* name, 521 const char* name,
535 SnapshotObjectId id, 522 SnapshotObjectId id,
536 int self_size, 523 int self_size);
537 int children_count,
538 int retainers_count);
539 524
540 HeapSnapshot* snapshot() { return snapshot_; } 525 HeapSnapshot* snapshot() { return snapshot_; }
541 Type type() { return static_cast<Type>(type_); } 526 Type type() { return static_cast<Type>(type_); }
542 const char* name() { return name_; } 527 const char* name() { return name_; }
543 void set_name(const char* name) { name_ = name; } 528 void set_name(const char* name) { name_ = name; }
544 inline SnapshotObjectId id() { return id_; } 529 inline SnapshotObjectId id() { return id_; }
545 int self_size() { return self_size_; } 530 int self_size() { return self_size_; }
546 int retained_size() { return retained_size_; } 531 int retained_size() { return retained_size_; }
547 void add_retained_size(int size) { retained_size_ += size; } 532 void add_retained_size(int size) { retained_size_ += size; }
548 void set_retained_size(int value) { retained_size_ = value; } 533 void set_retained_size(int size) { retained_size_ = size; }
549 int ordered_index() { return ordered_index_; } 534 INLINE(int index() const);
550 void set_ordered_index(int value) { ordered_index_ = value; } 535 int postorder_index() { return postorder_index_; }
551 int entry_index() { return entry_index_; } 536 void set_postorder_index(int value) { postorder_index_ = value; }
552 void set_entry_index(int value) { entry_index_ = value; } 537 int children_count() const { return children_count_; }
553 538 int set_children_index(int index) {
mnaganov (inactive) 2012/05/03 15:44:31 This function isn't a trivial one-liner, so it nee
alexeif 2012/05/07 11:04:35 Done.
554 Vector<HeapGraphEdge> children() { 539 children_index_ = index;
555 return Vector<HeapGraphEdge>(children_arr(), children_count_); } 540 int next_index = index + children_count_;
541 children_count_ = 0;
542 return next_index;
543 }
544 int set_retainers_index(int index) {
mnaganov (inactive) 2012/05/03 15:44:31 ditto
alexeif 2012/05/07 11:04:35 Done.
545 retainers_index_ = index;
546 int next_index = index + retainers_count_;
547 retainers_count_ = 0;
548 return next_index;
549 }
550 void add_child(HeapGraphEdge* edge) {
551 children_arr()[children_count_++] = edge;
552 }
553 void add_retainer(HeapGraphEdge* edge) {
554 retainers_arr()[retainers_count_++] = edge;
555 }
556 Vector<HeapGraphEdge*> children() {
557 return Vector<HeapGraphEdge*>(children_arr(), children_count_); }
556 Vector<HeapGraphEdge*> retainers() { 558 Vector<HeapGraphEdge*> retainers() {
557 return Vector<HeapGraphEdge*>(retainers_arr(), retainers_count_); } 559 return Vector<HeapGraphEdge*>(retainers_arr(), retainers_count_); }
558 HeapEntry* dominator() { return dominator_; } 560 INLINE(HeapEntry* dominator() const);
559 void set_dominator(HeapEntry* entry) { 561 void set_dominator(HeapEntry* entry) {
560 ASSERT(entry != NULL); 562 ASSERT(entry != NULL);
561 dominator_ = entry; 563 dominator_ = entry->index();
562 } 564 }
563 void clear_paint() { painted_ = false; } 565 void clear_paint() { painted_ = false; }
564 bool painted() { return painted_; } 566 bool painted() { return painted_; }
565 void paint() { painted_ = true; } 567 void paint() { painted_ = true; }
566 bool user_reachable() { return user_reachable_; } 568 bool user_reachable() { return user_reachable_; }
567 void set_user_reachable() { user_reachable_ = true; } 569 void set_user_reachable() { user_reachable_ = true; }
568 570
569 void SetIndexedReference(HeapGraphEdge::Type type, 571 void SetIndexedReference(
570 int child_index, 572 HeapGraphEdge::Type type, int index, HeapEntry* entry);
571 int index, 573 void SetNamedReference(
572 HeapEntry* entry, 574 HeapGraphEdge::Type type, const char* name, HeapEntry* entry);
573 int retainer_index);
574 void SetNamedReference(HeapGraphEdge::Type type,
575 int child_index,
576 const char* name,
577 HeapEntry* entry,
578 int retainer_index);
579 void SetUnidirElementReference(int child_index, int index, HeapEntry* entry);
580
581 size_t EntrySize() {
582 return EntriesSize(1, children_count_, retainers_count_);
583 }
584 575
585 void Print( 576 void Print(
586 const char* prefix, const char* edge_name, int max_depth, int indent); 577 const char* prefix, const char* edge_name, int max_depth, int indent);
587 578
588 Handle<HeapObject> GetHeapObject(); 579 Handle<HeapObject> GetHeapObject();
589 580
590 static size_t EntriesSize(int entries_count,
591 int children_count,
592 int retainers_count);
593
594 private: 581 private:
595 HeapGraphEdge* children_arr() { 582 INLINE(HeapGraphEdge** children_arr());
596 return reinterpret_cast<HeapGraphEdge*>(this + 1); 583 INLINE(HeapGraphEdge** retainers_arr());
597 }
598 HeapGraphEdge** retainers_arr() {
599 return reinterpret_cast<HeapGraphEdge**>(children_arr() + children_count_);
600 }
601 const char* TypeAsString(); 584 const char* TypeAsString();
602 585
586 HeapSnapshot* snapshot_;
mnaganov (inactive) 2012/05/03 15:44:31 Are you sure this reordering doesn't affect entry
alexeif 2012/05/07 11:04:35 Done.
587 const char* name_;
588 SnapshotObjectId id_;
603 unsigned painted_: 1; 589 unsigned painted_: 1;
604 unsigned user_reachable_: 1; 590 unsigned user_reachable_: 1;
591 int dominator_: 30;
605 unsigned type_: 4; 592 unsigned type_: 4;
606 int children_count_: 26; 593 int retainers_count_: 28;
607 int retainers_count_; 594 int retainers_index_;
595 int children_count_;
596 int children_index_;
608 int self_size_; 597 int self_size_;
609 union { 598 union {
610 int ordered_index_; // Used during dominator tree building. 599 int postorder_index_; // Used during dominator tree building.
611 int retained_size_; // At that moment, there is no retained size yet. 600 int retained_size_; // At that moment, there is no retained size yet.
612 }; 601 };
613 int entry_index_;
614 SnapshotObjectId id_;
615 HeapEntry* dominator_;
616 HeapSnapshot* snapshot_;
617 const char* name_;
618
619 DISALLOW_COPY_AND_ASSIGN(HeapEntry);
620 }; 602 };
621 603
622 604
623 class HeapSnapshotsCollection; 605 class HeapSnapshotsCollection;
624 606
625 // HeapSnapshot represents a single heap snapshot. It is stored in 607 // HeapSnapshot represents a single heap snapshot. It is stored in
626 // HeapSnapshotsCollection, which is also a factory for 608 // HeapSnapshotsCollection, which is also a factory for
627 // HeapSnapshots. All HeapSnapshots share strings copied from JS heap 609 // HeapSnapshots. All HeapSnapshots share strings copied from JS heap
628 // to be able to return them even if they were collected. 610 // to be able to return them even if they were collected.
629 // HeapSnapshotGenerator fills in a HeapSnapshot. 611 // HeapSnapshotGenerator fills in a HeapSnapshot.
630 class HeapSnapshot { 612 class HeapSnapshot {
631 public: 613 public:
632 enum Type { 614 enum Type {
633 kFull = v8::HeapSnapshot::kFull 615 kFull = v8::HeapSnapshot::kFull
634 }; 616 };
635 617
636 HeapSnapshot(HeapSnapshotsCollection* collection, 618 HeapSnapshot(HeapSnapshotsCollection* collection,
637 Type type, 619 Type type,
638 const char* title, 620 const char* title,
639 unsigned uid); 621 unsigned uid);
640 ~HeapSnapshot();
641 void Delete(); 622 void Delete();
642 623
643 HeapSnapshotsCollection* collection() { return collection_; } 624 HeapSnapshotsCollection* collection() { return collection_; }
644 Type type() { return type_; } 625 Type type() { return type_; }
645 const char* title() { return title_; } 626 const char* title() { return title_; }
646 unsigned uid() { return uid_; } 627 unsigned uid() { return uid_; }
647 HeapEntry* root() { return root_entry_; } 628 size_t RawSnapshotSize() const;
648 HeapEntry* gc_roots() { return gc_roots_entry_; } 629 HeapEntry* root() { return &entries_[root_entry_]; }
649 HeapEntry* natives_root() { return natives_root_entry_; } 630 HeapEntry* gc_roots() { return &entries_[gc_roots_entry_]; }
650 HeapEntry* gc_subroot(int index) { return gc_subroot_entries_[index]; } 631 HeapEntry* natives_root() { return &entries_[natives_root_entry_]; }
651 List<HeapEntry*>* entries() { return &entries_; } 632 HeapEntry* gc_subroot(int index) {
652 size_t raw_entries_size() { return raw_entries_size_; } 633 return &entries_[gc_subroot_entries_[index]];
653 int number_of_edges() { return number_of_edges_; } 634 }
635 List<HeapEntry>& entries() { return entries_; }
636 List<HeapGraphEdge>& edges() { return edges_; }
637 List<HeapGraphEdge*>& children() { return children_; }
638 List<HeapGraphEdge*>& retainers() { return retainers_; }
654 void RememberLastJSObjectId(); 639 void RememberLastJSObjectId();
655 SnapshotObjectId max_snapshot_js_object_id() const { 640 SnapshotObjectId max_snapshot_js_object_id() const {
656 return max_snapshot_js_object_id_; 641 return max_snapshot_js_object_id_;
657 } 642 }
658 643
659 void AllocateEntries(
660 int entries_count, int children_count, int retainers_count);
661 HeapEntry* AddEntry(HeapEntry::Type type, 644 HeapEntry* AddEntry(HeapEntry::Type type,
662 const char* name, 645 const char* name,
663 SnapshotObjectId id, 646 SnapshotObjectId id,
664 int size, 647 int size);
665 int children_count, 648 HeapEntry* AddRootEntry();
666 int retainers_count); 649 HeapEntry* AddGcRootsEntry();
667 HeapEntry* AddRootEntry(int children_count); 650 HeapEntry* AddGcSubrootEntry(int tag);
668 HeapEntry* AddGcRootsEntry(int children_count, int retainers_count); 651 HeapEntry* AddNativesRootEntry();
669 HeapEntry* AddGcSubrootEntry(int tag,
670 int children_count,
671 int retainers_count);
672 HeapEntry* AddNativesRootEntry(int children_count, int retainers_count);
673 void ClearPaint(); 652 void ClearPaint();
674 HeapEntry* GetEntryById(SnapshotObjectId id); 653 HeapEntry* GetEntryById(SnapshotObjectId id);
675 List<HeapEntry*>* GetSortedEntriesList(); 654 List<HeapEntry*>* GetSortedEntriesList();
676 void SetDominatorsToSelf(); 655 void SetDominatorsToSelf();
656 void FillChildrenAndRetainers();
677 657
678 void Print(int max_depth); 658 void Print(int max_depth);
679 void PrintEntriesSize(); 659 void PrintEntriesSize();
680 660
681 private: 661 private:
682 HeapEntry* GetNextEntryToInit();
683
684 HeapSnapshotsCollection* collection_; 662 HeapSnapshotsCollection* collection_;
685 Type type_; 663 Type type_;
686 const char* title_; 664 const char* title_;
687 unsigned uid_; 665 unsigned uid_;
688 HeapEntry* root_entry_; 666 int root_entry_;
689 HeapEntry* gc_roots_entry_; 667 int gc_roots_entry_;
690 HeapEntry* natives_root_entry_; 668 int natives_root_entry_;
691 HeapEntry* gc_subroot_entries_[VisitorSynchronization::kNumberOfSyncTags]; 669 int gc_subroot_entries_[VisitorSynchronization::kNumberOfSyncTags];
692 char* raw_entries_; 670 List<HeapEntry> entries_;
693 List<HeapEntry*> entries_; 671 List<HeapGraphEdge> edges_;
672 List<HeapGraphEdge*> children_;
673 List<HeapGraphEdge*> retainers_;
694 List<HeapEntry*> sorted_entries_; 674 List<HeapEntry*> sorted_entries_;
695 size_t raw_entries_size_;
696 int number_of_edges_;
697 SnapshotObjectId max_snapshot_js_object_id_; 675 SnapshotObjectId max_snapshot_js_object_id_;
698 676
699 friend class HeapSnapshotTester; 677 friend class HeapSnapshotTester;
700 678
701 DISALLOW_COPY_AND_ASSIGN(HeapSnapshot); 679 DISALLOW_COPY_AND_ASSIGN(HeapSnapshot);
702 }; 680 };
703 681
704 682
705 class HeapObjectsMap { 683 class HeapObjectsMap {
706 public: 684 public:
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 799
822 // A typedef for referencing anything that can be snapshotted living 800 // A typedef for referencing anything that can be snapshotted living
823 // in any kind of heap memory. 801 // in any kind of heap memory.
824 typedef void* HeapThing; 802 typedef void* HeapThing;
825 803
826 804
827 // An interface that creates HeapEntries by HeapThings. 805 // An interface that creates HeapEntries by HeapThings.
828 class HeapEntriesAllocator { 806 class HeapEntriesAllocator {
829 public: 807 public:
830 virtual ~HeapEntriesAllocator() { } 808 virtual ~HeapEntriesAllocator() { }
831 virtual HeapEntry* AllocateEntry( 809 virtual HeapEntry* AllocateEntry(HeapThing ptr) = 0;
832 HeapThing ptr, int children_count, int retainers_count) = 0;
833 }; 810 };
834 811
835 812
836 // The HeapEntriesMap instance is used to track a mapping between 813 // The HeapEntriesMap instance is used to track a mapping between
837 // real heap objects and their representations in heap snapshots. 814 // real heap objects and their representations in heap snapshots.
838 class HeapEntriesMap { 815 class HeapEntriesMap {
839 public: 816 public:
840 HeapEntriesMap(); 817 HeapEntriesMap();
841 ~HeapEntriesMap();
842 818
843 void AllocateEntries(HeapThing root_object); 819 int Map(HeapThing thing);
844 HeapEntry* Map(HeapThing thing); 820 void Pair(HeapThing thing, int entry);
845 void Pair(HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry);
846 void CountReference(HeapThing from, HeapThing to,
847 int* prev_children_count = NULL,
848 int* prev_retainers_count = NULL);
849
850 int entries_count() { return entries_count_; }
851 int total_children_count() { return total_children_count_; }
852 int total_retainers_count() { return total_retainers_count_; }
853
854 static HeapEntry* const kHeapEntryPlaceholder;
855 821
856 private: 822 private:
857 struct EntryInfo {
858 EntryInfo(HeapEntry* entry, HeapEntriesAllocator* allocator)
859 : entry(entry),
860 allocator(allocator),
861 children_count(0),
862 retainers_count(0) {
863 }
864 HeapEntry* entry;
865 HeapEntriesAllocator* allocator;
866 int children_count;
867 int retainers_count;
868 };
869
870 static inline void AllocateHeapEntryForMapEntry(HashMap::Entry* map_entry);
871
872 static uint32_t Hash(HeapThing thing) { 823 static uint32_t Hash(HeapThing thing) {
873 return ComputeIntegerHash( 824 return ComputeIntegerHash(
874 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)), 825 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)),
875 v8::internal::kZeroHashSeed); 826 v8::internal::kZeroHashSeed);
876 } 827 }
877 static bool HeapThingsMatch(HeapThing key1, HeapThing key2) { 828 static bool HeapThingsMatch(HeapThing key1, HeapThing key2) {
878 return key1 == key2; 829 return key1 == key2;
879 } 830 }
880 831
881 HashMap entries_; 832 HashMap entries_;
882 int entries_count_;
883 int total_children_count_;
884 int total_retainers_count_;
885 833
886 friend class HeapObjectsSet; 834 friend class HeapObjectsSet;
887 835
888 DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); 836 DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap);
889 }; 837 };
890 838
891 839
892 class HeapObjectsSet { 840 class HeapObjectsSet {
893 public: 841 public:
894 HeapObjectsSet(); 842 HeapObjectsSet();
(...skipping 14 matching lines...) Expand all
909 // An interface used to populate a snapshot with nodes and edges. 857 // An interface used to populate a snapshot with nodes and edges.
910 class SnapshotFillerInterface { 858 class SnapshotFillerInterface {
911 public: 859 public:
912 virtual ~SnapshotFillerInterface() { } 860 virtual ~SnapshotFillerInterface() { }
913 virtual HeapEntry* AddEntry(HeapThing ptr, 861 virtual HeapEntry* AddEntry(HeapThing ptr,
914 HeapEntriesAllocator* allocator) = 0; 862 HeapEntriesAllocator* allocator) = 0;
915 virtual HeapEntry* FindEntry(HeapThing ptr) = 0; 863 virtual HeapEntry* FindEntry(HeapThing ptr) = 0;
916 virtual HeapEntry* FindOrAddEntry(HeapThing ptr, 864 virtual HeapEntry* FindOrAddEntry(HeapThing ptr,
917 HeapEntriesAllocator* allocator) = 0; 865 HeapEntriesAllocator* allocator) = 0;
918 virtual void SetIndexedReference(HeapGraphEdge::Type type, 866 virtual void SetIndexedReference(HeapGraphEdge::Type type,
919 HeapThing parent_ptr, 867 int parent_entry,
920 HeapEntry* parent_entry,
921 int index, 868 int index,
922 HeapThing child_ptr,
923 HeapEntry* child_entry) = 0; 869 HeapEntry* child_entry) = 0;
924 virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, 870 virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
925 HeapThing parent_ptr, 871 int parent_entry,
926 HeapEntry* parent_entry,
927 HeapThing child_ptr,
928 HeapEntry* child_entry) = 0; 872 HeapEntry* child_entry) = 0;
929 virtual void SetNamedReference(HeapGraphEdge::Type type, 873 virtual void SetNamedReference(HeapGraphEdge::Type type,
930 HeapThing parent_ptr, 874 int parent_entry,
931 HeapEntry* parent_entry,
932 const char* reference_name, 875 const char* reference_name,
933 HeapThing child_ptr,
934 HeapEntry* child_entry) = 0; 876 HeapEntry* child_entry) = 0;
935 virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type, 877 virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
936 HeapThing parent_ptr, 878 int parent_entry,
937 HeapEntry* parent_entry,
938 HeapThing child_ptr,
939 HeapEntry* child_entry) = 0; 879 HeapEntry* child_entry) = 0;
940 }; 880 };
941 881
942 882
943 class SnapshottingProgressReportingInterface { 883 class SnapshottingProgressReportingInterface {
944 public: 884 public:
945 virtual ~SnapshottingProgressReportingInterface() { } 885 virtual ~SnapshottingProgressReportingInterface() { }
946 virtual void ProgressStep() = 0; 886 virtual void ProgressStep() = 0;
947 virtual bool ProgressReport(bool force) = 0; 887 virtual bool ProgressReport(bool force) = 0;
948 }; 888 };
949 889
950 890
951 // An implementation of V8 heap graph extractor. 891 // An implementation of V8 heap graph extractor.
952 class V8HeapExplorer : public HeapEntriesAllocator { 892 class V8HeapExplorer : public HeapEntriesAllocator {
953 public: 893 public:
954 V8HeapExplorer(HeapSnapshot* snapshot, 894 V8HeapExplorer(HeapSnapshot* snapshot,
955 SnapshottingProgressReportingInterface* progress); 895 SnapshottingProgressReportingInterface* progress);
956 virtual ~V8HeapExplorer(); 896 virtual ~V8HeapExplorer();
957 virtual HeapEntry* AllocateEntry( 897 virtual HeapEntry* AllocateEntry(HeapThing ptr);
958 HeapThing ptr, int children_count, int retainers_count);
959 void AddRootEntries(SnapshotFillerInterface* filler); 898 void AddRootEntries(SnapshotFillerInterface* filler);
960 int EstimateObjectsCount(HeapIterator* iterator); 899 int EstimateObjectsCount(HeapIterator* iterator);
961 bool IterateAndExtractReferences(SnapshotFillerInterface* filler); 900 bool IterateAndExtractReferences(SnapshotFillerInterface* filler);
962 bool IterateAndSetObjectNames(SnapshotFillerInterface* filler); 901 bool IterateAndSetObjectNames(SnapshotFillerInterface* filler);
963 void TagGlobalObjects(); 902 void TagGlobalObjects();
964 903
965 static String* GetConstructorName(JSObject* object); 904 static String* GetConstructorName(JSObject* object);
966 905
967 static HeapObject* const kInternalRootObject; 906 static HeapObject* const kInternalRootObject;
968 907
969 private: 908 private:
970 HeapEntry* AddEntry( 909 HeapEntry* AddEntry(HeapObject* object);
971 HeapObject* object, int children_count, int retainers_count);
972 HeapEntry* AddEntry(HeapObject* object, 910 HeapEntry* AddEntry(HeapObject* object,
973 HeapEntry::Type type, 911 HeapEntry::Type type,
974 const char* name, 912 const char* name);
975 int children_count,
976 int retainers_count);
977 const char* GetSystemEntryName(HeapObject* object); 913 const char* GetSystemEntryName(HeapObject* object);
978 914
979 void ExtractReferences(HeapObject* obj); 915 void ExtractReferences(HeapObject* obj);
980 void ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy); 916 void ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy);
981 void ExtractJSObjectReferences(HeapEntry* entry, JSObject* js_obj); 917 void ExtractJSObjectReferences(int entry, JSObject* js_obj);
982 void ExtractStringReferences(HeapEntry* entry, String* obj); 918 void ExtractStringReferences(int entry, String* obj);
983 void ExtractContextReferences(HeapEntry* entry, Context* context); 919 void ExtractContextReferences(int entry, Context* context);
984 void ExtractMapReferences(HeapEntry* entry, Map* map); 920 void ExtractMapReferences(int entry, Map* map);
985 void ExtractSharedFunctionInfoReferences(HeapEntry* entry, 921 void ExtractSharedFunctionInfoReferences(int entry,
986 SharedFunctionInfo* shared); 922 SharedFunctionInfo* shared);
987 void ExtractScriptReferences(HeapEntry* entry, Script* script); 923 void ExtractScriptReferences(int entry, Script* script);
988 void ExtractCodeCacheReferences(HeapEntry* entry, CodeCache* code_cache); 924 void ExtractCodeCacheReferences(int entry, CodeCache* code_cache);
989 void ExtractCodeReferences(HeapEntry* entry, Code* code); 925 void ExtractCodeReferences(int entry, Code* code);
990 void ExtractJSGlobalPropertyCellReferences(HeapEntry* entry, 926 void ExtractJSGlobalPropertyCellReferences(int entry,
991 JSGlobalPropertyCell* cell); 927 JSGlobalPropertyCell* cell);
992 void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry); 928 void ExtractClosureReferences(JSObject* js_obj, int entry);
993 void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); 929 void ExtractPropertyReferences(JSObject* js_obj, int entry);
994 void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); 930 void ExtractElementReferences(JSObject* js_obj, int entry);
995 void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry); 931 void ExtractInternalReferences(JSObject* js_obj, int entry);
996 bool IsEssentialObject(Object* object); 932 bool IsEssentialObject(Object* object);
997 void SetClosureReference(HeapObject* parent_obj, 933 void SetClosureReference(HeapObject* parent_obj,
998 HeapEntry* parent, 934 int parent,
999 String* reference_name, 935 String* reference_name,
1000 Object* child); 936 Object* child);
1001 void SetNativeBindReference(HeapObject* parent_obj, 937 void SetNativeBindReference(HeapObject* parent_obj,
1002 HeapEntry* parent, 938 int parent,
1003 const char* reference_name, 939 const char* reference_name,
1004 Object* child); 940 Object* child);
1005 void SetElementReference(HeapObject* parent_obj, 941 void SetElementReference(HeapObject* parent_obj,
1006 HeapEntry* parent, 942 int parent,
1007 int index, 943 int index,
1008 Object* child); 944 Object* child);
1009 void SetInternalReference(HeapObject* parent_obj, 945 void SetInternalReference(HeapObject* parent_obj,
1010 HeapEntry* parent, 946 int parent,
1011 const char* reference_name, 947 const char* reference_name,
1012 Object* child, 948 Object* child,
1013 int field_offset = -1); 949 int field_offset = -1);
1014 void SetInternalReference(HeapObject* parent_obj, 950 void SetInternalReference(HeapObject* parent_obj,
1015 HeapEntry* parent, 951 int parent,
1016 int index, 952 int index,
1017 Object* child, 953 Object* child,
1018 int field_offset = -1); 954 int field_offset = -1);
1019 void SetHiddenReference(HeapObject* parent_obj, 955 void SetHiddenReference(HeapObject* parent_obj,
1020 HeapEntry* parent, 956 int parent,
1021 int index, 957 int index,
1022 Object* child); 958 Object* child);
1023 void SetWeakReference(HeapObject* parent_obj, 959 void SetWeakReference(HeapObject* parent_obj,
1024 HeapEntry* parent_entry, 960 int parent,
1025 int index, 961 int index,
1026 Object* child_obj, 962 Object* child_obj,
1027 int field_offset); 963 int field_offset);
1028 void SetPropertyReference(HeapObject* parent_obj, 964 void SetPropertyReference(HeapObject* parent_obj,
1029 HeapEntry* parent, 965 int parent,
1030 String* reference_name, 966 String* reference_name,
1031 Object* child, 967 Object* child,
1032 const char* name_format_string = NULL, 968 const char* name_format_string = NULL,
1033 int field_offset = -1); 969 int field_offset = -1);
1034 void SetPropertyShortcutReference(HeapObject* parent_obj, 970 void SetPropertyShortcutReference(HeapObject* parent_obj,
1035 HeapEntry* parent, 971 int parent,
1036 String* reference_name, 972 String* reference_name,
1037 Object* child); 973 Object* child);
1038 void SetUserGlobalReference(Object* window); 974 void SetUserGlobalReference(Object* user_global);
1039 void SetRootGcRootsReference(); 975 void SetRootGcRootsReference();
1040 void SetGcRootsReference(VisitorSynchronization::SyncTag tag); 976 void SetGcRootsReference(VisitorSynchronization::SyncTag tag);
1041 void SetGcSubrootReference( 977 void SetGcSubrootReference(
1042 VisitorSynchronization::SyncTag tag, bool is_weak, Object* child); 978 VisitorSynchronization::SyncTag tag, bool is_weak, Object* child);
1043 const char* GetStrongGcSubrootName(Object* object); 979 const char* GetStrongGcSubrootName(Object* object);
1044 void SetObjectName(HeapObject* object); 980 void SetObjectName(HeapObject* object);
1045 void TagObject(Object* obj, const char* tag); 981 void TagObject(Object* obj, const char* tag);
1046 982
1047 HeapEntry* GetEntry(Object* obj); 983 HeapEntry* GetEntry(Object* obj);
1048 984
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { 1068 class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
1133 public: 1069 public:
1134 HeapSnapshotGenerator(HeapSnapshot* snapshot, 1070 HeapSnapshotGenerator(HeapSnapshot* snapshot,
1135 v8::ActivityControl* control); 1071 v8::ActivityControl* control);
1136 bool GenerateSnapshot(); 1072 bool GenerateSnapshot();
1137 1073
1138 private: 1074 private:
1139 bool BuildDominatorTree(const Vector<HeapEntry*>& entries, 1075 bool BuildDominatorTree(const Vector<HeapEntry*>& entries,
1140 Vector<int>* dominators); 1076 Vector<int>* dominators);
1141 bool CalculateRetainedSizes(); 1077 bool CalculateRetainedSizes();
1142 bool CountEntriesAndReferences();
1143 bool FillReferences(); 1078 bool FillReferences();
1144 void FillPostorderIndexes(Vector<HeapEntry*>* entries); 1079 void FillPostorderIndexes(Vector<HeapEntry*>* entries);
1145 bool IsUserGlobalReference(const HeapGraphEdge& edge); 1080 bool IsUserGlobalReference(const HeapGraphEdge* edge);
1146 void MarkUserReachableObjects(); 1081 void MarkUserReachableObjects();
1147 void ProgressStep(); 1082 void ProgressStep();
1148 bool ProgressReport(bool force = false); 1083 bool ProgressReport(bool force = false);
1149 bool SetEntriesDominators(); 1084 bool SetEntriesDominators();
1150 void SetProgressTotal(int iterations_count); 1085 void SetProgressTotal(int iterations_count);
1151 1086
1152 HeapSnapshot* snapshot_; 1087 HeapSnapshot* snapshot_;
1153 v8::ActivityControl* control_; 1088 v8::ActivityControl* control_;
1154 V8HeapExplorer v8_heap_explorer_; 1089 V8HeapExplorer v8_heap_explorer_;
1155 NativeObjectsExplorer dom_explorer_; 1090 NativeObjectsExplorer dom_explorer_;
(...skipping 23 matching lines...) Expand all
1179 INLINE(static bool ObjectsMatch(void* key1, void* key2)) { 1114 INLINE(static bool ObjectsMatch(void* key1, void* key2)) {
1180 return key1 == key2; 1115 return key1 == key2;
1181 } 1116 }
1182 1117
1183 INLINE(static uint32_t ObjectHash(const void* key)) { 1118 INLINE(static uint32_t ObjectHash(const void* key)) {
1184 return ComputeIntegerHash( 1119 return ComputeIntegerHash(
1185 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)), 1120 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)),
1186 v8::internal::kZeroHashSeed); 1121 v8::internal::kZeroHashSeed);
1187 } 1122 }
1188 1123
1189 void CalculateNodeIndexes(const List<HeapEntry*>& nodes);
1190 HeapSnapshot* CreateFakeSnapshot(); 1124 HeapSnapshot* CreateFakeSnapshot();
1191 int GetStringId(const char* s); 1125 int GetStringId(const char* s);
1126 int entry_index(HeapEntry* e) { return e->index() * kNodeFieldsCount; }
1192 void SerializeEdge(HeapGraphEdge* edge, bool first_edge); 1127 void SerializeEdge(HeapGraphEdge* edge, bool first_edge);
1193 void SerializeEdges(const List<HeapEntry*>& nodes); 1128 void SerializeEdges(const List<HeapEntry>& nodes);
1194 void SerializeImpl(); 1129 void SerializeImpl();
1195 void SerializeNode(HeapEntry* entry, int edges_index); 1130 void SerializeNode(HeapEntry* entry, int edges_index);
1196 void SerializeNodes(const List<HeapEntry*>& nodes); 1131 void SerializeNodes(const List<HeapEntry>& nodes);
1197 void SerializeSnapshot(); 1132 void SerializeSnapshot();
1198 void SerializeString(const unsigned char* s); 1133 void SerializeString(const unsigned char* s);
1199 void SerializeStrings(); 1134 void SerializeStrings();
1200 void SortHashMap(HashMap* map, List<HashMap::Entry*>* sorted_entries); 1135 void SortHashMap(HashMap* map, List<HashMap::Entry*>* sorted_entries);
1201 1136
1202 static const int kMaxSerializableSnapshotRawSize; 1137 // type, name|index, to_node.
1138 static const int kEdgeFieldsCount = 3;
mnaganov (inactive) 2012/05/03 15:44:31 I would suggest providing a storage for this const
alexeif 2012/05/07 11:04:35 Done.
1139 // type, name, id, self_size, retained_size, dominator, children_index.
1140 static const int kNodeFieldsCount = 7;
mnaganov (inactive) 2012/05/03 15:44:31 ditto
alexeif 2012/05/07 11:04:35 Done.
1203 1141
1204 HeapSnapshot* snapshot_; 1142 HeapSnapshot* snapshot_;
1205 HashMap strings_; 1143 HashMap strings_;
1206 int next_node_id_; 1144 int next_node_id_;
1207 int next_string_id_; 1145 int next_string_id_;
1208 OutputStreamWriter* writer_; 1146 OutputStreamWriter* writer_;
1209 1147
1210 friend class HeapSnapshotJSONSerializerEnumerator; 1148 friend class HeapSnapshotJSONSerializerEnumerator;
1211 friend class HeapSnapshotJSONSerializerIterator; 1149 friend class HeapSnapshotJSONSerializerIterator;
1212 1150
1213 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer); 1151 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer);
1214 }; 1152 };
1215 1153
1216 } } // namespace v8::internal 1154 } } // namespace v8::internal
1217 1155
1218 #endif // V8_PROFILE_GENERATOR_H_ 1156 #endif // V8_PROFILE_GENERATOR_H_
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/profile-generator.cc » ('j') | src/profile-generator.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698