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 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1301 return (gc_subroot_entries_[tag] = AddEntry( | 1301 return (gc_subroot_entries_[tag] = AddEntry( |
1302 HeapEntry::kObject, | 1302 HeapEntry::kObject, |
1303 VisitorSynchronization::kTagNames[tag], | 1303 VisitorSynchronization::kTagNames[tag], |
1304 HeapObjectsMap::GetNthGcSubrootId(tag), | 1304 HeapObjectsMap::GetNthGcSubrootId(tag), |
1305 0, | 1305 0, |
1306 children_count, | 1306 children_count, |
1307 retainers_count)); | 1307 retainers_count)); |
1308 } | 1308 } |
1309 | 1309 |
1310 | 1310 |
1311 HeapEntry* HeapSnapshot::AddNativesRootEntry(int children_count, | |
1312 int retainers_count) { | |
1313 ASSERT(natives_root_entry_ == NULL); | |
1314 return (natives_root_entry_ = AddEntry( | |
1315 HeapEntry::kObject, | |
1316 "(Native objects)", | |
1317 HeapObjectsMap::kNativesRootObjectId, | |
1318 0, | |
1319 children_count, | |
1320 retainers_count)); | |
1321 } | |
1322 | |
1323 | |
1324 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, | 1311 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, |
1325 const char* name, | 1312 const char* name, |
1326 uint64_t id, | 1313 uint64_t id, |
1327 int size, | 1314 int size, |
1328 int children_count, | 1315 int children_count, |
1329 int retainers_count) { | 1316 int retainers_count) { |
1330 HeapEntry* entry = GetNextEntryToInit(); | 1317 HeapEntry* entry = GetNextEntryToInit(); |
1331 entry->Init(this, type, name, id, size, children_count, retainers_count); | 1318 entry->Init(this, type, name, id, size, children_count, retainers_count); |
1332 return entry; | 1319 return entry; |
1333 } | 1320 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1395 void HeapSnapshot::Print(int max_depth) { | 1382 void HeapSnapshot::Print(int max_depth) { |
1396 root()->Print("", "", max_depth, 0); | 1383 root()->Print("", "", max_depth, 0); |
1397 } | 1384 } |
1398 | 1385 |
1399 | 1386 |
1400 // We split IDs on evens for embedder objects (see | 1387 // We split IDs on evens for embedder objects (see |
1401 // HeapObjectsMap::GenerateId) and odds for native objects. | 1388 // HeapObjectsMap::GenerateId) and odds for native objects. |
1402 const uint64_t HeapObjectsMap::kInternalRootObjectId = 1; | 1389 const uint64_t HeapObjectsMap::kInternalRootObjectId = 1; |
1403 const uint64_t HeapObjectsMap::kGcRootsObjectId = | 1390 const uint64_t HeapObjectsMap::kGcRootsObjectId = |
1404 HeapObjectsMap::kInternalRootObjectId + HeapObjectsMap::kObjectIdStep; | 1391 HeapObjectsMap::kInternalRootObjectId + HeapObjectsMap::kObjectIdStep; |
1405 const uint64_t HeapObjectsMap::kNativesRootObjectId = | 1392 const uint64_t HeapObjectsMap::kGcRootsFirstSubrootId = |
1406 HeapObjectsMap::kGcRootsObjectId + HeapObjectsMap::kObjectIdStep; | 1393 HeapObjectsMap::kGcRootsObjectId + HeapObjectsMap::kObjectIdStep; |
1407 const uint64_t HeapObjectsMap::kGcRootsFirstSubrootId = | |
1408 HeapObjectsMap::kNativesRootObjectId + HeapObjectsMap::kObjectIdStep; | |
1409 const uint64_t HeapObjectsMap::kFirstAvailableObjectId = | 1394 const uint64_t HeapObjectsMap::kFirstAvailableObjectId = |
1410 HeapObjectsMap::kGcRootsFirstSubrootId + | 1395 HeapObjectsMap::kGcRootsFirstSubrootId + |
1411 VisitorSynchronization::kNumberOfSyncTags * HeapObjectsMap::kObjectIdStep; | 1396 VisitorSynchronization::kNumberOfSyncTags * HeapObjectsMap::kObjectIdStep; |
1412 | 1397 |
1413 HeapObjectsMap::HeapObjectsMap() | 1398 HeapObjectsMap::HeapObjectsMap() |
1414 : initial_fill_mode_(true), | 1399 : initial_fill_mode_(true), |
1415 next_id_(kFirstAvailableObjectId), | 1400 next_id_(kFirstAvailableObjectId), |
1416 entries_map_(AddressesMatch), | 1401 entries_map_(AddressesMatch), |
1417 entries_(new List<EntryInfo>()) { } | 1402 entries_(new List<EntryInfo>()) { } |
1418 | 1403 |
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2705 virtual void VisitPointers(Object** start, Object** end) { | 2690 virtual void VisitPointers(Object** start, Object** end) { |
2706 UNREACHABLE(); | 2691 UNREACHABLE(); |
2707 } | 2692 } |
2708 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) { | 2693 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) { |
2709 explorer_->VisitSubtreeWrapper(p, class_id); | 2694 explorer_->VisitSubtreeWrapper(p, class_id); |
2710 } | 2695 } |
2711 private: | 2696 private: |
2712 NativeObjectsExplorer* explorer_; | 2697 NativeObjectsExplorer* explorer_; |
2713 }; | 2698 }; |
2714 | 2699 |
2715 HeapThing const NativeObjectsExplorer::kNativesRootObject = | |
2716 reinterpret_cast<HeapThing>( | |
2717 static_cast<intptr_t>(HeapObjectsMap::kNativesRootObjectId)); | |
2718 | |
2719 | |
2720 NativeObjectsExplorer::NativeObjectsExplorer( | 2700 NativeObjectsExplorer::NativeObjectsExplorer( |
2721 HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress) | 2701 HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress) |
2722 : snapshot_(snapshot), | 2702 : snapshot_(snapshot), |
2723 collection_(snapshot_->collection()), | 2703 collection_(snapshot_->collection()), |
2724 progress_(progress), | 2704 progress_(progress), |
2725 embedder_queried_(false), | 2705 embedder_queried_(false), |
2726 objects_by_info_(RetainedInfosMatch), | 2706 objects_by_info_(RetainedInfosMatch), |
2707 native_groups_(StringsMatch), | |
2727 filler_(NULL) { | 2708 filler_(NULL) { |
2728 } | 2709 } |
2729 | 2710 |
2730 | 2711 |
2731 NativeObjectsExplorer::~NativeObjectsExplorer() { | 2712 NativeObjectsExplorer::~NativeObjectsExplorer() { |
2732 for (HashMap::Entry* p = objects_by_info_.Start(); | 2713 for (HashMap::Entry* p = objects_by_info_.Start(); |
2733 p != NULL; | 2714 p != NULL; |
2734 p = objects_by_info_.Next(p)) { | 2715 p = objects_by_info_.Next(p)) { |
2735 v8::RetainedObjectInfo* info = | 2716 v8::RetainedObjectInfo* info = |
2736 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | 2717 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); |
2737 info->Dispose(); | 2718 info->Dispose(); |
2738 List<HeapObject*>* objects = | 2719 List<HeapObject*>* objects = |
2739 reinterpret_cast<List<HeapObject*>* >(p->value); | 2720 reinterpret_cast<List<HeapObject*>* >(p->value); |
2740 delete objects; | 2721 delete objects; |
2741 } | 2722 } |
2742 } | 2723 } |
2743 | 2724 |
2744 | 2725 |
2745 HeapEntry* NativeObjectsExplorer::AllocateEntry( | 2726 HeapEntry* NativeObjectsExplorer::AllocateEntry( |
2746 HeapThing ptr, int children_count, int retainers_count) { | 2727 HeapThing ptr, int children_count, int retainers_count) { |
2747 if (ptr == kNativesRootObject) { | 2728 v8::RetainedObjectInfo* info = |
2748 return snapshot_->AddNativesRootEntry(children_count, retainers_count); | 2729 reinterpret_cast<v8::RetainedObjectInfo*>(ptr); |
2749 } else { | 2730 intptr_t elements = info->GetElementCount(); |
2750 v8::RetainedObjectInfo* info = | 2731 intptr_t size = info->GetSizeInBytes(); |
2751 reinterpret_cast<v8::RetainedObjectInfo*>(ptr); | 2732 return snapshot_->AddEntry( |
2752 intptr_t elements = info->GetElementCount(); | 2733 HeapEntry::kNative, |
2753 intptr_t size = info->GetSizeInBytes(); | 2734 elements != -1 ? |
2754 return snapshot_->AddEntry( | 2735 collection_->names()->GetFormatted( |
2755 HeapEntry::kNative, | 2736 "%s / %" V8_PTR_PREFIX "d entries", |
2756 elements != -1 ? | 2737 info->GetLabel(), |
2757 collection_->names()->GetFormatted( | 2738 info->GetElementCount()) : |
2758 "%s / %" V8_PTR_PREFIX "d entries", | 2739 collection_->names()->GetCopy(info->GetLabel()), |
2759 info->GetLabel(), | 2740 HeapObjectsMap::GenerateId(info), |
2760 info->GetElementCount()) : | 2741 size != -1 ? static_cast<int>(size) : 0, |
2761 collection_->names()->GetCopy(info->GetLabel()), | 2742 children_count, |
2762 HeapObjectsMap::GenerateId(info), | 2743 retainers_count); |
2763 size != -1 ? static_cast<int>(size) : 0, | |
2764 children_count, | |
2765 retainers_count); | |
2766 } | |
2767 } | 2744 } |
2768 | 2745 |
2769 | 2746 |
2770 void NativeObjectsExplorer::AddRootEntries(SnapshotFillerInterface* filler) { | |
2771 if (EstimateObjectsCount() <= 0) return; | |
2772 filler->AddEntry(kNativesRootObject, this); | |
2773 } | |
2774 | |
2775 | |
2776 int NativeObjectsExplorer::EstimateObjectsCount() { | 2747 int NativeObjectsExplorer::EstimateObjectsCount() { |
2777 FillRetainedObjects(); | 2748 FillRetainedObjects(); |
2778 return objects_by_info_.occupancy(); | 2749 return objects_by_info_.occupancy(); |
2779 } | 2750 } |
2780 | 2751 |
2781 | 2752 |
2782 void NativeObjectsExplorer::FillRetainedObjects() { | 2753 void NativeObjectsExplorer::FillRetainedObjects() { |
2783 if (embedder_queried_) return; | 2754 if (embedder_queried_) return; |
2784 Isolate* isolate = Isolate::Current(); | 2755 Isolate* isolate = Isolate::Current(); |
2785 // Record objects that are joined into ObjectGroups. | 2756 // Record objects that are joined into ObjectGroups. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2834 for (int i = 0; i < objects->length(); ++i) { | 2805 for (int i = 0; i < objects->length(); ++i) { |
2835 SetWrapperNativeReferences(objects->at(i), info); | 2806 SetWrapperNativeReferences(objects->at(i), info); |
2836 } | 2807 } |
2837 } | 2808 } |
2838 SetRootNativesRootReference(); | 2809 SetRootNativesRootReference(); |
2839 filler_ = NULL; | 2810 filler_ = NULL; |
2840 return true; | 2811 return true; |
2841 } | 2812 } |
2842 | 2813 |
2843 | 2814 |
2815 class NativeGroupRetainedObjectInfo : public v8::RetainedObjectInfo { | |
2816 public: | |
2817 explicit NativeGroupRetainedObjectInfo(const char* label) | |
2818 : disposed_(false), | |
2819 hash_(reinterpret_cast<intptr_t>(label)), | |
2820 label_(label) { | |
2821 } | |
2822 | |
2823 virtual ~NativeGroupRetainedObjectInfo() {} | |
2824 virtual void Dispose() { | |
2825 CHECK(!disposed_); | |
2826 disposed_ = true; | |
2827 } | |
2828 virtual bool IsEquivalent(RetainedObjectInfo* other) { | |
2829 return hash_ == other->GetHash() && !strcmp(label_, other->GetLabel()); | |
2830 } | |
2831 virtual intptr_t GetHash() { return hash_; } | |
2832 virtual const char* GetLabel() { return label_; } | |
2833 | |
2834 private: | |
2835 bool disposed_; | |
2836 int hash_; | |
2837 const char* label_; | |
2838 }; | |
2839 | |
2840 | |
2841 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( | |
2842 const char* label) { | |
2843 const char* label_copy = collection_->names()->GetCopy(label); | |
2844 intptr_t hash = HashSequentialString(label_copy, strlen(label_copy), | |
2845 HEAP->HashSeed()); | |
2846 HashMap::Entry* entry = native_groups_.Lookup(const_cast<char*>(label_copy), | |
2847 hash, true); | |
2848 if (entry->value == NULL) | |
2849 entry->value = new NativeGroupRetainedObjectInfo(label); | |
2850 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value); | |
2851 } | |
2852 | |
2853 | |
2844 void NativeObjectsExplorer::SetNativeRootReference( | 2854 void NativeObjectsExplorer::SetNativeRootReference( |
2845 v8::RetainedObjectInfo* info) { | 2855 v8::RetainedObjectInfo* info) { |
2846 HeapEntry* child_entry = filler_->FindOrAddEntry(info, this); | 2856 HeapEntry* child_entry = filler_->FindOrAddEntry(info, this); |
2847 ASSERT(child_entry != NULL); | 2857 ASSERT(child_entry != NULL); |
2858 NativeGroupRetainedObjectInfo* group_info = | |
2859 FindOrAddGroupInfo(info->GetGroupLabel()); | |
2860 HeapEntry* group_entry = filler_->FindOrAddEntry(group_info, this); | |
2848 filler_->SetIndexedAutoIndexReference( | 2861 filler_->SetIndexedAutoIndexReference( |
2849 HeapGraphEdge::kElement, | 2862 HeapGraphEdge::kElement, |
2850 kNativesRootObject, snapshot_->natives_root(), | 2863 group_info, group_entry, |
2851 info, child_entry); | 2864 info, child_entry); |
2852 } | 2865 } |
2853 | 2866 |
2854 | 2867 |
2855 void NativeObjectsExplorer::SetWrapperNativeReferences( | 2868 void NativeObjectsExplorer::SetWrapperNativeReferences( |
2856 HeapObject* wrapper, v8::RetainedObjectInfo* info) { | 2869 HeapObject* wrapper, v8::RetainedObjectInfo* info) { |
2857 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper); | 2870 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper); |
2858 ASSERT(wrapper_entry != NULL); | 2871 ASSERT(wrapper_entry != NULL); |
2859 HeapEntry* info_entry = filler_->FindOrAddEntry(info, this); | 2872 HeapEntry* info_entry = filler_->FindOrAddEntry(info, this); |
2860 ASSERT(info_entry != NULL); | 2873 ASSERT(info_entry != NULL); |
2861 filler_->SetNamedReference(HeapGraphEdge::kInternal, | 2874 filler_->SetNamedReference(HeapGraphEdge::kInternal, |
2862 wrapper, wrapper_entry, | 2875 wrapper, wrapper_entry, |
2863 "native", | 2876 "native", |
2864 info, info_entry); | 2877 info, info_entry); |
2865 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, | 2878 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, |
2866 info, info_entry, | 2879 info, info_entry, |
2867 wrapper, wrapper_entry); | 2880 wrapper, wrapper_entry); |
2868 } | 2881 } |
2869 | 2882 |
2870 | 2883 |
2871 void NativeObjectsExplorer::SetRootNativesRootReference() { | 2884 void NativeObjectsExplorer::SetRootNativesRootReference() { |
mnaganov (inactive)
2012/01/27 09:53:17
Perhaps, you need to rename this to SetRootNativeR
| |
2872 filler_->SetIndexedAutoIndexReference( | 2885 for (HashMap::Entry* entry = native_groups_.Start(); |
2873 HeapGraphEdge::kElement, | 2886 entry; |
2874 V8HeapExplorer::kInternalRootObject, snapshot_->root(), | 2887 entry = native_groups_.Next(entry)) { |
2875 kNativesRootObject, snapshot_->natives_root()); | 2888 NativeGroupRetainedObjectInfo* group_info = |
2889 static_cast<NativeGroupRetainedObjectInfo*>(entry->value); | |
2890 HeapEntry* group_entry = filler_->FindOrAddEntry(group_info, this); | |
2891 ASSERT(group_entry != NULL); | |
2892 filler_->SetIndexedAutoIndexReference( | |
2893 HeapGraphEdge::kElement, | |
mnaganov (inactive)
2012/01/27 09:53:17
I think you should use kInternal and SetNamedAutoI
| |
2894 V8HeapExplorer::kInternalRootObject, snapshot_->root(), | |
2895 group_info, group_entry); | |
2896 } | |
2876 } | 2897 } |
2877 | 2898 |
2878 | 2899 |
2879 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { | 2900 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { |
2880 if (in_groups_.Contains(*p)) return; | 2901 if (in_groups_.Contains(*p)) return; |
2881 Isolate* isolate = Isolate::Current(); | 2902 Isolate* isolate = Isolate::Current(); |
2882 v8::RetainedObjectInfo* info = | 2903 v8::RetainedObjectInfo* info = |
2883 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); | 2904 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); |
2884 if (info == NULL) return; | 2905 if (info == NULL) return; |
2885 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); | 2906 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3100 progress_total_ = ( | 3121 progress_total_ = ( |
3101 v8_heap_explorer_.EstimateObjectsCount(&iterator) + | 3122 v8_heap_explorer_.EstimateObjectsCount(&iterator) + |
3102 dom_explorer_.EstimateObjectsCount()) * iterations_count; | 3123 dom_explorer_.EstimateObjectsCount()) * iterations_count; |
3103 progress_counter_ = 0; | 3124 progress_counter_ = 0; |
3104 } | 3125 } |
3105 | 3126 |
3106 | 3127 |
3107 bool HeapSnapshotGenerator::CountEntriesAndReferences() { | 3128 bool HeapSnapshotGenerator::CountEntriesAndReferences() { |
3108 SnapshotCounter counter(&entries_); | 3129 SnapshotCounter counter(&entries_); |
3109 v8_heap_explorer_.AddRootEntries(&counter); | 3130 v8_heap_explorer_.AddRootEntries(&counter); |
3110 dom_explorer_.AddRootEntries(&counter); | |
3111 return | 3131 return |
3112 v8_heap_explorer_.IterateAndExtractReferences(&counter) && | 3132 v8_heap_explorer_.IterateAndExtractReferences(&counter) && |
3113 dom_explorer_.IterateAndExtractReferences(&counter); | 3133 dom_explorer_.IterateAndExtractReferences(&counter); |
3114 } | 3134 } |
3115 | 3135 |
3116 | 3136 |
3117 bool HeapSnapshotGenerator::FillReferences() { | 3137 bool HeapSnapshotGenerator::FillReferences() { |
3118 SnapshotFiller filler(snapshot_, &entries_); | 3138 SnapshotFiller filler(snapshot_, &entries_); |
3119 return | 3139 return |
3120 v8_heap_explorer_.IterateAndExtractReferences(&filler) && | 3140 v8_heap_explorer_.IterateAndExtractReferences(&filler) && |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3638 | 3658 |
3639 | 3659 |
3640 void HeapSnapshotJSONSerializer::SortHashMap( | 3660 void HeapSnapshotJSONSerializer::SortHashMap( |
3641 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3661 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3642 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3662 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3643 sorted_entries->Add(p); | 3663 sorted_entries->Add(p); |
3644 sorted_entries->Sort(SortUsingEntryValue); | 3664 sorted_entries->Sort(SortUsingEntryValue); |
3645 } | 3665 } |
3646 | 3666 |
3647 } } // namespace v8::internal | 3667 } } // namespace v8::internal |
OLD | NEW |