| 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 3148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3159 #endif | 3159 #endif |
| 3160 | 3160 |
| 3161 // The following code uses heap iterators, so we want the heap to be | 3161 // The following code uses heap iterators, so we want the heap to be |
| 3162 // stable. It should follow TagGlobalObjects as that can allocate. | 3162 // stable. It should follow TagGlobalObjects as that can allocate. |
| 3163 AssertNoAllocation no_alloc; | 3163 AssertNoAllocation no_alloc; |
| 3164 | 3164 |
| 3165 #ifdef DEBUG | 3165 #ifdef DEBUG |
| 3166 debug_heap->Verify(); | 3166 debug_heap->Verify(); |
| 3167 #endif | 3167 #endif |
| 3168 | 3168 |
| 3169 SetProgressTotal(4); // 2 passes + dominators + sizes. | 3169 SetProgressTotal(2); // 2 passes. |
| 3170 | 3170 |
| 3171 #ifdef DEBUG | 3171 #ifdef DEBUG |
| 3172 debug_heap->Verify(); | 3172 debug_heap->Verify(); |
| 3173 #endif | 3173 #endif |
| 3174 | 3174 |
| 3175 // Pass 1. Iterate heap contents to count entries and references. | 3175 // Pass 1. Iterate heap contents to count entries and references. |
| 3176 if (!CountEntriesAndReferences()) return false; | 3176 if (!CountEntriesAndReferences()) return false; |
| 3177 | 3177 |
| 3178 #ifdef DEBUG | 3178 #ifdef DEBUG |
| 3179 debug_heap->Verify(); | 3179 debug_heap->Verify(); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3296 // The affected array is used to mark those entries that may | 3296 // The affected array is used to mark those entries that may |
| 3297 // be affected because of dominators change among their retainers. | 3297 // be affected because of dominators change among their retainers. |
| 3298 ScopedVector<bool> affected(entries_length); | 3298 ScopedVector<bool> affected(entries_length); |
| 3299 for (int i = 0; i < entries_length; ++i) affected[i] = false; | 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. | 3302 // Mark the root direct children as affected. |
| 3303 affected[children[i].to()->ordered_index()] = true; | 3303 affected[children[i].to()->ordered_index()] = true; |
| 3304 } | 3304 } |
| 3305 | 3305 |
| 3306 int changed = 1; | 3306 bool changed = true; |
| 3307 const int base_progress_counter = progress_counter_; | 3307 while (changed) { |
| 3308 while (changed != 0) { | 3308 changed = false; |
| 3309 changed = 0; | |
| 3310 for (int i = root_index - 1; i >= 0; --i) { | 3309 for (int i = root_index - 1; i >= 0; --i) { |
| 3311 // If dominator of the entry has already been set to root, | 3310 // If dominator of the entry has already been set to root, |
| 3312 // then it can't propagate any further. | 3311 // then it can't propagate any further. |
| 3313 if ((*dominators)[i] == root_index) continue; | 3312 if ((*dominators)[i] == root_index) continue; |
| 3314 if (!affected[i]) continue; | 3313 if (!affected[i]) continue; |
| 3315 affected[i] = false; | 3314 affected[i] = false; |
| 3316 int new_idom_index = kNoDominator; | 3315 int new_idom_index = kNoDominator; |
| 3317 Vector<HeapGraphEdge*> rets = entries[i]->retainers(); | 3316 Vector<HeapGraphEdge*> rets = entries[i]->retainers(); |
| 3318 for (int j = 0; j < rets.length(); ++j) { | 3317 for (int j = 0; j < rets.length(); ++j) { |
| 3319 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; | 3318 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; |
| 3320 int ret_index = rets[j]->From()->ordered_index(); | 3319 int ret_index = rets[j]->From()->ordered_index(); |
| 3321 if (dominators->at(ret_index) != kNoDominator) { | 3320 if (dominators->at(ret_index) != kNoDominator) { |
| 3322 new_idom_index = new_idom_index == kNoDominator | 3321 new_idom_index = new_idom_index == kNoDominator |
| 3323 ? ret_index | 3322 ? ret_index |
| 3324 : Intersect(ret_index, new_idom_index, *dominators); | 3323 : Intersect(ret_index, new_idom_index, *dominators); |
| 3325 // If idom has already reached the root, it doesn't make sense | 3324 // If idom has already reached the root, it doesn't make sense |
| 3326 // to check other retainers. | 3325 // to check other retainers. |
| 3327 if (new_idom_index == root_index) break; | 3326 if (new_idom_index == root_index) break; |
| 3328 } | 3327 } |
| 3329 } | 3328 } |
| 3330 if (new_idom_index != kNoDominator | 3329 if (new_idom_index != kNoDominator |
| 3331 && dominators->at(i) != new_idom_index) { | 3330 && dominators->at(i) != new_idom_index) { |
| 3332 (*dominators)[i] = new_idom_index; | 3331 (*dominators)[i] = new_idom_index; |
| 3333 ++changed; | 3332 changed = true; |
| 3334 Vector<HeapGraphEdge> children = entries[i]->children(); | 3333 Vector<HeapGraphEdge> children = entries[i]->children(); |
| 3335 for (int j = 0; j < children.length(); ++j) { | 3334 for (int j = 0; j < children.length(); ++j) { |
| 3336 affected[children[j].to()->ordered_index()] = true; | 3335 affected[children[j].to()->ordered_index()] = true; |
| 3337 } | 3336 } |
| 3338 } | 3337 } |
| 3339 } | 3338 } |
| 3340 int remaining = entries_length - changed; | |
| 3341 ASSERT(remaining >= 0); | |
| 3342 progress_counter_ = base_progress_counter + remaining; | |
| 3343 if (!ProgressReport(true)) return false; | |
| 3344 } | 3339 } |
| 3345 return true; | 3340 return true; |
| 3346 } | 3341 } |
| 3347 | 3342 |
| 3348 | 3343 |
| 3349 bool HeapSnapshotGenerator::SetEntriesDominators() { | 3344 bool HeapSnapshotGenerator::SetEntriesDominators() { |
| 3350 // This array is used for maintaining reverse postorder of nodes. | 3345 // This array is used for maintaining reverse postorder of nodes. |
| 3351 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length()); | 3346 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length()); |
| 3352 FillReversePostorderIndexes(&ordered_entries); | 3347 FillReversePostorderIndexes(&ordered_entries); |
| 3353 ScopedVector<int> dominators(ordered_entries.length()); | 3348 ScopedVector<int> dominators(ordered_entries.length()); |
| 3354 if (!BuildDominatorTree(ordered_entries, &dominators)) return false; | 3349 if (!BuildDominatorTree(ordered_entries, &dominators)) return false; |
| 3355 for (int i = 0; i < ordered_entries.length(); ++i) { | 3350 for (int i = 0; i < ordered_entries.length(); ++i) { |
| 3356 ASSERT(dominators[i] >= 0); | 3351 ASSERT(dominators[i] >= 0); |
| 3357 ordered_entries[i]->set_dominator(ordered_entries[dominators[i]]); | 3352 ordered_entries[i]->set_dominator(ordered_entries[dominators[i]]); |
| 3358 } | 3353 } |
| 3359 return true; | 3354 return true; |
| 3360 } | 3355 } |
| 3361 | 3356 |
| 3362 | 3357 |
| 3363 bool HeapSnapshotGenerator::ApproximateRetainedSizes() { | 3358 bool HeapSnapshotGenerator::ApproximateRetainedSizes() { |
| 3364 // As for the dominators tree we only know parent nodes, not | 3359 // As for the dominators tree we only know parent nodes, not |
| 3365 // children, to sum up total sizes we "bubble" node's self size | 3360 // children, to sum up total sizes we "bubble" node's self size |
| 3366 // adding it to all of its parents. | 3361 // adding it to all of its parents. |
| 3367 for (int i = 0; i < snapshot_->entries()->length(); ++i) { | 3362 List<HeapEntry*>& entries = *snapshot_->entries(); |
| 3368 HeapEntry* entry = snapshot_->entries()->at(i); | 3363 for (int i = 0; i < entries.length(); ++i) { |
| 3364 HeapEntry* entry = entries[i]; |
| 3369 entry->set_retained_size(entry->self_size()); | 3365 entry->set_retained_size(entry->self_size()); |
| 3370 } | 3366 } |
| 3371 for (int i = 0; | 3367 for (int i = 0; i < entries.length(); ++i) { |
| 3372 i < snapshot_->entries()->length(); | 3368 HeapEntry* entry = entries[i]; |
| 3373 ++i, ProgressStep()) { | |
| 3374 HeapEntry* entry = snapshot_->entries()->at(i); | |
| 3375 int entry_size = entry->self_size(); | 3369 int entry_size = entry->self_size(); |
| 3376 for (HeapEntry* dominator = entry->dominator(); | 3370 for (HeapEntry* dominator = entry->dominator(); |
| 3377 dominator != entry; | 3371 dominator != entry; |
| 3378 entry = dominator, dominator = entry->dominator()) { | 3372 entry = dominator, dominator = entry->dominator()) { |
| 3379 dominator->add_retained_size(entry_size); | 3373 dominator->add_retained_size(entry_size); |
| 3380 } | 3374 } |
| 3381 if (!ProgressReport()) return false; | |
| 3382 } | 3375 } |
| 3383 return true; | 3376 return true; |
| 3384 } | 3377 } |
| 3385 | 3378 |
| 3386 | 3379 |
| 3387 template<int bytes> struct MaxDecimalDigitsIn; | 3380 template<int bytes> struct MaxDecimalDigitsIn; |
| 3388 template<> struct MaxDecimalDigitsIn<4> { | 3381 template<> struct MaxDecimalDigitsIn<4> { |
| 3389 static const int kSigned = 11; | 3382 static const int kSigned = 11; |
| 3390 static const int kUnsigned = 10; | 3383 static const int kUnsigned = 10; |
| 3391 }; | 3384 }; |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3803 | 3796 |
| 3804 | 3797 |
| 3805 void HeapSnapshotJSONSerializer::SortHashMap( | 3798 void HeapSnapshotJSONSerializer::SortHashMap( |
| 3806 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3799 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
| 3807 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3800 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
| 3808 sorted_entries->Add(p); | 3801 sorted_entries->Add(p); |
| 3809 sorted_entries->Sort(SortUsingEntryValue); | 3802 sorted_entries->Sort(SortUsingEntryValue); |
| 3810 } | 3803 } |
| 3811 | 3804 |
| 3812 } } // namespace v8::internal | 3805 } } // namespace v8::internal |
| OLD | NEW |