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 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 |