Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/profile-generator.cc

Issue 9223009: Detailed heap snapshot usability improvement. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: cosmetic changes Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/profile-generator.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2828 p = objects_by_info_.Next(p)) { 2799 p = objects_by_info_.Next(p)) {
2829 v8::RetainedObjectInfo* info = 2800 v8::RetainedObjectInfo* info =
2830 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); 2801 reinterpret_cast<v8::RetainedObjectInfo*>(p->key);
2831 SetNativeRootReference(info); 2802 SetNativeRootReference(info);
2832 List<HeapObject*>* objects = 2803 List<HeapObject*>* objects =
2833 reinterpret_cast<List<HeapObject*>* >(p->value); 2804 reinterpret_cast<List<HeapObject*>* >(p->value);
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 SetRootNativeRootsReference();
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);
2848 filler_->SetIndexedAutoIndexReference( 2858 NativeGroupRetainedObjectInfo* group_info =
2849 HeapGraphEdge::kElement, 2859 FindOrAddGroupInfo(info->GetGroupLabel());
2850 kNativesRootObject, snapshot_->natives_root(), 2860 HeapEntry* group_entry = filler_->FindOrAddEntry(group_info, this);
2861 filler_->SetNamedAutoIndexReference(
2862 HeapGraphEdge::kInternal,
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::SetRootNativeRootsReference() {
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,
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
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
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
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698