| 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 |