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

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

Issue 8139027: Version 3.6.5 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 2 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') | src/property.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 1008
1009 1009
1010 int HeapEntry::RetainedSize(bool exact) { 1010 int HeapEntry::RetainedSize(bool exact) {
1011 if (exact && (retained_size_ & kExactRetainedSizeTag) == 0) { 1011 if (exact && (retained_size_ & kExactRetainedSizeTag) == 0) {
1012 CalculateExactRetainedSize(); 1012 CalculateExactRetainedSize();
1013 } 1013 }
1014 return retained_size_ & (~kExactRetainedSizeTag); 1014 return retained_size_ & (~kExactRetainedSizeTag);
1015 } 1015 }
1016 1016
1017 1017
1018 Handle<HeapObject> HeapEntry::GetHeapObject() {
1019 return snapshot_->collection()->FindHeapObjectById(id());
1020 }
1021
1022
1018 template<class Visitor> 1023 template<class Visitor>
1019 void HeapEntry::ApplyAndPaintAllReachable(Visitor* visitor) { 1024 void HeapEntry::ApplyAndPaintAllReachable(Visitor* visitor) {
1020 List<HeapEntry*> list(10); 1025 List<HeapEntry*> list(10);
1021 list.Add(this); 1026 list.Add(this);
1022 this->paint_reachable(); 1027 this->paint_reachable();
1023 visitor->Apply(this); 1028 visitor->Apply(this);
1024 while (!list.is_empty()) { 1029 while (!list.is_empty()) {
1025 HeapEntry* entry = list.RemoveLast(); 1030 HeapEntry* entry = list.RemoveLast();
1026 Vector<HeapGraphEdge> children = entry->children(); 1031 Vector<HeapGraphEdge> children = entry->children();
1027 for (int i = 0; i < children.length(); ++i) { 1032 for (int i = 0; i < children.length(); ++i) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1368 entries_map_(AddressesMatch), 1373 entries_map_(AddressesMatch),
1369 entries_(new List<EntryInfo>()) { } 1374 entries_(new List<EntryInfo>()) { }
1370 1375
1371 1376
1372 HeapObjectsMap::~HeapObjectsMap() { 1377 HeapObjectsMap::~HeapObjectsMap() {
1373 delete entries_; 1378 delete entries_;
1374 } 1379 }
1375 1380
1376 1381
1377 void HeapObjectsMap::SnapshotGenerationFinished() { 1382 void HeapObjectsMap::SnapshotGenerationFinished() {
1378 initial_fill_mode_ = false; 1383 initial_fill_mode_ = false;
1379 RemoveDeadEntries(); 1384 RemoveDeadEntries();
1380 } 1385 }
1381 1386
1382 1387
1383 uint64_t HeapObjectsMap::FindObject(Address addr) { 1388 uint64_t HeapObjectsMap::FindObject(Address addr) {
1384 if (!initial_fill_mode_) { 1389 if (!initial_fill_mode_) {
1385 uint64_t existing = FindEntry(addr); 1390 uint64_t existing = FindEntry(addr);
1386 if (existing != 0) return existing; 1391 if (existing != 0) return existing;
1387 } 1392 }
1388 uint64_t id = next_id_; 1393 uint64_t id = next_id_;
1389 next_id_ += 2; 1394 next_id_ += 2;
1390 AddEntry(addr, id); 1395 AddEntry(addr, id);
1391 return id; 1396 return id;
1392 } 1397 }
1393 1398
1394 1399
1395 void HeapObjectsMap::MoveObject(Address from, Address to) { 1400 void HeapObjectsMap::MoveObject(Address from, Address to) {
1396 if (from == to) return; 1401 if (from == to) return;
1397 HashMap::Entry* entry = entries_map_.Lookup(from, AddressHash(from), false); 1402 HashMap::Entry* entry = entries_map_.Lookup(from, AddressHash(from), false);
1398 if (entry != NULL) { 1403 if (entry != NULL) {
1399 void* value = entry->value; 1404 void* value = entry->value;
1400 entries_map_.Remove(from, AddressHash(from)); 1405 entries_map_.Remove(from, AddressHash(from));
1401 entry = entries_map_.Lookup(to, AddressHash(to), true); 1406 if (to != NULL) {
1402 // We can have an entry at the new location, it is OK, as GC can overwrite 1407 entry = entries_map_.Lookup(to, AddressHash(to), true);
1403 // dead objects with alive objects being moved. 1408 // We can have an entry at the new location, it is OK, as GC can overwrite
1404 entry->value = value; 1409 // dead objects with alive objects being moved.
1410 entry->value = value;
1411 }
1405 } 1412 }
1406 } 1413 }
1407 1414
1408 1415
1409 void HeapObjectsMap::AddEntry(Address addr, uint64_t id) { 1416 void HeapObjectsMap::AddEntry(Address addr, uint64_t id) {
1410 HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), true); 1417 HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), true);
1411 ASSERT(entry->value == NULL); 1418 ASSERT(entry->value == NULL);
1412 entry->value = reinterpret_cast<void*>(entries_->length()); 1419 entry->value = reinterpret_cast<void*>(entries_->length());
1413 entries_->Add(EntryInfo(id)); 1420 entries_->Add(EntryInfo(id));
1414 } 1421 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 1522
1516 1523
1517 void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) { 1524 void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) {
1518 snapshots_.RemoveElement(snapshot); 1525 snapshots_.RemoveElement(snapshot);
1519 unsigned uid = snapshot->uid(); 1526 unsigned uid = snapshot->uid();
1520 snapshots_uids_.Remove(reinterpret_cast<void*>(uid), 1527 snapshots_uids_.Remove(reinterpret_cast<void*>(uid),
1521 static_cast<uint32_t>(uid)); 1528 static_cast<uint32_t>(uid));
1522 } 1529 }
1523 1530
1524 1531
1532 Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(uint64_t id) {
1533 // First perform a full GC in order to avoid dead objects.
1534 HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask);
1535 AssertNoAllocation no_allocation;
1536 HeapObject* object = NULL;
1537 HeapIterator iterator(HeapIterator::kFilterUnreachable);
1538 // Make sure that object with the given id is still reachable.
1539 for (HeapObject* obj = iterator.next();
1540 obj != NULL;
1541 obj = iterator.next()) {
1542 if (ids_.FindObject(obj->address()) == id) {
1543 ASSERT(object == NULL);
1544 object = obj;
1545 // Can't break -- kFilterUnreachable requires full heap traversal.
1546 }
1547 }
1548 return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>();
1549 }
1550
1551
1525 HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder = 1552 HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder =
1526 reinterpret_cast<HeapEntry*>(1); 1553 reinterpret_cast<HeapEntry*>(1);
1527 1554
1528 HeapEntriesMap::HeapEntriesMap() 1555 HeapEntriesMap::HeapEntriesMap()
1529 : entries_(HeapThingsMatch), 1556 : entries_(HeapThingsMatch),
1530 entries_count_(0), 1557 entries_count_(0),
1531 total_children_count_(0), 1558 total_children_count_(0),
1532 total_retainers_count_(0) { 1559 total_retainers_count_(0) {
1533 } 1560 }
1534 1561
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1805 case ODDBALL_TYPE: return "system / Oddball"; 1832 case ODDBALL_TYPE: return "system / Oddball";
1806 #define MAKE_STRUCT_CASE(NAME, Name, name) \ 1833 #define MAKE_STRUCT_CASE(NAME, Name, name) \
1807 case NAME##_TYPE: return "system / "#Name; 1834 case NAME##_TYPE: return "system / "#Name;
1808 STRUCT_LIST(MAKE_STRUCT_CASE) 1835 STRUCT_LIST(MAKE_STRUCT_CASE)
1809 #undef MAKE_STRUCT_CASE 1836 #undef MAKE_STRUCT_CASE
1810 default: return "system"; 1837 default: return "system";
1811 } 1838 }
1812 } 1839 }
1813 1840
1814 1841
1815 int V8HeapExplorer::EstimateObjectsCount() { 1842 int V8HeapExplorer::EstimateObjectsCount(HeapIterator* iterator) {
1816 HeapIterator iterator(HeapIterator::kFilterUnreachable);
1817 int objects_count = 0; 1843 int objects_count = 0;
1818 for (HeapObject* obj = iterator.next(); 1844 for (HeapObject* obj = iterator->next();
1819 obj != NULL; 1845 obj != NULL;
1820 obj = iterator.next(), ++objects_count) {} 1846 obj = iterator->next()) {
1847 objects_count++;
1848 }
1821 return objects_count; 1849 return objects_count;
1822 } 1850 }
1823 1851
1824 1852
1825 class IndexedReferencesExtractor : public ObjectVisitor { 1853 class IndexedReferencesExtractor : public ObjectVisitor {
1826 public: 1854 public:
1827 IndexedReferencesExtractor(V8HeapExplorer* generator, 1855 IndexedReferencesExtractor(V8HeapExplorer* generator,
1828 HeapObject* parent_obj, 1856 HeapObject* parent_obj,
1829 HeapEntry* parent_entry) 1857 HeapEntry* parent_entry)
1830 : generator_(generator), 1858 : generator_(generator),
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 "prototype", map->prototype(), Map::kPrototypeOffset); 1966 "prototype", map->prototype(), Map::kPrototypeOffset);
1939 SetInternalReference(obj, entry, 1967 SetInternalReference(obj, entry,
1940 "constructor", map->constructor(), 1968 "constructor", map->constructor(),
1941 Map::kConstructorOffset); 1969 Map::kConstructorOffset);
1942 if (!map->instance_descriptors()->IsEmpty()) { 1970 if (!map->instance_descriptors()->IsEmpty()) {
1943 TagObject(map->instance_descriptors(), "(map descriptors)"); 1971 TagObject(map->instance_descriptors(), "(map descriptors)");
1944 SetInternalReference(obj, entry, 1972 SetInternalReference(obj, entry,
1945 "descriptors", map->instance_descriptors(), 1973 "descriptors", map->instance_descriptors(),
1946 Map::kInstanceDescriptorsOrBitField3Offset); 1974 Map::kInstanceDescriptorsOrBitField3Offset);
1947 } 1975 }
1976 if (map->prototype_transitions() != heap_->empty_fixed_array()) {
1977 TagObject(map->prototype_transitions(), "(prototype transitions)");
1978 SetInternalReference(obj,
1979 entry,
1980 "prototype_transitions",
1981 map->prototype_transitions(),
1982 Map::kPrototypeTransitionsOffset);
1983 }
1948 SetInternalReference(obj, entry, 1984 SetInternalReference(obj, entry,
1949 "code_cache", map->code_cache(), 1985 "code_cache", map->code_cache(),
1950 Map::kCodeCacheOffset); 1986 Map::kCodeCacheOffset);
1951 } else if (obj->IsSharedFunctionInfo()) { 1987 } else if (obj->IsSharedFunctionInfo()) {
1952 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); 1988 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
1953 SetInternalReference(obj, entry, 1989 SetInternalReference(obj, entry,
1954 "name", shared->name(), 1990 "name", shared->name(),
1955 SharedFunctionInfo::kNameOffset); 1991 SharedFunctionInfo::kNameOffset);
1956 SetInternalReference(obj, entry, 1992 SetInternalReference(obj, entry,
1957 "code", shared->unchecked_code(), 1993 "code", shared->unchecked_code(),
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 void VisitPointers(Object** start, Object** end) { 2204 void VisitPointers(Object** start, Object** end) {
2169 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p); 2205 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p);
2170 } 2206 }
2171 private: 2207 private:
2172 V8HeapExplorer* explorer_; 2208 V8HeapExplorer* explorer_;
2173 }; 2209 };
2174 2210
2175 2211
2176 bool V8HeapExplorer::IterateAndExtractReferences( 2212 bool V8HeapExplorer::IterateAndExtractReferences(
2177 SnapshotFillerInterface* filler) { 2213 SnapshotFillerInterface* filler) {
2214 HeapIterator iterator(HeapIterator::kFilterUnreachable);
2215
2178 filler_ = filler; 2216 filler_ = filler;
2179 HeapIterator iterator(HeapIterator::kFilterUnreachable);
2180 bool interrupted = false; 2217 bool interrupted = false;
2218
2181 // Heap iteration with filtering must be finished in any case. 2219 // Heap iteration with filtering must be finished in any case.
2182 for (HeapObject* obj = iterator.next(); 2220 for (HeapObject* obj = iterator.next();
2183 obj != NULL; 2221 obj != NULL;
2184 obj = iterator.next(), progress_->ProgressStep()) { 2222 obj = iterator.next(), progress_->ProgressStep()) {
2185 if (!interrupted) { 2223 if (!interrupted) {
2186 ExtractReferences(obj); 2224 ExtractReferences(obj);
2187 if (!progress_->ProgressReport(false)) interrupted = true; 2225 if (!progress_->ProgressReport(false)) interrupted = true;
2188 } 2226 }
2189 } 2227 }
2190 if (interrupted) { 2228 if (interrupted) {
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
2736 private: 2774 private:
2737 HeapSnapshot* snapshot_; 2775 HeapSnapshot* snapshot_;
2738 HeapSnapshotsCollection* collection_; 2776 HeapSnapshotsCollection* collection_;
2739 HeapEntriesMap* entries_; 2777 HeapEntriesMap* entries_;
2740 }; 2778 };
2741 2779
2742 2780
2743 bool HeapSnapshotGenerator::GenerateSnapshot() { 2781 bool HeapSnapshotGenerator::GenerateSnapshot() {
2744 v8_heap_explorer_.TagGlobalObjects(); 2782 v8_heap_explorer_.TagGlobalObjects();
2745 2783
2784 // TODO(1562) Profiler assumes that any object that is in the heap after
2785 // full GC is reachable from the root when computing dominators.
2786 // This is not true for weakly reachable objects.
2787 // As a temporary solution we call GC twice.
2788 Isolate::Current()->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
2789 Isolate::Current()->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
2790
2791 #ifdef DEBUG
2792 Heap* debug_heap = Isolate::Current()->heap();
2793 ASSERT(!debug_heap->old_data_space()->was_swept_conservatively());
2794 ASSERT(!debug_heap->old_pointer_space()->was_swept_conservatively());
2795 ASSERT(!debug_heap->code_space()->was_swept_conservatively());
2796 ASSERT(!debug_heap->cell_space()->was_swept_conservatively());
2797 ASSERT(!debug_heap->map_space()->was_swept_conservatively());
2798 #endif
2799
2800 // The following code uses heap iterators, so we want the heap to be
2801 // stable. It should follow TagGlobalObjects as that can allocate.
2746 AssertNoAllocation no_alloc; 2802 AssertNoAllocation no_alloc;
2747 2803
2804 #ifdef DEBUG
2805 debug_heap->Verify();
2806 #endif
2807
2748 SetProgressTotal(4); // 2 passes + dominators + sizes. 2808 SetProgressTotal(4); // 2 passes + dominators + sizes.
2749 2809
2810 #ifdef DEBUG
2811 debug_heap->Verify();
2812 #endif
2813
2750 // Pass 1. Iterate heap contents to count entries and references. 2814 // Pass 1. Iterate heap contents to count entries and references.
2751 if (!CountEntriesAndReferences()) return false; 2815 if (!CountEntriesAndReferences()) return false;
2752 2816
2817 #ifdef DEBUG
2818 debug_heap->Verify();
2819 #endif
2820
2753 // Allocate and fill entries in the snapshot, allocate references. 2821 // Allocate and fill entries in the snapshot, allocate references.
2754 snapshot_->AllocateEntries(entries_.entries_count(), 2822 snapshot_->AllocateEntries(entries_.entries_count(),
2755 entries_.total_children_count(), 2823 entries_.total_children_count(),
2756 entries_.total_retainers_count()); 2824 entries_.total_retainers_count());
2757 entries_.AllocateEntries(); 2825 entries_.AllocateEntries();
2758 2826
2759 // Pass 2. Fill references. 2827 // Pass 2. Fill references.
2760 if (!FillReferences()) return false; 2828 if (!FillReferences()) return false;
2761 2829
2762 if (!SetEntriesDominators()) return false; 2830 if (!SetEntriesDominators()) return false;
(...skipping 17 matching lines...) Expand all
2780 return 2848 return
2781 control_->ReportProgressValue(progress_counter_, progress_total_) == 2849 control_->ReportProgressValue(progress_counter_, progress_total_) ==
2782 v8::ActivityControl::kContinue; 2850 v8::ActivityControl::kContinue;
2783 } 2851 }
2784 return true; 2852 return true;
2785 } 2853 }
2786 2854
2787 2855
2788 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) { 2856 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
2789 if (control_ == NULL) return; 2857 if (control_ == NULL) return;
2858 HeapIterator iterator(HeapIterator::kFilterUnreachable);
2790 progress_total_ = ( 2859 progress_total_ = (
2791 v8_heap_explorer_.EstimateObjectsCount() + 2860 v8_heap_explorer_.EstimateObjectsCount(&iterator) +
2792 dom_explorer_.EstimateObjectsCount()) * iterations_count; 2861 dom_explorer_.EstimateObjectsCount()) * iterations_count;
2793 progress_counter_ = 0; 2862 progress_counter_ = 0;
2794 } 2863 }
2795 2864
2796 2865
2797 bool HeapSnapshotGenerator::CountEntriesAndReferences() { 2866 bool HeapSnapshotGenerator::CountEntriesAndReferences() {
2798 SnapshotCounter counter(&entries_); 2867 SnapshotCounter counter(&entries_);
2799 v8_heap_explorer_.AddRootEntries(&counter); 2868 v8_heap_explorer_.AddRootEntries(&counter);
2800 dom_explorer_.AddRootEntries(&counter); 2869 dom_explorer_.AddRootEntries(&counter);
2801 return 2870 return
(...skipping 29 matching lines...) Expand all
2831 child->paint_reachable(); 2900 child->paint_reachable();
2832 has_new_edges = true; 2901 has_new_edges = true;
2833 } 2902 }
2834 } 2903 }
2835 if (!has_new_edges) { 2904 if (!has_new_edges) {
2836 entry->set_ordered_index(current_entry); 2905 entry->set_ordered_index(current_entry);
2837 (*entries)[current_entry++] = entry; 2906 (*entries)[current_entry++] = entry;
2838 nodes_to_visit.RemoveLast(); 2907 nodes_to_visit.RemoveLast();
2839 } 2908 }
2840 } 2909 }
2841 entries->Truncate(current_entry); 2910 ASSERT_EQ(current_entry, entries->length());
2842 } 2911 }
2843 2912
2844 2913
2845 static int Intersect(int i1, int i2, const Vector<HeapEntry*>& dominators) { 2914 static int Intersect(int i1, int i2, const Vector<HeapEntry*>& dominators) {
2846 int finger1 = i1, finger2 = i2; 2915 int finger1 = i1, finger2 = i2;
2847 while (finger1 != finger2) { 2916 while (finger1 != finger2) {
2848 while (finger1 < finger2) finger1 = dominators[finger1]->ordered_index(); 2917 while (finger1 < finger2) finger1 = dominators[finger1]->ordered_index();
2849 while (finger2 < finger1) finger2 = dominators[finger2]->ordered_index(); 2918 while (finger2 < finger1) finger2 = dominators[finger2]->ordered_index();
2850 } 2919 }
2851 return finger1; 2920 return finger1;
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
3326 3395
3327 3396
3328 void HeapSnapshotJSONSerializer::SortHashMap( 3397 void HeapSnapshotJSONSerializer::SortHashMap(
3329 HashMap* map, List<HashMap::Entry*>* sorted_entries) { 3398 HashMap* map, List<HashMap::Entry*>* sorted_entries) {
3330 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) 3399 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p))
3331 sorted_entries->Add(p); 3400 sorted_entries->Add(p);
3332 sorted_entries->Sort(SortUsingEntryValue); 3401 sorted_entries->Sort(SortUsingEntryValue);
3333 } 3402 }
3334 3403
3335 } } // namespace v8::internal 3404 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | src/property.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698