Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 HeapSnapshotsCollection* collection() { return collection_; } | 674 HeapSnapshotsCollection* collection() { return collection_; } |
| 675 Type type() { return type_; } | 675 Type type() { return type_; } |
| 676 const char* title() { return title_; } | 676 const char* title() { return title_; } |
| 677 unsigned uid() { return uid_; } | 677 unsigned uid() { return uid_; } |
| 678 HeapEntry* root() { return root_entry_; } | 678 HeapEntry* root() { return root_entry_; } |
| 679 HeapEntry* gc_roots() { return gc_roots_entry_; } | 679 HeapEntry* gc_roots() { return gc_roots_entry_; } |
| 680 List<HeapEntry*>* entries() { return &entries_; } | 680 List<HeapEntry*>* entries() { return &entries_; } |
| 681 | 681 |
| 682 void AllocateEntries( | 682 void AllocateEntries( |
| 683 int entries_count, int children_count, int retainers_count); | 683 int entries_count, int children_count, int retainers_count); |
| 684 HeapEntry* AddEntry( | |
| 685 HeapObject* object, int children_count, int retainers_count); | |
| 686 HeapEntry* AddEntry(HeapEntry::Type type, | 684 HeapEntry* AddEntry(HeapEntry::Type type, |
| 687 const char* name, | 685 const char* name, |
| 688 uint64_t id, | 686 uint64_t id, |
| 689 int size, | 687 int size, |
| 690 int children_count, | 688 int children_count, |
| 691 int retainers_count); | 689 int retainers_count); |
| 690 HeapEntry* AddRootEntry(int children_count); | |
| 691 HeapEntry* AddGcRootsEntry(int children_count, int retainers_count); | |
| 692 void ClearPaint(); | 692 void ClearPaint(); |
| 693 HeapSnapshotsDiff* CompareWith(HeapSnapshot* snapshot); | 693 HeapSnapshotsDiff* CompareWith(HeapSnapshot* snapshot); |
| 694 HeapEntry* GetEntryById(uint64_t id); | 694 HeapEntry* GetEntryById(uint64_t id); |
| 695 List<HeapGraphPath*>* GetRetainingPaths(HeapEntry* entry); | 695 List<HeapGraphPath*>* GetRetainingPaths(HeapEntry* entry); |
| 696 List<HeapEntry*>* GetSortedEntriesList(); | 696 List<HeapEntry*>* GetSortedEntriesList(); |
| 697 template<class Visitor> | 697 template<class Visitor> |
| 698 void IterateEntries(Visitor* visitor) { entries_.Iterate(visitor); } | 698 void IterateEntries(Visitor* visitor) { entries_.Iterate(visitor); } |
| 699 void SetDominatorsToSelf(); | 699 void SetDominatorsToSelf(); |
| 700 | 700 |
| 701 void Print(int max_depth); | 701 void Print(int max_depth); |
| 702 void PrintEntriesSize(); | 702 void PrintEntriesSize(); |
| 703 | 703 |
| 704 static HeapObject* const kInternalRootObject; | |
| 705 static HeapObject* const kGcRootsObject; | |
| 706 | |
| 707 private: | 704 private: |
| 708 HeapEntry* AddEntry(HeapObject* object, | |
| 709 HeapEntry::Type type, | |
| 710 const char* name, | |
| 711 int children_count, | |
| 712 int retainers_count); | |
| 713 HeapEntry* GetNextEntryToInit(); | 705 HeapEntry* GetNextEntryToInit(); |
| 714 | 706 |
| 715 HeapSnapshotsCollection* collection_; | 707 HeapSnapshotsCollection* collection_; |
| 716 Type type_; | 708 Type type_; |
| 717 const char* title_; | 709 const char* title_; |
| 718 unsigned uid_; | 710 unsigned uid_; |
| 719 HeapEntry* root_entry_; | 711 HeapEntry* root_entry_; |
| 720 HeapEntry* gc_roots_entry_; | 712 HeapEntry* gc_roots_entry_; |
| 721 char* raw_entries_; | 713 char* raw_entries_; |
| 722 List<HeapEntry*> entries_; | 714 List<HeapEntry*> entries_; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 StringsStorage names_; | 858 StringsStorage names_; |
| 867 TokenEnumerator* token_enumerator_; | 859 TokenEnumerator* token_enumerator_; |
| 868 // Mapping from HeapObject addresses to objects' uids. | 860 // Mapping from HeapObject addresses to objects' uids. |
| 869 HeapObjectsMap ids_; | 861 HeapObjectsMap ids_; |
| 870 HeapSnapshotsComparator comparator_; | 862 HeapSnapshotsComparator comparator_; |
| 871 | 863 |
| 872 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection); | 864 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection); |
| 873 }; | 865 }; |
| 874 | 866 |
| 875 | 867 |
| 868 // A typedef for referencing anything that can be snapshotted living | |
| 869 // in any kind of heap memory. | |
| 870 typedef void* HeapThing; | |
| 871 | |
| 872 | |
| 873 // An interface that creates HeapEntries by HeapThings. | |
| 874 class HeapEntriesAllocator { | |
| 875 public: | |
| 876 virtual ~HeapEntriesAllocator() { } | |
| 877 virtual HeapEntry* AllocateEntry( | |
| 878 HeapThing ptr, int children_count, int retainers_count) = 0; | |
| 879 }; | |
| 880 | |
| 881 | |
| 876 // The HeapEntriesMap instance is used to track a mapping between | 882 // The HeapEntriesMap instance is used to track a mapping between |
| 877 // real heap objects and their representations in heap snapshots. | 883 // real heap objects and their representations in heap snapshots. |
| 878 class HeapEntriesMap { | 884 class HeapEntriesMap { |
|
Vitaly Repeshko
2011/03/01 16:55:51
Consider refactoring it into a simple HeapThing->E
mnaganov (inactive)
2011/03/01 17:35:41
Thanks, but let me postpone it.
| |
| 879 public: | 885 public: |
| 880 HeapEntriesMap(); | 886 HeapEntriesMap(); |
| 881 ~HeapEntriesMap(); | 887 ~HeapEntriesMap(); |
| 882 | 888 |
| 883 HeapEntry* Map(HeapObject* object); | 889 HeapEntry* Map(HeapThing thing); |
| 884 void Pair(HeapObject* object, HeapEntry* entry); | 890 void Pair(HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry); |
| 885 void CountReference(HeapObject* from, HeapObject* to, | 891 void CountReference(HeapThing from, HeapThing to, |
| 886 int* prev_children_count = NULL, | 892 int* prev_children_count = NULL, |
| 887 int* prev_retainers_count = NULL); | 893 int* prev_retainers_count = NULL); |
| 888 template<class Visitor> | 894 void UpdateEntries(); |
|
Vitaly Repeshko
2011/03/01 16:55:51
The name is confusing. It's supposed to be called
mnaganov (inactive)
2011/03/01 17:35:41
Renamed to AllocateEntries -- this should meet you
| |
| 889 void UpdateEntries(Visitor* visitor); | |
| 890 | 895 |
| 891 int entries_count() { return entries_count_; } | 896 int entries_count() { return entries_count_; } |
| 892 int total_children_count() { return total_children_count_; } | 897 int total_children_count() { return total_children_count_; } |
| 893 int total_retainers_count() { return total_retainers_count_; } | 898 int total_retainers_count() { return total_retainers_count_; } |
| 894 | 899 |
| 895 static HeapEntry *const kHeapEntryPlaceholder; | 900 static HeapEntry *const kHeapEntryPlaceholder; |
| 896 | 901 |
| 897 private: | 902 private: |
| 898 struct EntryInfo { | 903 struct EntryInfo { |
| 899 explicit EntryInfo(HeapEntry* entry) | 904 EntryInfo(HeapEntry* entry, HeapEntriesAllocator* allocator) |
| 900 : entry(entry), children_count(0), retainers_count(0) { } | 905 : entry(entry), |
| 906 allocator(allocator), | |
| 907 children_count(0), | |
| 908 retainers_count(0) { | |
| 909 } | |
| 901 HeapEntry* entry; | 910 HeapEntry* entry; |
| 911 HeapEntriesAllocator* allocator; | |
| 902 int children_count; | 912 int children_count; |
| 903 int retainers_count; | 913 int retainers_count; |
| 904 }; | 914 }; |
| 905 | 915 |
| 906 static uint32_t Hash(HeapObject* object) { | 916 static uint32_t Hash(HeapThing thing) { |
| 907 return ComputeIntegerHash( | 917 return ComputeIntegerHash( |
| 908 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(object))); | 918 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing))); |
| 909 } | 919 } |
| 910 static bool HeapObjectsMatch(void* key1, void* key2) { return key1 == key2; } | 920 static bool HeapThingsMatch(HeapThing key1, HeapThing key2) { |
| 921 return key1 == key2; | |
| 922 } | |
| 911 | 923 |
| 912 HashMap entries_; | 924 HashMap entries_; |
| 913 int entries_count_; | 925 int entries_count_; |
| 914 int total_children_count_; | 926 int total_children_count_; |
| 915 int total_retainers_count_; | 927 int total_retainers_count_; |
| 916 | 928 |
| 917 friend class HeapObjectsSet; | 929 friend class HeapObjectsSet; |
| 918 | 930 |
| 919 DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); | 931 DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); |
| 920 }; | 932 }; |
| 921 | 933 |
| 922 | 934 |
| 923 class HeapObjectsSet { | 935 class HeapObjectsSet { |
| 924 public: | 936 public: |
| 925 HeapObjectsSet(); | 937 HeapObjectsSet(); |
| 926 void Clear(); | 938 void Clear(); |
| 927 bool Contains(Object* object); | 939 bool Contains(Object* object); |
| 928 void Insert(Object* obj); | 940 void Insert(Object* obj); |
| 929 | 941 |
| 930 private: | 942 private: |
| 931 HashMap entries_; | 943 HashMap entries_; |
| 932 | 944 |
| 933 DISALLOW_COPY_AND_ASSIGN(HeapObjectsSet); | 945 DISALLOW_COPY_AND_ASSIGN(HeapObjectsSet); |
| 934 }; | 946 }; |
| 935 | 947 |
| 936 | 948 |
| 937 class HeapSnapshotGenerator { | 949 // An interface used to populate a snapshot with nodes and edges. |
| 950 class SnapshotFillerInterface { | |
| 938 public: | 951 public: |
| 939 class SnapshotFillerInterface { | 952 virtual ~SnapshotFillerInterface() { } |
| 940 public: | 953 virtual HeapEntry* AddEntry(HeapThing ptr) = 0; |
| 941 virtual ~SnapshotFillerInterface() { } | 954 virtual HeapEntry* FindOrAddEntry(HeapThing ptr) = 0; |
| 942 virtual HeapEntry* AddEntry(HeapObject* obj) = 0; | 955 virtual void SetIndexedReference(HeapGraphEdge::Type type, |
| 943 virtual void SetIndexedReference(HeapGraphEdge::Type type, | 956 HeapThing parent_ptr, |
| 944 HeapObject* parent_obj, | |
| 945 HeapEntry* parent_entry, | |
| 946 int index, | |
| 947 Object* child_obj, | |
| 948 HeapEntry* child_entry) = 0; | |
| 949 virtual void SetNamedReference(HeapGraphEdge::Type type, | |
| 950 HeapObject* parent_obj, | |
| 951 HeapEntry* parent_entry, | 957 HeapEntry* parent_entry, |
| 952 const char* reference_name, | 958 int index, |
| 953 Object* child_obj, | 959 HeapThing child_ptr, |
| 954 HeapEntry* child_entry) = 0; | 960 HeapEntry* child_entry) = 0; |
| 955 virtual void SetRootGcRootsReference() = 0; | 961 virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, |
| 956 virtual void SetRootShortcutReference(Object* child_obj, | 962 HeapThing parent_ptr, |
| 963 HeapEntry* parent_entry, | |
| 964 HeapThing child_ptr, | |
| 965 HeapEntry* child_entry) = 0; | |
| 966 virtual void SetNamedReference(HeapGraphEdge::Type type, | |
| 967 HeapThing parent_ptr, | |
| 968 HeapEntry* parent_entry, | |
| 969 const char* reference_name, | |
| 970 HeapThing child_ptr, | |
| 971 HeapEntry* child_entry) = 0; | |
| 972 virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type, | |
| 973 HeapThing parent_ptr, | |
| 974 HeapEntry* parent_entry, | |
| 975 HeapThing child_ptr, | |
| 957 HeapEntry* child_entry) = 0; | 976 HeapEntry* child_entry) = 0; |
| 958 virtual void SetStrongRootReference(Object* child_obj, | 977 }; |
| 959 HeapEntry* child_entry) = 0; | |
| 960 }; | |
| 961 | 978 |
| 962 HeapSnapshotGenerator(HeapSnapshot* snapshot, | |
| 963 v8::ActivityControl* control); | |
| 964 bool GenerateSnapshot(); | |
| 965 | 979 |
| 966 private: | 980 class SnapshottingProgressReportingInterface { |
| 967 bool ApproximateRetainedSizes(); | 981 public: |
| 968 bool BuildDominatorTree(const Vector<HeapEntry*>& entries, | 982 virtual ~SnapshottingProgressReportingInterface() { } |
| 969 Vector<HeapEntry*>* dominators); | 983 virtual void ProgressStep() = 0; |
| 970 bool CountEntriesAndReferences(); | 984 virtual bool ProgressReport(bool force) = 0; |
| 971 HeapEntry* GetEntry(Object* obj); | 985 }; |
| 972 void IncProgressCounter() { ++progress_counter_; } | 986 |
| 987 | |
| 988 // An implementation of V8 heap graph extractor. | |
| 989 class V8HeapExplorer : public HeapEntriesAllocator { | |
| 990 public: | |
| 991 V8HeapExplorer(HeapSnapshot* snapshot, | |
| 992 SnapshottingProgressReportingInterface* progress); | |
| 993 ~V8HeapExplorer(); | |
| 994 HeapEntry* AllocateEntry( | |
|
Vitaly Repeshko
2011/03/01 16:55:51
It seems weird to have both AllocateEntry and AddE
mnaganov (inactive)
2011/03/01 17:35:41
Marked AllocateEntry as virtual.
Also, I made priv
| |
| 995 HeapThing ptr, int children_count, int retainers_count); | |
| 996 | |
| 997 HeapEntry* AddEntry( | |
| 998 HeapObject* object, int children_count, int retainers_count); | |
| 999 HeapEntry* AddEntry(HeapObject* object, | |
| 1000 HeapEntry::Type type, | |
| 1001 const char* name, | |
| 1002 int children_count, | |
| 1003 int retainers_count); | |
| 1004 void AddRootEntries(SnapshotFillerInterface* filler); | |
| 973 void ExtractReferences(HeapObject* obj); | 1005 void ExtractReferences(HeapObject* obj); |
| 974 void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry); | 1006 void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry); |
| 975 void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); | 1007 void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); |
| 976 void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); | 1008 void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); |
| 977 void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry); | 1009 void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry); |
| 978 bool FillReferences(); | 1010 int EstimateObjectsCount(); |
| 979 void FillReversePostorderIndexes(Vector<HeapEntry*>* entries); | 1011 bool IterateAndExtractReferences(SnapshotFillerInterface* filler); |
| 980 bool IterateAndExtractReferences(); | |
| 981 inline bool ReportProgress(bool force = false); | |
| 982 bool SetEntriesDominators(); | |
| 983 void SetClosureReference(HeapObject* parent_obj, | 1012 void SetClosureReference(HeapObject* parent_obj, |
| 984 HeapEntry* parent, | 1013 HeapEntry* parent, |
| 985 String* reference_name, | 1014 String* reference_name, |
| 986 Object* child); | 1015 Object* child); |
| 987 void SetElementReference(HeapObject* parent_obj, | 1016 void SetElementReference(HeapObject* parent_obj, |
| 988 HeapEntry* parent, | 1017 HeapEntry* parent, |
| 989 int index, | 1018 int index, |
| 990 Object* child); | 1019 Object* child); |
| 991 void SetInternalReference(HeapObject* parent_obj, | 1020 void SetInternalReference(HeapObject* parent_obj, |
| 992 HeapEntry* parent, | 1021 HeapEntry* parent, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1004 HeapEntry* parent, | 1033 HeapEntry* parent, |
| 1005 String* reference_name, | 1034 String* reference_name, |
| 1006 Object* child); | 1035 Object* child); |
| 1007 void SetPropertyShortcutReference(HeapObject* parent_obj, | 1036 void SetPropertyShortcutReference(HeapObject* parent_obj, |
| 1008 HeapEntry* parent, | 1037 HeapEntry* parent, |
| 1009 String* reference_name, | 1038 String* reference_name, |
| 1010 Object* child); | 1039 Object* child); |
| 1011 void SetRootShortcutReference(Object* child); | 1040 void SetRootShortcutReference(Object* child); |
| 1012 void SetRootGcRootsReference(); | 1041 void SetRootGcRootsReference(); |
| 1013 void SetGcRootsReference(Object* child); | 1042 void SetGcRootsReference(Object* child); |
| 1043 | |
| 1044 private: | |
| 1045 HeapEntry* GetEntry(Object* obj); | |
| 1046 | |
| 1047 HeapSnapshot* snapshot_; | |
| 1048 HeapSnapshotsCollection* collection_; | |
| 1049 SnapshottingProgressReportingInterface* progress_; | |
| 1050 // Used during references extraction to mark heap objects that | |
| 1051 // are references via non-hidden properties. | |
| 1052 HeapObjectsSet known_references_; | |
| 1053 SnapshotFillerInterface* filler_; | |
| 1054 | |
| 1055 static HeapObject* const kInternalRootObject; | |
| 1056 static HeapObject* const kGcRootsObject; | |
| 1057 | |
| 1058 friend class IndexedReferencesExtractor; | |
| 1059 friend class RootsReferencesExtractor; | |
| 1060 | |
| 1061 DISALLOW_COPY_AND_ASSIGN(V8HeapExplorer); | |
| 1062 }; | |
| 1063 | |
| 1064 | |
| 1065 class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { | |
| 1066 public: | |
| 1067 HeapSnapshotGenerator(HeapSnapshot* snapshot, | |
| 1068 v8::ActivityControl* control); | |
| 1069 bool GenerateSnapshot(); | |
| 1070 | |
| 1071 private: | |
| 1072 bool ApproximateRetainedSizes(); | |
| 1073 bool BuildDominatorTree(const Vector<HeapEntry*>& entries, | |
| 1074 Vector<HeapEntry*>* dominators); | |
| 1075 bool CountEntriesAndReferences(); | |
| 1076 bool FillReferences(); | |
| 1077 void FillReversePostorderIndexes(Vector<HeapEntry*>* entries); | |
| 1078 void ProgressStep(); | |
| 1079 bool ProgressReport(bool force = false); | |
| 1080 bool SetEntriesDominators(); | |
| 1014 void SetProgressTotal(int iterations_count); | 1081 void SetProgressTotal(int iterations_count); |
| 1015 | 1082 |
| 1016 HeapSnapshot* snapshot_; | 1083 HeapSnapshot* snapshot_; |
| 1017 v8::ActivityControl* control_; | 1084 v8::ActivityControl* control_; |
| 1018 HeapSnapshotsCollection* collection_; | 1085 V8HeapExplorer v8_heap_explorer_; |
| 1019 // Mapping from HeapObject* pointers to HeapEntry* pointers. | 1086 // Mapping from HeapThing pointers to HeapEntry* pointers. |
| 1020 HeapEntriesMap entries_; | 1087 HeapEntriesMap entries_; |
| 1021 SnapshotFillerInterface* filler_; | |
| 1022 // Used during references extraction to mark heap objects that | |
| 1023 // are references via non-hidden properties. | |
| 1024 HeapObjectsSet known_references_; | |
| 1025 // Used during snapshot generation. | 1088 // Used during snapshot generation. |
| 1026 int progress_counter_; | 1089 int progress_counter_; |
| 1027 int progress_total_; | 1090 int progress_total_; |
| 1028 | 1091 |
| 1029 friend class IndexedReferencesExtractor; | |
| 1030 friend class RootsReferencesExtractor; | |
| 1031 | |
| 1032 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator); | 1092 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator); |
| 1033 }; | 1093 }; |
| 1034 | 1094 |
| 1035 class OutputStreamWriter; | 1095 class OutputStreamWriter; |
| 1036 | 1096 |
| 1037 class HeapSnapshotJSONSerializer { | 1097 class HeapSnapshotJSONSerializer { |
| 1038 public: | 1098 public: |
| 1039 explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot) | 1099 explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot) |
| 1040 : snapshot_(snapshot), | 1100 : snapshot_(snapshot), |
| 1041 nodes_(ObjectsMatch), | 1101 nodes_(ObjectsMatch), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1082 }; | 1142 }; |
| 1083 | 1143 |
| 1084 | 1144 |
| 1085 String* GetConstructorNameForHeapProfile(JSObject* object); | 1145 String* GetConstructorNameForHeapProfile(JSObject* object); |
| 1086 | 1146 |
| 1087 } } // namespace v8::internal | 1147 } } // namespace v8::internal |
| 1088 | 1148 |
| 1089 #endif // ENABLE_LOGGING_AND_PROFILING | 1149 #endif // ENABLE_LOGGING_AND_PROFILING |
| 1090 | 1150 |
| 1091 #endif // V8_PROFILE_GENERATOR_H_ | 1151 #endif // V8_PROFILE_GENERATOR_H_ |
| OLD | NEW |