Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 List<bool> token_removed_; | 54 List<bool> token_removed_; |
| 55 | 55 |
| 56 friend class TokenEnumeratorTester; | 56 friend class TokenEnumeratorTester; |
| 57 | 57 |
| 58 DISALLOW_COPY_AND_ASSIGN(TokenEnumerator); | 58 DISALLOW_COPY_AND_ASSIGN(TokenEnumerator); |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 | 61 |
| 62 // Provides a storage of strings allocated in C++ heap, to hold them | 62 // Provides a storage of strings allocated in C++ heap, to hold them |
| 63 // forever, even if they disappear from JS heap or external storage. | 63 // forever, even if they disappear from JS heap or external storage. |
| 64 class StringsStorage { | 64 class StringsStorage { |
|
yurys
2013/02/21 09:07:44
StringStorage is used by both cpu profile and heap
Yang
2013/02/21 11:35:48
Or move it to utils.h
| |
| 65 public: | 65 public: |
| 66 StringsStorage(); | 66 StringsStorage(); |
| 67 ~StringsStorage(); | 67 ~StringsStorage(); |
| 68 | 68 |
| 69 const char* GetCopy(const char* src); | 69 const char* GetCopy(const char* src); |
| 70 const char* GetFormatted(const char* format, ...); | 70 const char* GetFormatted(const char* format, ...); |
| 71 const char* GetVFormatted(const char* format, va_list args); | 71 const char* GetVFormatted(const char* format, va_list args); |
| 72 const char* GetName(String* name); | 72 const char* GetName(String* name); |
| 73 const char* GetName(int index); | 73 const char* GetName(int index); |
| 74 inline const char* GetFunctionName(String* name); | 74 inline const char* GetFunctionName(String* name); |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 CpuProfilesCollection* profiles_; | 440 CpuProfilesCollection* profiles_; |
| 441 CodeMap code_map_; | 441 CodeMap code_map_; |
| 442 CodeEntry* program_entry_; | 442 CodeEntry* program_entry_; |
| 443 CodeEntry* gc_entry_; | 443 CodeEntry* gc_entry_; |
| 444 SampleRateCalculator sample_rate_calc_; | 444 SampleRateCalculator sample_rate_calc_; |
| 445 | 445 |
| 446 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); | 446 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); |
| 447 }; | 447 }; |
| 448 | 448 |
| 449 | 449 |
| 450 class HeapEntry; | |
| 451 class HeapSnapshot; | |
| 452 | |
| 453 class HeapGraphEdge BASE_EMBEDDED { | |
| 454 public: | |
| 455 enum Type { | |
| 456 kContextVariable = v8::HeapGraphEdge::kContextVariable, | |
| 457 kElement = v8::HeapGraphEdge::kElement, | |
| 458 kProperty = v8::HeapGraphEdge::kProperty, | |
| 459 kInternal = v8::HeapGraphEdge::kInternal, | |
| 460 kHidden = v8::HeapGraphEdge::kHidden, | |
| 461 kShortcut = v8::HeapGraphEdge::kShortcut, | |
| 462 kWeak = v8::HeapGraphEdge::kWeak | |
| 463 }; | |
| 464 | |
| 465 HeapGraphEdge() { } | |
| 466 HeapGraphEdge(Type type, const char* name, int from, int to); | |
| 467 HeapGraphEdge(Type type, int index, int from, int to); | |
| 468 void ReplaceToIndexWithEntry(HeapSnapshot* snapshot); | |
| 469 | |
| 470 Type type() const { return static_cast<Type>(type_); } | |
| 471 int index() const { | |
| 472 ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak); | |
| 473 return index_; | |
| 474 } | |
| 475 const char* name() const { | |
| 476 ASSERT(type_ == kContextVariable | |
| 477 || type_ == kProperty | |
| 478 || type_ == kInternal | |
| 479 || type_ == kShortcut); | |
| 480 return name_; | |
| 481 } | |
| 482 INLINE(HeapEntry* from() const); | |
| 483 HeapEntry* to() const { return to_entry_; } | |
| 484 | |
| 485 private: | |
| 486 INLINE(HeapSnapshot* snapshot() const); | |
| 487 | |
| 488 unsigned type_ : 3; | |
| 489 int from_index_ : 29; | |
| 490 union { | |
| 491 // During entries population |to_index_| is used for storing the index, | |
| 492 // afterwards it is replaced with a pointer to the entry. | |
| 493 int to_index_; | |
| 494 HeapEntry* to_entry_; | |
| 495 }; | |
| 496 union { | |
| 497 int index_; | |
| 498 const char* name_; | |
| 499 }; | |
| 500 }; | |
| 501 | |
| 502 | |
| 503 // HeapEntry instances represent an entity from the heap (or a special | |
| 504 // virtual node, e.g. root). | |
| 505 class HeapEntry BASE_EMBEDDED { | |
| 506 public: | |
| 507 enum Type { | |
| 508 kHidden = v8::HeapGraphNode::kHidden, | |
| 509 kArray = v8::HeapGraphNode::kArray, | |
| 510 kString = v8::HeapGraphNode::kString, | |
| 511 kObject = v8::HeapGraphNode::kObject, | |
| 512 kCode = v8::HeapGraphNode::kCode, | |
| 513 kClosure = v8::HeapGraphNode::kClosure, | |
| 514 kRegExp = v8::HeapGraphNode::kRegExp, | |
| 515 kHeapNumber = v8::HeapGraphNode::kHeapNumber, | |
| 516 kNative = v8::HeapGraphNode::kNative, | |
| 517 kSynthetic = v8::HeapGraphNode::kSynthetic | |
| 518 }; | |
| 519 static const int kNoEntry; | |
| 520 | |
| 521 HeapEntry() { } | |
| 522 HeapEntry(HeapSnapshot* snapshot, | |
| 523 Type type, | |
| 524 const char* name, | |
| 525 SnapshotObjectId id, | |
| 526 int self_size); | |
| 527 | |
| 528 HeapSnapshot* snapshot() { return snapshot_; } | |
| 529 Type type() { return static_cast<Type>(type_); } | |
| 530 const char* name() { return name_; } | |
| 531 void set_name(const char* name) { name_ = name; } | |
| 532 inline SnapshotObjectId id() { return id_; } | |
| 533 int self_size() { return self_size_; } | |
| 534 INLINE(int index() const); | |
| 535 int children_count() const { return children_count_; } | |
| 536 INLINE(int set_children_index(int index)); | |
| 537 void add_child(HeapGraphEdge* edge) { | |
| 538 children_arr()[children_count_++] = edge; | |
| 539 } | |
| 540 Vector<HeapGraphEdge*> children() { | |
| 541 return Vector<HeapGraphEdge*>(children_arr(), children_count_); } | |
| 542 | |
| 543 void SetIndexedReference( | |
| 544 HeapGraphEdge::Type type, int index, HeapEntry* entry); | |
| 545 void SetNamedReference( | |
| 546 HeapGraphEdge::Type type, const char* name, HeapEntry* entry); | |
| 547 | |
| 548 void Print( | |
| 549 const char* prefix, const char* edge_name, int max_depth, int indent); | |
| 550 | |
| 551 Handle<HeapObject> GetHeapObject(); | |
| 552 | |
| 553 private: | |
| 554 INLINE(HeapGraphEdge** children_arr()); | |
| 555 const char* TypeAsString(); | |
| 556 | |
| 557 unsigned type_: 4; | |
| 558 int children_count_: 28; | |
| 559 int children_index_; | |
| 560 int self_size_; | |
| 561 SnapshotObjectId id_; | |
| 562 HeapSnapshot* snapshot_; | |
| 563 const char* name_; | |
| 564 }; | |
| 565 | |
| 566 | |
| 567 class HeapSnapshotsCollection; | |
| 568 | |
| 569 // HeapSnapshot represents a single heap snapshot. It is stored in | |
| 570 // HeapSnapshotsCollection, which is also a factory for | |
| 571 // HeapSnapshots. All HeapSnapshots share strings copied from JS heap | |
| 572 // to be able to return them even if they were collected. | |
| 573 // HeapSnapshotGenerator fills in a HeapSnapshot. | |
| 574 class HeapSnapshot { | |
| 575 public: | |
| 576 enum Type { | |
| 577 kFull = v8::HeapSnapshot::kFull | |
| 578 }; | |
| 579 | |
| 580 HeapSnapshot(HeapSnapshotsCollection* collection, | |
| 581 Type type, | |
| 582 const char* title, | |
| 583 unsigned uid); | |
| 584 void Delete(); | |
| 585 | |
| 586 HeapSnapshotsCollection* collection() { return collection_; } | |
| 587 Type type() { return type_; } | |
| 588 const char* title() { return title_; } | |
| 589 unsigned uid() { return uid_; } | |
| 590 size_t RawSnapshotSize() const; | |
| 591 HeapEntry* root() { return &entries_[root_index_]; } | |
| 592 HeapEntry* gc_roots() { return &entries_[gc_roots_index_]; } | |
| 593 HeapEntry* natives_root() { return &entries_[natives_root_index_]; } | |
| 594 HeapEntry* gc_subroot(int index) { | |
| 595 return &entries_[gc_subroot_indexes_[index]]; | |
| 596 } | |
| 597 List<HeapEntry>& entries() { return entries_; } | |
| 598 List<HeapGraphEdge>& edges() { return edges_; } | |
| 599 List<HeapGraphEdge*>& children() { return children_; } | |
| 600 void RememberLastJSObjectId(); | |
| 601 SnapshotObjectId max_snapshot_js_object_id() const { | |
| 602 return max_snapshot_js_object_id_; | |
| 603 } | |
| 604 | |
| 605 HeapEntry* AddEntry(HeapEntry::Type type, | |
| 606 const char* name, | |
| 607 SnapshotObjectId id, | |
| 608 int size); | |
| 609 HeapEntry* AddRootEntry(); | |
| 610 HeapEntry* AddGcRootsEntry(); | |
| 611 HeapEntry* AddGcSubrootEntry(int tag); | |
| 612 HeapEntry* AddNativesRootEntry(); | |
| 613 HeapEntry* GetEntryById(SnapshotObjectId id); | |
| 614 List<HeapEntry*>* GetSortedEntriesList(); | |
| 615 void FillChildren(); | |
| 616 | |
| 617 void Print(int max_depth); | |
| 618 void PrintEntriesSize(); | |
| 619 | |
| 620 private: | |
| 621 HeapSnapshotsCollection* collection_; | |
| 622 Type type_; | |
| 623 const char* title_; | |
| 624 unsigned uid_; | |
| 625 int root_index_; | |
| 626 int gc_roots_index_; | |
| 627 int natives_root_index_; | |
| 628 int gc_subroot_indexes_[VisitorSynchronization::kNumberOfSyncTags]; | |
| 629 List<HeapEntry> entries_; | |
| 630 List<HeapGraphEdge> edges_; | |
| 631 List<HeapGraphEdge*> children_; | |
| 632 List<HeapEntry*> sorted_entries_; | |
| 633 SnapshotObjectId max_snapshot_js_object_id_; | |
| 634 | |
| 635 friend class HeapSnapshotTester; | |
| 636 | |
| 637 DISALLOW_COPY_AND_ASSIGN(HeapSnapshot); | |
| 638 }; | |
| 639 | |
| 640 | |
| 641 class HeapObjectsMap { | |
| 642 public: | |
| 643 explicit HeapObjectsMap(Heap* heap); | |
| 644 | |
| 645 Heap* heap() const { return heap_; } | |
| 646 | |
| 647 void SnapshotGenerationFinished(); | |
| 648 SnapshotObjectId FindEntry(Address addr); | |
| 649 SnapshotObjectId FindOrAddEntry(Address addr, unsigned int size); | |
| 650 void MoveObject(Address from, Address to); | |
| 651 SnapshotObjectId last_assigned_id() const { | |
| 652 return next_id_ - kObjectIdStep; | |
| 653 } | |
| 654 | |
| 655 void StopHeapObjectsTracking(); | |
| 656 SnapshotObjectId PushHeapObjectsStats(OutputStream* stream); | |
| 657 size_t GetUsedMemorySize() const; | |
| 658 | |
| 659 static SnapshotObjectId GenerateId(v8::RetainedObjectInfo* info); | |
| 660 static inline SnapshotObjectId GetNthGcSubrootId(int delta); | |
| 661 | |
| 662 static const int kObjectIdStep = 2; | |
| 663 static const SnapshotObjectId kInternalRootObjectId; | |
| 664 static const SnapshotObjectId kGcRootsObjectId; | |
| 665 static const SnapshotObjectId kNativesRootObjectId; | |
| 666 static const SnapshotObjectId kGcRootsFirstSubrootId; | |
| 667 static const SnapshotObjectId kFirstAvailableObjectId; | |
| 668 | |
| 669 private: | |
| 670 struct EntryInfo { | |
| 671 EntryInfo(SnapshotObjectId id, Address addr, unsigned int size) | |
| 672 : id(id), addr(addr), size(size), accessed(true) { } | |
| 673 EntryInfo(SnapshotObjectId id, Address addr, unsigned int size, bool accessed) | |
| 674 : id(id), addr(addr), size(size), accessed(accessed) { } | |
| 675 SnapshotObjectId id; | |
| 676 Address addr; | |
| 677 unsigned int size; | |
| 678 bool accessed; | |
| 679 }; | |
| 680 struct TimeInterval { | |
| 681 explicit TimeInterval(SnapshotObjectId id) : id(id), size(0), count(0) { } | |
| 682 SnapshotObjectId id; | |
| 683 uint32_t size; | |
| 684 uint32_t count; | |
| 685 }; | |
| 686 | |
| 687 void UpdateHeapObjectsMap(); | |
| 688 void RemoveDeadEntries(); | |
| 689 | |
| 690 static bool AddressesMatch(void* key1, void* key2) { | |
| 691 return key1 == key2; | |
| 692 } | |
| 693 | |
| 694 static uint32_t AddressHash(Address addr) { | |
| 695 return ComputeIntegerHash( | |
| 696 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(addr)), | |
| 697 v8::internal::kZeroHashSeed); | |
| 698 } | |
| 699 | |
| 700 SnapshotObjectId next_id_; | |
| 701 HashMap entries_map_; | |
| 702 List<EntryInfo> entries_; | |
| 703 List<TimeInterval> time_intervals_; | |
| 704 Heap* heap_; | |
| 705 | |
| 706 DISALLOW_COPY_AND_ASSIGN(HeapObjectsMap); | |
| 707 }; | |
| 708 | |
| 709 | |
| 710 class HeapSnapshotsCollection { | |
| 711 public: | |
| 712 explicit HeapSnapshotsCollection(Heap* heap); | |
| 713 ~HeapSnapshotsCollection(); | |
| 714 | |
| 715 Heap* heap() const { return ids_.heap(); } | |
| 716 | |
| 717 bool is_tracking_objects() { return is_tracking_objects_; } | |
| 718 SnapshotObjectId PushHeapObjectsStats(OutputStream* stream) { | |
| 719 return ids_.PushHeapObjectsStats(stream); | |
| 720 } | |
| 721 void StartHeapObjectsTracking() { is_tracking_objects_ = true; } | |
| 722 void StopHeapObjectsTracking() { ids_.StopHeapObjectsTracking(); } | |
| 723 | |
| 724 HeapSnapshot* NewSnapshot( | |
| 725 HeapSnapshot::Type type, const char* name, unsigned uid); | |
| 726 void SnapshotGenerationFinished(HeapSnapshot* snapshot); | |
| 727 List<HeapSnapshot*>* snapshots() { return &snapshots_; } | |
| 728 HeapSnapshot* GetSnapshot(unsigned uid); | |
| 729 void RemoveSnapshot(HeapSnapshot* snapshot); | |
| 730 | |
| 731 StringsStorage* names() { return &names_; } | |
| 732 TokenEnumerator* token_enumerator() { return token_enumerator_; } | |
| 733 | |
| 734 SnapshotObjectId FindObjectId(Address object_addr) { | |
| 735 return ids_.FindEntry(object_addr); | |
| 736 } | |
| 737 SnapshotObjectId GetObjectId(Address object_addr, int object_size) { | |
| 738 return ids_.FindOrAddEntry(object_addr, object_size); | |
| 739 } | |
| 740 Handle<HeapObject> FindHeapObjectById(SnapshotObjectId id); | |
| 741 void ObjectMoveEvent(Address from, Address to) { ids_.MoveObject(from, to); } | |
| 742 SnapshotObjectId last_assigned_id() const { | |
| 743 return ids_.last_assigned_id(); | |
| 744 } | |
| 745 size_t GetUsedMemorySize() const; | |
| 746 | |
| 747 private: | |
| 748 INLINE(static bool HeapSnapshotsMatch(void* key1, void* key2)) { | |
| 749 return key1 == key2; | |
| 750 } | |
| 751 | |
| 752 bool is_tracking_objects_; // Whether tracking object moves is needed. | |
| 753 List<HeapSnapshot*> snapshots_; | |
| 754 // Mapping from snapshots' uids to HeapSnapshot* pointers. | |
| 755 HashMap snapshots_uids_; | |
| 756 StringsStorage names_; | |
| 757 TokenEnumerator* token_enumerator_; | |
| 758 // Mapping from HeapObject addresses to objects' uids. | |
| 759 HeapObjectsMap ids_; | |
| 760 | |
| 761 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection); | |
| 762 }; | |
| 763 | |
| 764 | |
| 765 // A typedef for referencing anything that can be snapshotted living | |
| 766 // in any kind of heap memory. | |
| 767 typedef void* HeapThing; | |
| 768 | |
| 769 | |
| 770 // An interface that creates HeapEntries by HeapThings. | |
| 771 class HeapEntriesAllocator { | |
| 772 public: | |
| 773 virtual ~HeapEntriesAllocator() { } | |
| 774 virtual HeapEntry* AllocateEntry(HeapThing ptr) = 0; | |
| 775 }; | |
| 776 | |
| 777 | |
| 778 // The HeapEntriesMap instance is used to track a mapping between | |
| 779 // real heap objects and their representations in heap snapshots. | |
| 780 class HeapEntriesMap { | |
| 781 public: | |
| 782 HeapEntriesMap(); | |
| 783 | |
| 784 int Map(HeapThing thing); | |
| 785 void Pair(HeapThing thing, int entry); | |
| 786 | |
| 787 private: | |
| 788 static uint32_t Hash(HeapThing thing) { | |
| 789 return ComputeIntegerHash( | |
| 790 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)), | |
| 791 v8::internal::kZeroHashSeed); | |
| 792 } | |
| 793 static bool HeapThingsMatch(HeapThing key1, HeapThing key2) { | |
| 794 return key1 == key2; | |
| 795 } | |
| 796 | |
| 797 HashMap entries_; | |
| 798 | |
| 799 friend class HeapObjectsSet; | |
| 800 | |
| 801 DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); | |
| 802 }; | |
| 803 | |
| 804 | |
| 805 class HeapObjectsSet { | |
| 806 public: | |
| 807 HeapObjectsSet(); | |
| 808 void Clear(); | |
| 809 bool Contains(Object* object); | |
| 810 void Insert(Object* obj); | |
| 811 const char* GetTag(Object* obj); | |
| 812 void SetTag(Object* obj, const char* tag); | |
| 813 bool is_empty() const { return entries_.occupancy() == 0; } | |
| 814 | |
| 815 private: | |
| 816 HashMap entries_; | |
| 817 | |
| 818 DISALLOW_COPY_AND_ASSIGN(HeapObjectsSet); | |
| 819 }; | |
| 820 | |
| 821 | |
| 822 // An interface used to populate a snapshot with nodes and edges. | |
| 823 class SnapshotFillerInterface { | |
| 824 public: | |
| 825 virtual ~SnapshotFillerInterface() { } | |
| 826 virtual HeapEntry* AddEntry(HeapThing ptr, | |
| 827 HeapEntriesAllocator* allocator) = 0; | |
| 828 virtual HeapEntry* FindEntry(HeapThing ptr) = 0; | |
| 829 virtual HeapEntry* FindOrAddEntry(HeapThing ptr, | |
| 830 HeapEntriesAllocator* allocator) = 0; | |
| 831 virtual void SetIndexedReference(HeapGraphEdge::Type type, | |
| 832 int parent_entry, | |
| 833 int index, | |
| 834 HeapEntry* child_entry) = 0; | |
| 835 virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, | |
| 836 int parent_entry, | |
| 837 HeapEntry* child_entry) = 0; | |
| 838 virtual void SetNamedReference(HeapGraphEdge::Type type, | |
| 839 int parent_entry, | |
| 840 const char* reference_name, | |
| 841 HeapEntry* child_entry) = 0; | |
| 842 virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type, | |
| 843 int parent_entry, | |
| 844 HeapEntry* child_entry) = 0; | |
| 845 }; | |
| 846 | |
| 847 | |
| 848 class SnapshottingProgressReportingInterface { | |
| 849 public: | |
| 850 virtual ~SnapshottingProgressReportingInterface() { } | |
| 851 virtual void ProgressStep() = 0; | |
| 852 virtual bool ProgressReport(bool force) = 0; | |
| 853 }; | |
| 854 | |
| 855 | |
| 856 // An implementation of V8 heap graph extractor. | |
| 857 class V8HeapExplorer : public HeapEntriesAllocator { | |
| 858 public: | |
| 859 V8HeapExplorer(HeapSnapshot* snapshot, | |
| 860 SnapshottingProgressReportingInterface* progress, | |
| 861 v8::HeapProfiler::ObjectNameResolver* resolver); | |
| 862 virtual ~V8HeapExplorer(); | |
| 863 virtual HeapEntry* AllocateEntry(HeapThing ptr); | |
| 864 void AddRootEntries(SnapshotFillerInterface* filler); | |
| 865 int EstimateObjectsCount(HeapIterator* iterator); | |
| 866 bool IterateAndExtractReferences(SnapshotFillerInterface* filler); | |
| 867 void TagGlobalObjects(); | |
| 868 | |
| 869 static String* GetConstructorName(JSObject* object); | |
| 870 | |
| 871 static HeapObject* const kInternalRootObject; | |
| 872 | |
| 873 private: | |
| 874 HeapEntry* AddEntry(HeapObject* object); | |
| 875 HeapEntry* AddEntry(HeapObject* object, | |
| 876 HeapEntry::Type type, | |
| 877 const char* name); | |
| 878 const char* GetSystemEntryName(HeapObject* object); | |
| 879 | |
| 880 void ExtractReferences(HeapObject* obj); | |
| 881 void ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy); | |
| 882 void ExtractJSObjectReferences(int entry, JSObject* js_obj); | |
| 883 void ExtractStringReferences(int entry, String* obj); | |
| 884 void ExtractContextReferences(int entry, Context* context); | |
| 885 void ExtractMapReferences(int entry, Map* map); | |
| 886 void ExtractSharedFunctionInfoReferences(int entry, | |
| 887 SharedFunctionInfo* shared); | |
| 888 void ExtractScriptReferences(int entry, Script* script); | |
| 889 void ExtractCodeCacheReferences(int entry, CodeCache* code_cache); | |
| 890 void ExtractCodeReferences(int entry, Code* code); | |
| 891 void ExtractJSGlobalPropertyCellReferences(int entry, | |
| 892 JSGlobalPropertyCell* cell); | |
| 893 void ExtractClosureReferences(JSObject* js_obj, int entry); | |
| 894 void ExtractPropertyReferences(JSObject* js_obj, int entry); | |
| 895 void ExtractElementReferences(JSObject* js_obj, int entry); | |
| 896 void ExtractInternalReferences(JSObject* js_obj, int entry); | |
| 897 bool IsEssentialObject(Object* object); | |
| 898 void SetClosureReference(HeapObject* parent_obj, | |
| 899 int parent, | |
| 900 String* reference_name, | |
| 901 Object* child); | |
| 902 void SetNativeBindReference(HeapObject* parent_obj, | |
| 903 int parent, | |
| 904 const char* reference_name, | |
| 905 Object* child); | |
| 906 void SetElementReference(HeapObject* parent_obj, | |
| 907 int parent, | |
| 908 int index, | |
| 909 Object* child); | |
| 910 void SetInternalReference(HeapObject* parent_obj, | |
| 911 int parent, | |
| 912 const char* reference_name, | |
| 913 Object* child, | |
| 914 int field_offset = -1); | |
| 915 void SetInternalReference(HeapObject* parent_obj, | |
| 916 int parent, | |
| 917 int index, | |
| 918 Object* child, | |
| 919 int field_offset = -1); | |
| 920 void SetHiddenReference(HeapObject* parent_obj, | |
| 921 int parent, | |
| 922 int index, | |
| 923 Object* child); | |
| 924 void SetWeakReference(HeapObject* parent_obj, | |
| 925 int parent, | |
| 926 int index, | |
| 927 Object* child_obj, | |
| 928 int field_offset); | |
| 929 void SetPropertyReference(HeapObject* parent_obj, | |
| 930 int parent, | |
| 931 String* reference_name, | |
| 932 Object* child, | |
| 933 const char* name_format_string = NULL, | |
| 934 int field_offset = -1); | |
| 935 void SetUserGlobalReference(Object* user_global); | |
| 936 void SetRootGcRootsReference(); | |
| 937 void SetGcRootsReference(VisitorSynchronization::SyncTag tag); | |
| 938 void SetGcSubrootReference( | |
| 939 VisitorSynchronization::SyncTag tag, bool is_weak, Object* child); | |
| 940 const char* GetStrongGcSubrootName(Object* object); | |
| 941 void TagObject(Object* obj, const char* tag); | |
| 942 | |
| 943 HeapEntry* GetEntry(Object* obj); | |
| 944 | |
| 945 static inline HeapObject* GetNthGcSubrootObject(int delta); | |
| 946 static inline int GetGcSubrootOrder(HeapObject* subroot); | |
| 947 | |
| 948 Heap* heap_; | |
| 949 HeapSnapshot* snapshot_; | |
| 950 HeapSnapshotsCollection* collection_; | |
| 951 SnapshottingProgressReportingInterface* progress_; | |
| 952 SnapshotFillerInterface* filler_; | |
| 953 HeapObjectsSet objects_tags_; | |
| 954 HeapObjectsSet strong_gc_subroot_names_; | |
| 955 v8::HeapProfiler::ObjectNameResolver* global_object_name_resolver_; | |
| 956 | |
| 957 static HeapObject* const kGcRootsObject; | |
| 958 static HeapObject* const kFirstGcSubrootObject; | |
| 959 static HeapObject* const kLastGcSubrootObject; | |
| 960 | |
| 961 friend class IndexedReferencesExtractor; | |
| 962 friend class GcSubrootsEnumerator; | |
| 963 friend class RootsReferencesExtractor; | |
| 964 | |
| 965 DISALLOW_COPY_AND_ASSIGN(V8HeapExplorer); | |
| 966 }; | |
| 967 | |
| 968 | |
| 969 class NativeGroupRetainedObjectInfo; | |
| 970 | |
| 971 | |
| 972 // An implementation of retained native objects extractor. | |
| 973 class NativeObjectsExplorer { | |
| 974 public: | |
| 975 NativeObjectsExplorer(HeapSnapshot* snapshot, | |
| 976 SnapshottingProgressReportingInterface* progress); | |
| 977 virtual ~NativeObjectsExplorer(); | |
| 978 void AddRootEntries(SnapshotFillerInterface* filler); | |
| 979 int EstimateObjectsCount(); | |
| 980 bool IterateAndExtractReferences(SnapshotFillerInterface* filler); | |
| 981 | |
| 982 private: | |
| 983 void FillRetainedObjects(); | |
| 984 void FillImplicitReferences(); | |
| 985 List<HeapObject*>* GetListMaybeDisposeInfo(v8::RetainedObjectInfo* info); | |
| 986 void SetNativeRootReference(v8::RetainedObjectInfo* info); | |
| 987 void SetRootNativeRootsReference(); | |
| 988 void SetWrapperNativeReferences(HeapObject* wrapper, | |
| 989 v8::RetainedObjectInfo* info); | |
| 990 void VisitSubtreeWrapper(Object** p, uint16_t class_id); | |
| 991 | |
| 992 static uint32_t InfoHash(v8::RetainedObjectInfo* info) { | |
| 993 return ComputeIntegerHash(static_cast<uint32_t>(info->GetHash()), | |
| 994 v8::internal::kZeroHashSeed); | |
| 995 } | |
| 996 static bool RetainedInfosMatch(void* key1, void* key2) { | |
| 997 return key1 == key2 || | |
| 998 (reinterpret_cast<v8::RetainedObjectInfo*>(key1))->IsEquivalent( | |
| 999 reinterpret_cast<v8::RetainedObjectInfo*>(key2)); | |
| 1000 } | |
| 1001 INLINE(static bool StringsMatch(void* key1, void* key2)) { | |
| 1002 return strcmp(reinterpret_cast<char*>(key1), | |
| 1003 reinterpret_cast<char*>(key2)) == 0; | |
| 1004 } | |
| 1005 | |
| 1006 NativeGroupRetainedObjectInfo* FindOrAddGroupInfo(const char* label); | |
| 1007 | |
| 1008 HeapSnapshot* snapshot_; | |
| 1009 HeapSnapshotsCollection* collection_; | |
| 1010 SnapshottingProgressReportingInterface* progress_; | |
| 1011 bool embedder_queried_; | |
| 1012 HeapObjectsSet in_groups_; | |
| 1013 // RetainedObjectInfo* -> List<HeapObject*>* | |
| 1014 HashMap objects_by_info_; | |
| 1015 HashMap native_groups_; | |
| 1016 HeapEntriesAllocator* synthetic_entries_allocator_; | |
| 1017 HeapEntriesAllocator* native_entries_allocator_; | |
| 1018 // Used during references extraction. | |
| 1019 SnapshotFillerInterface* filler_; | |
| 1020 | |
| 1021 static HeapThing const kNativesRootObject; | |
| 1022 | |
| 1023 friend class GlobalHandlesExtractor; | |
| 1024 | |
| 1025 DISALLOW_COPY_AND_ASSIGN(NativeObjectsExplorer); | |
| 1026 }; | |
| 1027 | |
| 1028 | |
| 1029 class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { | |
| 1030 public: | |
| 1031 HeapSnapshotGenerator(HeapSnapshot* snapshot, | |
| 1032 v8::ActivityControl* control, | |
| 1033 v8::HeapProfiler::ObjectNameResolver* resolver, | |
| 1034 Heap* heap); | |
| 1035 bool GenerateSnapshot(); | |
| 1036 | |
| 1037 private: | |
| 1038 bool FillReferences(); | |
| 1039 void ProgressStep(); | |
| 1040 bool ProgressReport(bool force = false); | |
| 1041 void SetProgressTotal(int iterations_count); | |
| 1042 | |
| 1043 HeapSnapshot* snapshot_; | |
| 1044 v8::ActivityControl* control_; | |
| 1045 V8HeapExplorer v8_heap_explorer_; | |
| 1046 NativeObjectsExplorer dom_explorer_; | |
| 1047 // Mapping from HeapThing pointers to HeapEntry* pointers. | |
| 1048 HeapEntriesMap entries_; | |
| 1049 // Used during snapshot generation. | |
| 1050 int progress_counter_; | |
| 1051 int progress_total_; | |
| 1052 Heap* heap_; | |
| 1053 | |
| 1054 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator); | |
| 1055 }; | |
| 1056 | |
| 1057 class OutputStreamWriter; | |
| 1058 | |
| 1059 class HeapSnapshotJSONSerializer { | |
| 1060 public: | |
| 1061 explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot) | |
| 1062 : snapshot_(snapshot), | |
| 1063 strings_(ObjectsMatch), | |
| 1064 next_node_id_(1), | |
| 1065 next_string_id_(1), | |
| 1066 writer_(NULL) { | |
| 1067 } | |
| 1068 void Serialize(v8::OutputStream* stream); | |
| 1069 | |
| 1070 private: | |
| 1071 INLINE(static bool ObjectsMatch(void* key1, void* key2)) { | |
| 1072 return key1 == key2; | |
| 1073 } | |
| 1074 | |
| 1075 INLINE(static uint32_t ObjectHash(const void* key)) { | |
| 1076 return ComputeIntegerHash( | |
| 1077 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)), | |
| 1078 v8::internal::kZeroHashSeed); | |
| 1079 } | |
| 1080 | |
| 1081 HeapSnapshot* CreateFakeSnapshot(); | |
| 1082 int GetStringId(const char* s); | |
| 1083 int entry_index(HeapEntry* e) { return e->index() * kNodeFieldsCount; } | |
| 1084 void SerializeEdge(HeapGraphEdge* edge, bool first_edge); | |
| 1085 void SerializeEdges(); | |
| 1086 void SerializeImpl(); | |
| 1087 void SerializeNode(HeapEntry* entry); | |
| 1088 void SerializeNodes(); | |
| 1089 void SerializeSnapshot(); | |
| 1090 void SerializeString(const unsigned char* s); | |
| 1091 void SerializeStrings(); | |
| 1092 void SortHashMap(HashMap* map, List<HashMap::Entry*>* sorted_entries); | |
| 1093 | |
| 1094 static const int kEdgeFieldsCount; | |
| 1095 static const int kNodeFieldsCount; | |
| 1096 | |
| 1097 HeapSnapshot* snapshot_; | |
| 1098 HashMap strings_; | |
| 1099 int next_node_id_; | |
| 1100 int next_string_id_; | |
| 1101 OutputStreamWriter* writer_; | |
| 1102 | |
| 1103 friend class HeapSnapshotJSONSerializerEnumerator; | |
| 1104 friend class HeapSnapshotJSONSerializerIterator; | |
| 1105 | |
| 1106 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer); | |
| 1107 }; | |
| 1108 | |
| 1109 } } // namespace v8::internal | 450 } } // namespace v8::internal |
| 1110 | 451 |
| 1111 #endif // V8_PROFILE_GENERATOR_H_ | 452 #endif // V8_PROFILE_GENERATOR_H_ |
| OLD | NEW |