OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1804 retainers_count); | 1804 retainers_count); |
1805 } | 1805 } |
1806 | 1806 |
1807 | 1807 |
1808 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { | 1808 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { |
1809 filler->AddEntry(kInternalRootObject, this); | 1809 filler->AddEntry(kInternalRootObject, this); |
1810 filler->AddEntry(kGcRootsObject, this); | 1810 filler->AddEntry(kGcRootsObject, this); |
1811 } | 1811 } |
1812 | 1812 |
1813 | 1813 |
1814 int V8HeapExplorer::EstimateObjectsCount() { | 1814 int V8HeapExplorer::EstimateObjectsCount(HeapIterator* iterator) { |
1815 HeapIterator iterator(HeapIterator::kFilterUnreachable); | |
1816 int objects_count = 0; | 1815 int objects_count = 0; |
1817 for (HeapObject* obj = iterator.next(); | 1816 for (HeapObject* obj = iterator->Next(); |
1818 obj != NULL; | 1817 obj != NULL; |
1819 obj = iterator.next(), ++objects_count) {} | 1818 obj = iterator->Next(), ++objects_count) {} |
1820 return objects_count; | 1819 return objects_count; |
1821 } | 1820 } |
1822 | 1821 |
1823 | 1822 |
1824 class IndexedReferencesExtractor : public ObjectVisitor { | 1823 class IndexedReferencesExtractor : public ObjectVisitor { |
1825 public: | 1824 public: |
1826 IndexedReferencesExtractor(V8HeapExplorer* generator, | 1825 IndexedReferencesExtractor(V8HeapExplorer* generator, |
1827 HeapObject* parent_obj, | 1826 HeapObject* parent_obj, |
1828 HeapEntry* parent_entry, | 1827 HeapEntry* parent_entry, |
1829 HeapObjectsSet* known_references = NULL) | 1828 HeapObjectsSet* known_references = NULL) |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2008 } | 2007 } |
2009 void VisitPointers(Object** start, Object** end) { | 2008 void VisitPointers(Object** start, Object** end) { |
2010 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p); | 2009 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p); |
2011 } | 2010 } |
2012 private: | 2011 private: |
2013 V8HeapExplorer* explorer_; | 2012 V8HeapExplorer* explorer_; |
2014 }; | 2013 }; |
2015 | 2014 |
2016 | 2015 |
2017 bool V8HeapExplorer::IterateAndExtractReferences( | 2016 bool V8HeapExplorer::IterateAndExtractReferences( |
| 2017 HeapIterator* iterator, |
2018 SnapshotFillerInterface* filler) { | 2018 SnapshotFillerInterface* filler) { |
2019 filler_ = filler; | 2019 filler_ = filler; |
2020 HeapIterator iterator(HeapIterator::kFilterUnreachable); | |
2021 bool interrupted = false; | 2020 bool interrupted = false; |
2022 // Heap iteration with filtering must be finished in any case. | 2021 // Heap iteration with filtering must be finished in any case. |
2023 for (HeapObject* obj = iterator.next(); | 2022 for (HeapObject* obj = iterator->Next(); |
2024 obj != NULL; | 2023 obj != NULL; |
2025 obj = iterator.next(), progress_->ProgressStep()) { | 2024 obj = iterator->Next(), progress_->ProgressStep()) { |
2026 if (!interrupted) { | 2025 if (!interrupted) { |
2027 ExtractReferences(obj); | 2026 ExtractReferences(obj); |
2028 if (!progress_->ProgressReport(false)) interrupted = true; | 2027 if (!progress_->ProgressReport(false)) interrupted = true; |
2029 } | 2028 } |
2030 } | 2029 } |
2031 if (interrupted) { | 2030 if (interrupted) { |
2032 filler_ = NULL; | 2031 filler_ = NULL; |
2033 return false; | 2032 return false; |
2034 } | 2033 } |
2035 SetRootGcRootsReference(); | 2034 SetRootGcRootsReference(); |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2501 retainer_index); | 2500 retainer_index); |
2502 } | 2501 } |
2503 private: | 2502 private: |
2504 HeapSnapshot* snapshot_; | 2503 HeapSnapshot* snapshot_; |
2505 HeapSnapshotsCollection* collection_; | 2504 HeapSnapshotsCollection* collection_; |
2506 HeapEntriesMap* entries_; | 2505 HeapEntriesMap* entries_; |
2507 }; | 2506 }; |
2508 | 2507 |
2509 | 2508 |
2510 bool HeapSnapshotGenerator::GenerateSnapshot() { | 2509 bool HeapSnapshotGenerator::GenerateSnapshot() { |
| 2510 HeapIterator set_progress_heap_iterator; |
| 2511 HeapIterator count_entries_heap_iterator; |
| 2512 HeapIterator fill_references_heap_iterator; |
2511 AssertNoAllocation no_alloc; | 2513 AssertNoAllocation no_alloc; |
2512 | 2514 |
2513 SetProgressTotal(4); // 2 passes + dominators + sizes. | 2515 SetProgressTotal(&set_progress_heap_iterator, |
| 2516 4); // 2 passes + dominators + sizes. |
2514 | 2517 |
2515 // Pass 1. Iterate heap contents to count entries and references. | 2518 // Pass 1. Iterate heap contents to count entries and references. |
2516 if (!CountEntriesAndReferences()) return false; | 2519 if (!CountEntriesAndReferences(&count_entries_heap_iterator)) return false; |
2517 | 2520 |
2518 // Allocate and fill entries in the snapshot, allocate references. | 2521 // Allocate and fill entries in the snapshot, allocate references. |
2519 snapshot_->AllocateEntries(entries_.entries_count(), | 2522 snapshot_->AllocateEntries(entries_.entries_count(), |
2520 entries_.total_children_count(), | 2523 entries_.total_children_count(), |
2521 entries_.total_retainers_count()); | 2524 entries_.total_retainers_count()); |
2522 entries_.AllocateEntries(); | 2525 entries_.AllocateEntries(); |
2523 | 2526 |
2524 // Pass 2. Fill references. | 2527 // Pass 2. Fill references. |
2525 if (!FillReferences()) return false; | 2528 if (!FillReferences(&fill_references_heap_iterator)) return false; |
2526 | 2529 |
2527 if (!SetEntriesDominators()) return false; | 2530 if (!SetEntriesDominators()) return false; |
2528 if (!ApproximateRetainedSizes()) return false; | 2531 if (!ApproximateRetainedSizes()) return false; |
2529 | 2532 |
2530 progress_counter_ = progress_total_; | 2533 progress_counter_ = progress_total_; |
2531 if (!ProgressReport(true)) return false; | 2534 if (!ProgressReport(true)) return false; |
2532 return true; | 2535 return true; |
2533 } | 2536 } |
2534 | 2537 |
2535 | 2538 |
2536 void HeapSnapshotGenerator::ProgressStep() { | 2539 void HeapSnapshotGenerator::ProgressStep() { |
2537 ++progress_counter_; | 2540 ++progress_counter_; |
2538 } | 2541 } |
2539 | 2542 |
2540 | 2543 |
2541 bool HeapSnapshotGenerator::ProgressReport(bool force) { | 2544 bool HeapSnapshotGenerator::ProgressReport(bool force) { |
2542 const int kProgressReportGranularity = 10000; | 2545 const int kProgressReportGranularity = 10000; |
2543 if (control_ != NULL | 2546 if (control_ != NULL |
2544 && (force || progress_counter_ % kProgressReportGranularity == 0)) { | 2547 && (force || progress_counter_ % kProgressReportGranularity == 0)) { |
2545 return | 2548 return |
2546 control_->ReportProgressValue(progress_counter_, progress_total_) == | 2549 control_->ReportProgressValue(progress_counter_, progress_total_) == |
2547 v8::ActivityControl::kContinue; | 2550 v8::ActivityControl::kContinue; |
2548 } | 2551 } |
2549 return true; | 2552 return true; |
2550 } | 2553 } |
2551 | 2554 |
2552 | 2555 |
2553 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) { | 2556 void HeapSnapshotGenerator::SetProgressTotal(HeapIterator* iterator, |
| 2557 int iterations_count) { |
2554 if (control_ == NULL) return; | 2558 if (control_ == NULL) return; |
2555 progress_total_ = ( | 2559 progress_total_ = ( |
2556 v8_heap_explorer_.EstimateObjectsCount() + | 2560 v8_heap_explorer_.EstimateObjectsCount(iterator) + |
2557 dom_explorer_.EstimateObjectsCount()) * iterations_count; | 2561 dom_explorer_.EstimateObjectsCount()) * iterations_count; |
2558 progress_counter_ = 0; | 2562 progress_counter_ = 0; |
2559 } | 2563 } |
2560 | 2564 |
2561 | 2565 |
2562 bool HeapSnapshotGenerator::CountEntriesAndReferences() { | 2566 bool HeapSnapshotGenerator::CountEntriesAndReferences(HeapIterator* iterator) { |
2563 SnapshotCounter counter(&entries_); | 2567 SnapshotCounter counter(&entries_); |
2564 v8_heap_explorer_.AddRootEntries(&counter); | 2568 v8_heap_explorer_.AddRootEntries(&counter); |
2565 dom_explorer_.AddRootEntries(&counter); | 2569 dom_explorer_.AddRootEntries(&counter); |
2566 return | 2570 return |
2567 v8_heap_explorer_.IterateAndExtractReferences(&counter) && | 2571 v8_heap_explorer_.IterateAndExtractReferences(iterator, &counter) && |
2568 dom_explorer_.IterateAndExtractReferences(&counter); | 2572 dom_explorer_.IterateAndExtractReferences(&counter); |
2569 } | 2573 } |
2570 | 2574 |
2571 | 2575 |
2572 bool HeapSnapshotGenerator::FillReferences() { | 2576 bool HeapSnapshotGenerator::FillReferences(HeapIterator* iterator) { |
2573 SnapshotFiller filler(snapshot_, &entries_); | 2577 SnapshotFiller filler(snapshot_, &entries_); |
2574 return | 2578 return |
2575 v8_heap_explorer_.IterateAndExtractReferences(&filler) && | 2579 v8_heap_explorer_.IterateAndExtractReferences(iterator, &filler) && |
2576 dom_explorer_.IterateAndExtractReferences(&filler); | 2580 dom_explorer_.IterateAndExtractReferences(&filler); |
2577 } | 2581 } |
2578 | 2582 |
2579 | 2583 |
2580 void HeapSnapshotGenerator::FillReversePostorderIndexes( | 2584 void HeapSnapshotGenerator::FillReversePostorderIndexes( |
2581 Vector<HeapEntry*>* entries) { | 2585 Vector<HeapEntry*>* entries) { |
2582 snapshot_->ClearPaint(); | 2586 snapshot_->ClearPaint(); |
2583 int current_entry = 0; | 2587 int current_entry = 0; |
2584 List<HeapEntry*> nodes_to_visit; | 2588 List<HeapEntry*> nodes_to_visit; |
2585 nodes_to_visit.Add(snapshot_->root()); | 2589 nodes_to_visit.Add(snapshot_->root()); |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3147 | 3151 |
3148 | 3152 |
3149 String* GetConstructorNameForHeapProfile(JSObject* object) { | 3153 String* GetConstructorNameForHeapProfile(JSObject* object) { |
3150 if (object->IsJSFunction()) return Heap::closure_symbol(); | 3154 if (object->IsJSFunction()) return Heap::closure_symbol(); |
3151 return object->constructor_name(); | 3155 return object->constructor_name(); |
3152 } | 3156 } |
3153 | 3157 |
3154 } } // namespace v8::internal | 3158 } } // namespace v8::internal |
3155 | 3159 |
3156 #endif // ENABLE_LOGGING_AND_PROFILING | 3160 #endif // ENABLE_LOGGING_AND_PROFILING |
OLD | NEW |