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

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

Issue 9594020: Fix the heap profiler crash caused by memory layout changes between passes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 9 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 974 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 } id_adaptor = {id}; 985 } id_adaptor = {id};
986 id_ = id_adaptor.stored_id; 986 id_ = id_adaptor.stored_id;
987 } 987 }
988 988
989 989
990 void HeapEntry::SetNamedReference(HeapGraphEdge::Type type, 990 void HeapEntry::SetNamedReference(HeapGraphEdge::Type type,
991 int child_index, 991 int child_index,
992 const char* name, 992 const char* name,
993 HeapEntry* entry, 993 HeapEntry* entry,
994 int retainer_index) { 994 int retainer_index) {
995 children_arr()[child_index].Init(child_index, type, name, entry); 995 children()[child_index].Init(child_index, type, name, entry);
996 entry->retainers_arr()[retainer_index] = children_arr() + child_index; 996 entry->retainers()[retainer_index] = children_arr() + child_index;
997 } 997 }
998 998
999 999
1000 void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type, 1000 void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type,
1001 int child_index, 1001 int child_index,
1002 int index, 1002 int index,
1003 HeapEntry* entry, 1003 HeapEntry* entry,
1004 int retainer_index) { 1004 int retainer_index) {
1005 children_arr()[child_index].Init(child_index, type, index, entry); 1005 children()[child_index].Init(child_index, type, index, entry);
1006 entry->retainers_arr()[retainer_index] = children_arr() + child_index; 1006 entry->retainers()[retainer_index] = children_arr() + child_index;
1007 } 1007 }
1008 1008
1009 1009
1010 void HeapEntry::SetUnidirElementReference( 1010 void HeapEntry::SetUnidirElementReference(
1011 int child_index, int index, HeapEntry* entry) { 1011 int child_index, int index, HeapEntry* entry) {
1012 children_arr()[child_index].Init(child_index, index, entry); 1012 children()[child_index].Init(child_index, index, entry);
1013 } 1013 }
1014 1014
1015 1015
1016 Handle<HeapObject> HeapEntry::GetHeapObject() { 1016 Handle<HeapObject> HeapEntry::GetHeapObject() {
1017 return snapshot_->collection()->FindHeapObjectById(id()); 1017 return snapshot_->collection()->FindHeapObjectById(id());
1018 } 1018 }
1019 1019
1020 1020
1021 void HeapEntry::Print( 1021 void HeapEntry::Print(
1022 const char* prefix, const char* edge_name, int max_depth, int indent) { 1022 const char* prefix, const char* edge_name, int max_depth, int indent) {
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 if (object == kInternalRootObject) { 1664 if (object == kInternalRootObject) {
1665 ASSERT(retainers_count == 0); 1665 ASSERT(retainers_count == 0);
1666 return snapshot_->AddRootEntry(children_count); 1666 return snapshot_->AddRootEntry(children_count);
1667 } else if (object == kGcRootsObject) { 1667 } else if (object == kGcRootsObject) {
1668 return snapshot_->AddGcRootsEntry(children_count, retainers_count); 1668 return snapshot_->AddGcRootsEntry(children_count, retainers_count);
1669 } else if (object >= kFirstGcSubrootObject && object < kLastGcSubrootObject) { 1669 } else if (object >= kFirstGcSubrootObject && object < kLastGcSubrootObject) {
1670 return snapshot_->AddGcSubrootEntry( 1670 return snapshot_->AddGcSubrootEntry(
1671 GetGcSubrootOrder(object), 1671 GetGcSubrootOrder(object),
1672 children_count, 1672 children_count,
1673 retainers_count); 1673 retainers_count);
1674 } else if (object->IsJSGlobalObject()) {
mnaganov (inactive) 2012/03/05 16:21:58 Will this fall through down to the generic case th
alexeif 2012/03/05 17:35:31 It should fall into JSObject at 1703 which is the
1675 const char* tag = objects_tags_.GetTag(object);
1676 const char* name = collection_->names()->GetName(
1677 GetConstructorName(JSObject::cast(object)));
1678 if (tag != NULL) {
1679 name = collection_->names()->GetFormatted("%s / %s", name, tag);
1680 }
1681 return AddEntry(object,
1682 HeapEntry::kObject,
1683 name,
1684 children_count,
1685 retainers_count);
1686 } else if (object->IsJSFunction()) { 1674 } else if (object->IsJSFunction()) {
1687 JSFunction* func = JSFunction::cast(object); 1675 JSFunction* func = JSFunction::cast(object);
1688 SharedFunctionInfo* shared = func->shared(); 1676 SharedFunctionInfo* shared = func->shared();
1689 const char* name = shared->bound() ? "native_bind" : 1677 const char* name = shared->bound() ? "native_bind" :
1690 collection_->names()->GetName(String::cast(shared->name())); 1678 collection_->names()->GetName(String::cast(shared->name()));
1691 return AddEntry(object, 1679 return AddEntry(object,
1692 HeapEntry::kClosure, 1680 HeapEntry::kClosure,
1693 name, 1681 name,
1694 children_count, 1682 children_count,
1695 retainers_count); 1683 retainers_count);
1696 } else if (object->IsJSRegExp()) { 1684 } else if (object->IsJSRegExp()) {
1697 JSRegExp* re = JSRegExp::cast(object); 1685 JSRegExp* re = JSRegExp::cast(object);
1698 return AddEntry(object, 1686 return AddEntry(object,
1699 HeapEntry::kRegExp, 1687 HeapEntry::kRegExp,
1700 collection_->names()->GetName(re->Pattern()), 1688 collection_->names()->GetName(re->Pattern()),
1701 children_count, 1689 children_count,
1702 retainers_count); 1690 retainers_count);
1703 } else if (object->IsJSObject()) { 1691 } else if (object->IsJSObject()) {
1704 return AddEntry(object, 1692 return AddEntry(object,
1705 HeapEntry::kObject, 1693 HeapEntry::kObject,
1706 collection_->names()->GetName( 1694 "",
1707 GetConstructorName(JSObject::cast(object))),
1708 children_count, 1695 children_count,
1709 retainers_count); 1696 retainers_count);
1710 } else if (object->IsString()) { 1697 } else if (object->IsString()) {
1711 return AddEntry(object, 1698 return AddEntry(object,
1712 HeapEntry::kString, 1699 HeapEntry::kString,
1713 collection_->names()->GetName(String::cast(object)), 1700 collection_->names()->GetName(String::cast(object)),
1714 children_count, 1701 children_count,
1715 retainers_count); 1702 retainers_count);
1716 } else if (object->IsCode()) { 1703 } else if (object->IsCode()) {
1717 return AddEntry(object, 1704 return AddEntry(object,
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
2342 RootsReferencesExtractor extractor; 2329 RootsReferencesExtractor extractor;
2343 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); 2330 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG);
2344 extractor.SetCollectingAllReferences(); 2331 extractor.SetCollectingAllReferences();
2345 heap_->IterateRoots(&extractor, VISIT_ALL); 2332 heap_->IterateRoots(&extractor, VISIT_ALL);
2346 extractor.FillReferences(this); 2333 extractor.FillReferences(this);
2347 filler_ = NULL; 2334 filler_ = NULL;
2348 return progress_->ProgressReport(false); 2335 return progress_->ProgressReport(false);
2349 } 2336 }
2350 2337
2351 2338
2339 bool V8HeapExplorer::IterateAndSetObjectNames(SnapshotFillerInterface* filler) {
2340 HeapIterator iterator(HeapIterator::kFilterUnreachable);
2341 filler_ = filler;
2342 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
2343 SetObjectName(obj);
2344 }
2345 return true;
2346 }
2347
2348
2349 void V8HeapExplorer::SetObjectName(HeapObject* object) {
2350 if (!object->IsJSObject() || object->IsJSRegExp() || object->IsJSFunction()) {
2351 return;
2352 }
2353 const char* name = collection_->names()->GetName(
2354 GetConstructorName(JSObject::cast(object)));
2355 if (object->IsJSGlobalObject()) {
2356 const char* tag = objects_tags_.GetTag(object);
2357 if (tag != NULL) {
2358 name = collection_->names()->GetFormatted("%s / %s", name, tag);
2359 }
2360 }
2361 GetEntry(object)->set_name(name);
2362 }
2363
2364
2352 void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj, 2365 void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
2353 HeapEntry* parent_entry, 2366 HeapEntry* parent_entry,
2354 String* reference_name, 2367 String* reference_name,
2355 Object* child_obj) { 2368 Object* child_obj) {
2356 HeapEntry* child_entry = GetEntry(child_obj); 2369 HeapEntry* child_entry = GetEntry(child_obj);
2357 if (child_entry != NULL) { 2370 if (child_entry != NULL) {
2358 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, 2371 filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
2359 parent_obj, 2372 parent_obj,
2360 parent_entry, 2373 parent_entry,
2361 collection_->names()->GetName(reference_name), 2374 collection_->names()->GetName(reference_name),
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
2900 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { 2913 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) {
2901 if (in_groups_.Contains(*p)) return; 2914 if (in_groups_.Contains(*p)) return;
2902 Isolate* isolate = Isolate::Current(); 2915 Isolate* isolate = Isolate::Current();
2903 v8::RetainedObjectInfo* info = 2916 v8::RetainedObjectInfo* info =
2904 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); 2917 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p);
2905 if (info == NULL) return; 2918 if (info == NULL) return;
2906 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); 2919 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p));
2907 } 2920 }
2908 2921
2909 2922
2910 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
2911 v8::ActivityControl* control)
2912 : snapshot_(snapshot),
2913 control_(control),
2914 v8_heap_explorer_(snapshot_, this),
2915 dom_explorer_(snapshot_, this) {
2916 }
2917
2918
2919 class SnapshotCounter : public SnapshotFillerInterface { 2923 class SnapshotCounter : public SnapshotFillerInterface {
2920 public: 2924 public:
2921 explicit SnapshotCounter(HeapEntriesMap* entries) : entries_(entries) { } 2925 explicit SnapshotCounter(HeapEntriesMap* entries) : entries_(entries) { }
2922 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { 2926 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
2923 entries_->Pair(ptr, allocator, HeapEntriesMap::kHeapEntryPlaceholder); 2927 entries_->Pair(ptr, allocator, HeapEntriesMap::kHeapEntryPlaceholder);
2924 return HeapEntriesMap::kHeapEntryPlaceholder; 2928 return HeapEntriesMap::kHeapEntryPlaceholder;
2925 } 2929 }
2926 HeapEntry* FindEntry(HeapThing ptr) { 2930 HeapEntry* FindEntry(HeapThing ptr) {
2927 return entries_->Map(ptr); 2931 return entries_->Map(ptr);
2928 } 2932 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3033 retainer_index); 3037 retainer_index);
3034 } 3038 }
3035 3039
3036 private: 3040 private:
3037 HeapSnapshot* snapshot_; 3041 HeapSnapshot* snapshot_;
3038 HeapSnapshotsCollection* collection_; 3042 HeapSnapshotsCollection* collection_;
3039 HeapEntriesMap* entries_; 3043 HeapEntriesMap* entries_;
3040 }; 3044 };
3041 3045
3042 3046
3047 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
3048 v8::ActivityControl* control)
3049 : snapshot_(snapshot),
3050 control_(control),
3051 v8_heap_explorer_(snapshot_, this),
3052 dom_explorer_(snapshot_, this) {
3053 }
3054
3055
3043 bool HeapSnapshotGenerator::GenerateSnapshot() { 3056 bool HeapSnapshotGenerator::GenerateSnapshot() {
3044 v8_heap_explorer_.TagGlobalObjects(); 3057 v8_heap_explorer_.TagGlobalObjects();
3045 3058
3046 // TODO(1562) Profiler assumes that any object that is in the heap after 3059 // TODO(1562) Profiler assumes that any object that is in the heap after
3047 // full GC is reachable from the root when computing dominators. 3060 // full GC is reachable from the root when computing dominators.
3048 // This is not true for weakly reachable objects. 3061 // This is not true for weakly reachable objects.
3049 // As a temporary solution we call GC twice. 3062 // As a temporary solution we call GC twice.
3050 Isolate::Current()->heap()->CollectAllGarbage( 3063 Isolate::Current()->heap()->CollectAllGarbage(
3051 Heap::kMakeHeapIterableMask, 3064 Heap::kMakeHeapIterableMask,
3052 "HeapSnapshotGenerator::GenerateSnapshot"); 3065 "HeapSnapshotGenerator::GenerateSnapshot");
(...skipping 24 matching lines...) Expand all
3077 debug_heap->Verify(); 3090 debug_heap->Verify();
3078 #endif 3091 #endif
3079 3092
3080 // Pass 1. Iterate heap contents to count entries and references. 3093 // Pass 1. Iterate heap contents to count entries and references.
3081 if (!CountEntriesAndReferences()) return false; 3094 if (!CountEntriesAndReferences()) return false;
3082 3095
3083 #ifdef DEBUG 3096 #ifdef DEBUG
3084 debug_heap->Verify(); 3097 debug_heap->Verify();
3085 #endif 3098 #endif
3086 3099
3087 // Allocate and fill entries in the snapshot, allocate references. 3100 // Allocate memory for entries and references.
3088 snapshot_->AllocateEntries(entries_.entries_count(), 3101 snapshot_->AllocateEntries(entries_.entries_count(),
3089 entries_.total_children_count(), 3102 entries_.total_children_count(),
3090 entries_.total_retainers_count()); 3103 entries_.total_retainers_count());
3104
3105 // Allocate heap objects to entries hash map.
3091 entries_.AllocateEntries(); 3106 entries_.AllocateEntries();
3092 3107
3093 // Pass 2. Fill references. 3108 // Pass 2. Fill references.
3094 if (!FillReferences()) return false; 3109 if (!FillReferences()) return false;
3095 3110
3096 if (!SetEntriesDominators()) return false; 3111 if (!SetEntriesDominators()) return false;
3097 if (!CalculateRetainedSizes()) return false; 3112 if (!CalculateRetainedSizes()) return false;
3098 3113
3099 progress_counter_ = progress_total_; 3114 progress_counter_ = progress_total_;
3100 if (!ProgressReport(true)) return false; 3115 if (!ProgressReport(true)) return false;
(...skipping 24 matching lines...) Expand all
3125 progress_total_ = ( 3140 progress_total_ = (
3126 v8_heap_explorer_.EstimateObjectsCount(&iterator) + 3141 v8_heap_explorer_.EstimateObjectsCount(&iterator) +
3127 dom_explorer_.EstimateObjectsCount()) * iterations_count; 3142 dom_explorer_.EstimateObjectsCount()) * iterations_count;
3128 progress_counter_ = 0; 3143 progress_counter_ = 0;
3129 } 3144 }
3130 3145
3131 3146
3132 bool HeapSnapshotGenerator::CountEntriesAndReferences() { 3147 bool HeapSnapshotGenerator::CountEntriesAndReferences() {
3133 SnapshotCounter counter(&entries_); 3148 SnapshotCounter counter(&entries_);
3134 v8_heap_explorer_.AddRootEntries(&counter); 3149 v8_heap_explorer_.AddRootEntries(&counter);
3135 return 3150 return v8_heap_explorer_.IterateAndExtractReferences(&counter)
3136 v8_heap_explorer_.IterateAndExtractReferences(&counter) && 3151 && dom_explorer_.IterateAndExtractReferences(&counter);
3137 dom_explorer_.IterateAndExtractReferences(&counter);
3138 } 3152 }
3139 3153
3140 3154
3141 bool HeapSnapshotGenerator::FillReferences() { 3155 bool HeapSnapshotGenerator::FillReferences() {
3142 SnapshotFiller filler(snapshot_, &entries_); 3156 SnapshotFiller filler(snapshot_, &entries_);
3143 return 3157 // IterateAndExtractReferences cannot set object names because
3144 v8_heap_explorer_.IterateAndExtractReferences(&filler) && 3158 // it makes call to JSObject::LocalLookupRealNamedProperty which
3145 dom_explorer_.IterateAndExtractReferences(&filler); 3159 // in turn may relocate objects in property maps thus changing the heap
3160 // layout and affecting retainer counts. This is not acceptable because
3161 // number of retainers must not change between count and fill passes.
3162 // To avoid this there's a separate postpass that set object names.
3163 return v8_heap_explorer_.IterateAndExtractReferences(&filler)
3164 && dom_explorer_.IterateAndExtractReferences(&filler)
3165 && v8_heap_explorer_.IterateAndSetObjectNames(&filler);
mnaganov (inactive) 2012/03/05 16:21:58 As we have discussed offline, please split Generat
alexeif 2012/03/05 17:35:31 I checked the AssertNoAllocation class and it does
3146 } 3166 }
3147 3167
3148 3168
3149 void HeapSnapshotGenerator::FillReversePostorderIndexes( 3169 void HeapSnapshotGenerator::FillReversePostorderIndexes(
3150 Vector<HeapEntry*>* entries) { 3170 Vector<HeapEntry*>* entries) {
3151 snapshot_->ClearPaint(); 3171 snapshot_->ClearPaint();
3152 int current_entry = 0; 3172 int current_entry = 0;
3153 List<HeapEntry*> nodes_to_visit; 3173 List<HeapEntry*> nodes_to_visit;
3154 nodes_to_visit.Add(snapshot_->root()); 3174 nodes_to_visit.Add(snapshot_->root());
3155 snapshot_->root()->paint(); 3175 snapshot_->root()->paint();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3191 // Softw. Pract. Exper. 4 (2001), pp. 1-10. 3211 // Softw. Pract. Exper. 4 (2001), pp. 1-10.
3192 bool HeapSnapshotGenerator::BuildDominatorTree( 3212 bool HeapSnapshotGenerator::BuildDominatorTree(
3193 const Vector<HeapEntry*>& entries, 3213 const Vector<HeapEntry*>& entries,
3194 Vector<int>* dominators) { 3214 Vector<int>* dominators) {
3195 if (entries.length() == 0) return true; 3215 if (entries.length() == 0) return true;
3196 const int entries_length = entries.length(), root_index = entries_length - 1; 3216 const int entries_length = entries.length(), root_index = entries_length - 1;
3197 static const int kNoDominator = -1; 3217 static const int kNoDominator = -1;
3198 for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator; 3218 for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator;
3199 (*dominators)[root_index] = root_index; 3219 (*dominators)[root_index] = root_index;
3200 3220
3201 // The painted flag is used to mark entries that need to be recalculated 3221 // The affected array is used to mark entries which dominators
3202 // because of dominators change among their retainers. 3222 // have to be racalculated because of changes in their retainers.
3203 for (int i = 0; i < entries_length; ++i) entries[i]->clear_paint(); 3223 ScopedVector<bool> affected(entries_length);
3204 3224 for (int i = 0; i < affected.length(); ++i) affected[i] = false;
3205 // Mark the root direct children as affected. 3225 // Mark the root direct children as affected.
3206 Vector<HeapGraphEdge> children = entries[root_index]->children(); 3226 Vector<HeapGraphEdge> children = entries[root_index]->children();
3207 for (int i = 0; i < children.length(); ++i) children[i].to()->paint(); 3227 for (int i = 0; i < children.length(); ++i) {
3228 affected[children[i].to()->ordered_index()] = true;
3229 }
3208 3230
3209 bool changed = true; 3231 bool changed = true;
3210 while (changed) { 3232 while (changed) {
3211 changed = false; 3233 changed = false;
3234 if (!ProgressReport(true)) return false;
3212 for (int i = root_index - 1; i >= 0; --i) { 3235 for (int i = root_index - 1; i >= 0; --i) {
3236 if (!affected[i]) continue;
3237 affected[i] = false;
3213 // If dominator of the entry has already been set to root, 3238 // If dominator of the entry has already been set to root,
3214 // then it can't propagate any further. 3239 // then it can't propagate any further.
3215 if ((*dominators)[i] == root_index) continue; 3240 if ((*dominators)[i] == root_index) continue;
3216 HeapEntry* entry = entries[i];
3217 if (!entry->painted()) continue;
3218 entry->clear_paint();
3219 int new_idom_index = kNoDominator; 3241 int new_idom_index = kNoDominator;
3220 Vector<HeapGraphEdge*> rets = entry->retainers(); 3242 Vector<HeapGraphEdge*> rets = entries[i]->retainers();
3221 for (int j = 0; j < rets.length(); ++j) { 3243 for (int j = 0; j < rets.length(); ++j) {
3222 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; 3244 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue;
3223 int ret_index = rets[j]->From()->ordered_index(); 3245 int ret_index = rets[j]->From()->ordered_index();
3224 if (dominators->at(ret_index) != kNoDominator) { 3246 if (dominators->at(ret_index) != kNoDominator) {
3225 new_idom_index = new_idom_index == kNoDominator 3247 new_idom_index = new_idom_index == kNoDominator
3226 ? ret_index 3248 ? ret_index
3227 : Intersect(ret_index, new_idom_index, *dominators); 3249 : Intersect(ret_index, new_idom_index, *dominators);
3228 // If idom has already reached the root, it doesn't make sense 3250 // If idom has already reached the root, it doesn't make sense
3229 // to check other retainers. 3251 // to check other retainers.
3230 if (new_idom_index == root_index) break; 3252 if (new_idom_index == root_index) break;
3231 } 3253 }
3232 } 3254 }
3233 if (new_idom_index != kNoDominator 3255 if (new_idom_index != kNoDominator
3234 && dominators->at(i) != new_idom_index) { 3256 && dominators->at(i) != new_idom_index) {
3235 (*dominators)[i] = new_idom_index; 3257 (*dominators)[i] = new_idom_index;
3236 changed = true; 3258 changed = true;
3237 Vector<HeapGraphEdge> children = entries[i]->children(); 3259 Vector<HeapGraphEdge> children = entries[i]->children();
3238 for (int j = 0; j < children.length(); ++j) children[j].to()->paint(); 3260 for (int j = 0; j < children.length(); ++j) {
3261 affected[children[j].to()->ordered_index()] = true;
3262 }
3239 } 3263 }
3240 } 3264 }
3241 } 3265 }
3242 return true; 3266 return true;
3243 } 3267 }
3244 3268
3245 3269
3246 bool HeapSnapshotGenerator::SetEntriesDominators() { 3270 bool HeapSnapshotGenerator::SetEntriesDominators() {
3247 // This array is used for maintaining reverse postorder of nodes. 3271 // This array is used for maintaining reverse postorder of nodes.
3248 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length()); 3272 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length());
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
3698 3722
3699 3723
3700 void HeapSnapshotJSONSerializer::SortHashMap( 3724 void HeapSnapshotJSONSerializer::SortHashMap(
3701 HashMap* map, List<HashMap::Entry*>* sorted_entries) { 3725 HashMap* map, List<HashMap::Entry*>* sorted_entries) {
3702 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) 3726 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p))
3703 sorted_entries->Add(p); 3727 sorted_entries->Add(p);
3704 sorted_entries->Sort(SortUsingEntryValue); 3728 sorted_entries->Sort(SortUsingEntryValue);
3705 } 3729 }
3706 3730
3707 } } // namespace v8::internal 3731 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698