OLD | NEW |
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 3275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3286 // Softw. Pract. Exper. 4 (2001), pp. 1-10. | 3286 // Softw. Pract. Exper. 4 (2001), pp. 1-10. |
3287 bool HeapSnapshotGenerator::BuildDominatorTree( | 3287 bool HeapSnapshotGenerator::BuildDominatorTree( |
3288 const Vector<HeapEntry*>& entries, | 3288 const Vector<HeapEntry*>& entries, |
3289 Vector<int>* dominators) { | 3289 Vector<int>* dominators) { |
3290 if (entries.length() == 0) return true; | 3290 if (entries.length() == 0) return true; |
3291 const int entries_length = entries.length(), root_index = entries_length - 1; | 3291 const int entries_length = entries.length(), root_index = entries_length - 1; |
3292 static const int kNoDominator = -1; | 3292 static const int kNoDominator = -1; |
3293 for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator; | 3293 for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator; |
3294 (*dominators)[root_index] = root_index; | 3294 (*dominators)[root_index] = root_index; |
3295 | 3295 |
3296 // We use time_stamps array to stamp entries with the iteration number | 3296 // The affected array is used to mark those entries that may |
3297 // when the dominance for the entry has been updated. | 3297 // be affected because of dominators change among their retainers. |
3298 ScopedVector<int> time_stamps(entries_length); | 3298 ScopedVector<bool> affected(entries_length); |
3299 for (int i = 0; i < entries_length; ++i) time_stamps[i] = -1; | 3299 for (int i = 0; i < entries_length; ++i) affected[i] = false; |
3300 Vector<HeapGraphEdge> children = entries[root_index]->children(); | 3300 Vector<HeapGraphEdge> children = entries[root_index]->children(); |
3301 for (int i = 0; i < children.length(); ++i) { | 3301 for (int i = 0; i < children.length(); ++i) { |
3302 // Mark the root direct children as affected on iteration zero. | 3302 // Mark the root direct children as affected. |
3303 time_stamps[children[i].to()->ordered_index()] = 0; | 3303 affected[children[i].to()->ordered_index()] = true; |
3304 } | 3304 } |
3305 | 3305 |
3306 int changed = 1; | 3306 int changed = 1; |
3307 int iteration = 0; | |
3308 const int base_progress_counter = progress_counter_; | 3307 const int base_progress_counter = progress_counter_; |
3309 while (changed != 0) { | 3308 while (changed != 0) { |
3310 ++iteration; | |
3311 changed = 0; | 3309 changed = 0; |
3312 for (int i = root_index - 1; i >= 0; --i) { | 3310 for (int i = root_index - 1; i >= 0; --i) { |
3313 // If dominator of the entry has already been set to root, | 3311 // If dominator of the entry has already been set to root, |
3314 // then it can't propagate any further. | 3312 // then it can't propagate any further. |
3315 if ((*dominators)[i] == root_index) continue; | 3313 if ((*dominators)[i] == root_index) continue; |
3316 // If no retainers of the entry had been updated on current | 3314 if (!affected[i]) continue; |
3317 // or previous iteration, then this entry is not affected. | 3315 affected[i] = false; |
3318 if (time_stamps[i] < iteration - 1) continue; | |
3319 int new_idom_index = kNoDominator; | 3316 int new_idom_index = kNoDominator; |
3320 Vector<HeapGraphEdge*> rets = entries[i]->retainers(); | 3317 Vector<HeapGraphEdge*> rets = entries[i]->retainers(); |
3321 for (int j = 0; j < rets.length(); ++j) { | 3318 for (int j = 0; j < rets.length(); ++j) { |
3322 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; | 3319 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; |
3323 int ret_index = rets[j]->From()->ordered_index(); | 3320 int ret_index = rets[j]->From()->ordered_index(); |
3324 if (dominators->at(ret_index) != kNoDominator) { | 3321 if (dominators->at(ret_index) != kNoDominator) { |
3325 new_idom_index = new_idom_index == kNoDominator | 3322 new_idom_index = new_idom_index == kNoDominator |
3326 ? ret_index | 3323 ? ret_index |
3327 : Intersect(ret_index, new_idom_index, *dominators); | 3324 : Intersect(ret_index, new_idom_index, *dominators); |
3328 // If idom has already reached the root, it doesn't make sense | 3325 // If idom has already reached the root, it doesn't make sense |
3329 // to check other retainers. | 3326 // to check other retainers. |
3330 if (new_idom_index == root_index) break; | 3327 if (new_idom_index == root_index) break; |
3331 } | 3328 } |
3332 } | 3329 } |
3333 if (new_idom_index != kNoDominator | 3330 if (new_idom_index != kNoDominator |
3334 && dominators->at(i) != new_idom_index) { | 3331 && dominators->at(i) != new_idom_index) { |
3335 (*dominators)[i] = new_idom_index; | 3332 (*dominators)[i] = new_idom_index; |
3336 ++changed; | 3333 ++changed; |
3337 Vector<HeapGraphEdge> children = entries[i]->children(); | 3334 Vector<HeapGraphEdge> children = entries[i]->children(); |
3338 for (int j = 0; j < children.length(); ++j) { | 3335 for (int j = 0; j < children.length(); ++j) { |
3339 time_stamps[children[j].to()->ordered_index()] = iteration; | 3336 affected[children[j].to()->ordered_index()] = true; |
3340 } | 3337 } |
3341 } | 3338 } |
3342 } | 3339 } |
3343 int remaining = entries_length - changed; | 3340 int remaining = entries_length - changed; |
3344 ASSERT(remaining >= 0); | 3341 ASSERT(remaining >= 0); |
3345 progress_counter_ = base_progress_counter + remaining; | 3342 progress_counter_ = base_progress_counter + remaining; |
3346 if (!ProgressReport(true)) return false; | 3343 if (!ProgressReport(true)) return false; |
3347 } | 3344 } |
3348 return true; | 3345 return true; |
3349 } | 3346 } |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3806 | 3803 |
3807 | 3804 |
3808 void HeapSnapshotJSONSerializer::SortHashMap( | 3805 void HeapSnapshotJSONSerializer::SortHashMap( |
3809 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3806 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3810 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3807 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3811 sorted_entries->Add(p); | 3808 sorted_entries->Add(p); |
3812 sorted_entries->Sort(SortUsingEntryValue); | 3809 sorted_entries->Sort(SortUsingEntryValue); |
3813 } | 3810 } |
3814 | 3811 |
3815 } } // namespace v8::internal | 3812 } } // namespace v8::internal |
OLD | NEW |