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

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

Issue 9372105: Speedup dominators construction in heap snapshot. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 10 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 3253 matching lines...) Expand 10 before | Expand all | Expand 10 after
3264 if (!has_new_edges) { 3264 if (!has_new_edges) {
3265 entry->set_ordered_index(current_entry); 3265 entry->set_ordered_index(current_entry);
3266 (*entries)[current_entry++] = entry; 3266 (*entries)[current_entry++] = entry;
3267 nodes_to_visit.RemoveLast(); 3267 nodes_to_visit.RemoveLast();
3268 } 3268 }
3269 } 3269 }
3270 ASSERT_EQ(current_entry, entries->length()); 3270 ASSERT_EQ(current_entry, entries->length());
3271 } 3271 }
3272 3272
3273 3273
3274 static int Intersect(int i1, int i2, const Vector<HeapEntry*>& dominators) { 3274 static int Intersect(int i1, int i2, const Vector<int>& dominators) {
3275 int finger1 = i1, finger2 = i2; 3275 int finger1 = i1, finger2 = i2;
3276 while (finger1 != finger2) { 3276 while (finger1 != finger2) {
3277 while (finger1 < finger2) finger1 = dominators[finger1]->ordered_index(); 3277 while (finger1 < finger2) finger1 = dominators[finger1];
3278 while (finger2 < finger1) finger2 = dominators[finger2]->ordered_index(); 3278 while (finger2 < finger1) finger2 = dominators[finger2];
3279 } 3279 }
3280 return finger1; 3280 return finger1;
3281 } 3281 }
3282 3282
3283
3283 // The algorithm is based on the article: 3284 // The algorithm is based on the article:
3284 // K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm" 3285 // K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm"
3285 // Softw. Pract. Exper. 4 (2001), pp. 1-10. 3286 // Softw. Pract. Exper. 4 (2001), pp. 1-10.
3286 bool HeapSnapshotGenerator::BuildDominatorTree( 3287 bool HeapSnapshotGenerator::BuildDominatorTree(
3287 const Vector<HeapEntry*>& entries, 3288 const Vector<HeapEntry*>& entries,
3288 Vector<HeapEntry*>* dominators) { 3289 Vector<int>* dominators) {
3289 if (entries.length() == 0) return true; 3290 if (entries.length() == 0) return true;
3290 const int entries_length = entries.length(), root_index = entries_length - 1; 3291 const int entries_length = entries.length(), root_index = entries_length - 1;
3291 for (int i = 0; i < root_index; ++i) (*dominators)[i] = NULL; 3292 static const int kNoDominator = -1;
3292 (*dominators)[root_index] = entries[root_index]; 3293 for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator;
3294 (*dominators)[root_index] = root_index;
3295
3296 // We use time_stamps array to stamp entries with the iteration number
3297 // when the dominance for the entry has been updated.
3298 ScopedVector<int> time_stamps(entries_length);
3299 for (int i = 0; i < entries_length; ++i) time_stamps[i] = -1;
3300 Vector<HeapGraphEdge> children = entries[root_index]->children();
3301 for (int i = 0; i < children.length(); ++i) {
3302 // Mark the root direct children as affected on iteration zero.
3303 time_stamps[children[i].to()->ordered_index()] = 0;
3304 }
3305
3293 int changed = 1; 3306 int changed = 1;
3307 int iteration = 0;
3294 const int base_progress_counter = progress_counter_; 3308 const int base_progress_counter = progress_counter_;
3295 while (changed != 0) { 3309 while (changed != 0) {
3310 ++iteration;
3296 changed = 0; 3311 changed = 0;
3297 for (int i = root_index - 1; i >= 0; --i) { 3312 for (int i = root_index - 1; i >= 0; --i) {
3298 HeapEntry* new_idom = NULL; 3313 // If dominator of the entry has already been set to root,
3314 // then it can't propagate any further.
3315 if ((*dominators)[i] == root_index) continue;
3316 // If no retainers of the entry had been updated on current
3317 // or previous iteration, then this entry is not affected.
3318 if (time_stamps[i] < iteration - 1) continue;
3319 int new_idom_index = kNoDominator;
3299 Vector<HeapGraphEdge*> rets = entries[i]->retainers(); 3320 Vector<HeapGraphEdge*> rets = entries[i]->retainers();
3300 int j = 0; 3321 for (int j = 0; j < rets.length(); ++j) {
3301 for (; j < rets.length(); ++j) {
3302 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; 3322 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue;
3303 HeapEntry* ret = rets[j]->From(); 3323 int ret_index = rets[j]->From()->ordered_index();
3304 if (dominators->at(ret->ordered_index()) != NULL) { 3324 if (dominators->at(ret_index) != kNoDominator) {
3305 new_idom = ret; 3325 new_idom_index = new_idom_index == kNoDominator
3306 break; 3326 ? ret_index
3327 : Intersect(ret_index, new_idom_index, *dominators);
3328 // If idom has already reached the root, it doesn't make sense
3329 // to check other retainers.
3330 if (new_idom_index == root_index) break;
3307 } 3331 }
3308 } 3332 }
3309 for (++j; j < rets.length(); ++j) { 3333 if (new_idom_index != kNoDominator
3310 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; 3334 && dominators->at(i) != new_idom_index) {
3311 HeapEntry* ret = rets[j]->From(); 3335 (*dominators)[i] = new_idom_index;
3312 if (dominators->at(ret->ordered_index()) != NULL) { 3336 ++changed;
3313 new_idom = entries[Intersect(ret->ordered_index(), 3337 Vector<HeapGraphEdge> children = entries[i]->children();
3314 new_idom->ordered_index(), 3338 for (int j = 0; j < children.length(); ++j) {
3315 *dominators)]; 3339 time_stamps[children[j].to()->ordered_index()] = iteration;
3316 } 3340 }
3317 } 3341 }
3318 if (new_idom != NULL && dominators->at(i) != new_idom) {
3319 (*dominators)[i] = new_idom;
3320 ++changed;
3321 }
3322 } 3342 }
3323 int remaining = entries_length - changed; 3343 int remaining = entries_length - changed;
3324 if (remaining < 0) remaining = 0; 3344 ASSERT(remaining >= 0);
3325 progress_counter_ = base_progress_counter + remaining; 3345 progress_counter_ = base_progress_counter + remaining;
3326 if (!ProgressReport(true)) return false; 3346 if (!ProgressReport(true)) return false;
3327 } 3347 }
3328 return true; 3348 return true;
3329 } 3349 }
3330 3350
3331 3351
3332 bool HeapSnapshotGenerator::SetEntriesDominators() { 3352 bool HeapSnapshotGenerator::SetEntriesDominators() {
3333 // This array is used for maintaining reverse postorder of nodes. 3353 // This array is used for maintaining reverse postorder of nodes.
3334 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length()); 3354 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length());
3335 FillReversePostorderIndexes(&ordered_entries); 3355 FillReversePostorderIndexes(&ordered_entries);
3336 ScopedVector<HeapEntry*> dominators(ordered_entries.length()); 3356 ScopedVector<int> dominators(ordered_entries.length());
3337 if (!BuildDominatorTree(ordered_entries, &dominators)) return false; 3357 if (!BuildDominatorTree(ordered_entries, &dominators)) return false;
3338 for (int i = 0; i < ordered_entries.length(); ++i) { 3358 for (int i = 0; i < ordered_entries.length(); ++i) {
3339 ASSERT(dominators[i] != NULL); 3359 ASSERT(dominators[i] >= 0);
3340 ordered_entries[i]->set_dominator(dominators[i]); 3360 ordered_entries[i]->set_dominator(ordered_entries[dominators[i]]);
3341 } 3361 }
3342 return true; 3362 return true;
3343 } 3363 }
3344 3364
3345 3365
3346 bool HeapSnapshotGenerator::ApproximateRetainedSizes() { 3366 bool HeapSnapshotGenerator::ApproximateRetainedSizes() {
3347 // As for the dominators tree we only know parent nodes, not 3367 // As for the dominators tree we only know parent nodes, not
3348 // children, to sum up total sizes we "bubble" node's self size 3368 // children, to sum up total sizes we "bubble" node's self size
3349 // adding it to all of its parents. 3369 // adding it to all of its parents.
3350 for (int i = 0; i < snapshot_->entries()->length(); ++i) { 3370 for (int i = 0; i < snapshot_->entries()->length(); ++i) {
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
3786 3806
3787 3807
3788 void HeapSnapshotJSONSerializer::SortHashMap( 3808 void HeapSnapshotJSONSerializer::SortHashMap(
3789 HashMap* map, List<HashMap::Entry*>* sorted_entries) { 3809 HashMap* map, List<HashMap::Entry*>* sorted_entries) {
3790 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) 3810 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p))
3791 sorted_entries->Add(p); 3811 sorted_entries->Add(p);
3792 sorted_entries->Sort(SortUsingEntryValue); 3812 sorted_entries->Sort(SortUsingEntryValue);
3793 } 3813 }
3794 3814
3795 } } // namespace v8::internal 3815 } } // 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