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 |