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

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

Issue 6596073: Refactor heap profiler's code to make possible including (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 9 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
OLDNEW
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 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 break; 1170 break;
1171 default: 1171 default:
1172 OS::Print("!!! unknown edge type: %d ", edge->type()); 1172 OS::Print("!!! unknown edge type: %d ", edge->type());
1173 } 1173 }
1174 edge->to()->Print(1, 0); 1174 edge->to()->Print(1, 0);
1175 } 1175 }
1176 OS::Print("\n"); 1176 OS::Print("\n");
1177 } 1177 }
1178 1178
1179 1179
1180 HeapObject *const HeapSnapshot::kInternalRootObject =
1181 reinterpret_cast<HeapObject*>(1);
1182 HeapObject *const HeapSnapshot::kGcRootsObject =
1183 reinterpret_cast<HeapObject*>(2);
1184
1185
1186 // It is very important to keep objects that form a heap snapshot 1180 // It is very important to keep objects that form a heap snapshot
1187 // as small as possible. 1181 // as small as possible.
1188 namespace { // Avoid littering the global namespace. 1182 namespace { // Avoid littering the global namespace.
1189 1183
1190 template <size_t ptr_size> struct SnapshotSizeConstants; 1184 template <size_t ptr_size> struct SnapshotSizeConstants;
1191 1185
1192 template <> struct SnapshotSizeConstants<4> { 1186 template <> struct SnapshotSizeConstants<4> {
1193 static const int kExpectedHeapGraphEdgeSize = 12; 1187 static const int kExpectedHeapGraphEdgeSize = 12;
1194 static const int kExpectedHeapEntrySize = 36; 1188 static const int kExpectedHeapEntrySize = 36;
1195 }; 1189 };
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 ASSERT(raw_entries_ == NULL); 1240 ASSERT(raw_entries_ == NULL);
1247 raw_entries_ = NewArray<char>( 1241 raw_entries_ = NewArray<char>(
1248 HeapEntry::EntriesSize(entries_count, children_count, retainers_count)); 1242 HeapEntry::EntriesSize(entries_count, children_count, retainers_count));
1249 #ifdef DEBUG 1243 #ifdef DEBUG
1250 raw_entries_size_ = 1244 raw_entries_size_ =
1251 HeapEntry::EntriesSize(entries_count, children_count, retainers_count); 1245 HeapEntry::EntriesSize(entries_count, children_count, retainers_count);
1252 #endif 1246 #endif
1253 } 1247 }
1254 1248
1255 1249
1256 HeapEntry* HeapSnapshot::AddEntry(HeapObject* object,
1257 int children_count,
1258 int retainers_count) {
1259 if (object == kInternalRootObject) {
1260 ASSERT(root_entry_ == NULL);
1261 ASSERT(retainers_count == 0);
1262 return (root_entry_ = AddEntry(HeapEntry::kObject,
1263 "",
1264 HeapObjectsMap::kInternalRootObjectId,
1265 0,
1266 children_count,
1267 retainers_count));
1268 } else if (object == kGcRootsObject) {
1269 ASSERT(gc_roots_entry_ == NULL);
1270 return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
1271 "(GC roots)",
1272 HeapObjectsMap::kGcRootsObjectId,
1273 0,
1274 children_count,
1275 retainers_count));
1276 } else if (object->IsJSFunction()) {
1277 JSFunction* func = JSFunction::cast(object);
1278 SharedFunctionInfo* shared = func->shared();
1279 return AddEntry(object,
1280 HeapEntry::kClosure,
1281 collection_->GetName(String::cast(shared->name())),
1282 children_count,
1283 retainers_count);
1284 } else if (object->IsJSRegExp()) {
1285 JSRegExp* re = JSRegExp::cast(object);
1286 return AddEntry(object,
1287 HeapEntry::kRegExp,
1288 collection_->GetName(re->Pattern()),
1289 children_count,
1290 retainers_count);
1291 } else if (object->IsJSObject()) {
1292 return AddEntry(object,
1293 HeapEntry::kObject,
1294 collection_->GetName(GetConstructorNameForHeapProfile(
1295 JSObject::cast(object))),
1296 children_count,
1297 retainers_count);
1298 } else if (object->IsString()) {
1299 return AddEntry(object,
1300 HeapEntry::kString,
1301 collection_->GetName(String::cast(object)),
1302 children_count,
1303 retainers_count);
1304 } else if (object->IsCode()) {
1305 return AddEntry(object,
1306 HeapEntry::kCode,
1307 "",
1308 children_count,
1309 retainers_count);
1310 } else if (object->IsSharedFunctionInfo()) {
1311 SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
1312 return AddEntry(object,
1313 HeapEntry::kCode,
1314 collection_->GetName(String::cast(shared->name())),
1315 children_count,
1316 retainers_count);
1317 } else if (object->IsScript()) {
1318 Script* script = Script::cast(object);
1319 return AddEntry(object,
1320 HeapEntry::kCode,
1321 script->name()->IsString() ?
1322 collection_->GetName(String::cast(script->name())) : "",
1323 children_count,
1324 retainers_count);
1325 } else if (object->IsFixedArray()) {
1326 return AddEntry(object,
1327 HeapEntry::kArray,
1328 "",
1329 children_count,
1330 retainers_count);
1331 } else if (object->IsHeapNumber()) {
1332 return AddEntry(object,
1333 HeapEntry::kHeapNumber,
1334 "number",
1335 children_count,
1336 retainers_count);
1337 }
1338 return AddEntry(object,
1339 HeapEntry::kHidden,
1340 "system",
1341 children_count,
1342 retainers_count);
1343 }
1344
1345
1346 static void HeapEntryClearPaint(HeapEntry** entry_ptr) { 1250 static void HeapEntryClearPaint(HeapEntry** entry_ptr) {
1347 (*entry_ptr)->clear_paint(); 1251 (*entry_ptr)->clear_paint();
1348 } 1252 }
1349 1253
1350 void HeapSnapshot::ClearPaint() { 1254 void HeapSnapshot::ClearPaint() {
1351 entries_.Iterate(HeapEntryClearPaint); 1255 entries_.Iterate(HeapEntryClearPaint);
1352 } 1256 }
1353 1257
1354 1258
1355 HeapEntry* HeapSnapshot::AddEntry(HeapObject* object, 1259 HeapEntry* HeapSnapshot::AddRootEntry(int children_count) {
1356 HeapEntry::Type type, 1260 ASSERT(root_entry_ == NULL);
1357 const char* name, 1261 return (root_entry_ = AddEntry(HeapEntry::kObject,
1358 int children_count, 1262 "",
1359 int retainers_count) { 1263 HeapObjectsMap::kInternalRootObjectId,
1360 return AddEntry(type, 1264 0,
1361 name, 1265 children_count,
1362 collection_->GetObjectId(object->address()), 1266 0));
1363 object->Size(),
1364 children_count,
1365 retainers_count);
1366 } 1267 }
1367 1268
1368 1269
1270 HeapEntry* HeapSnapshot::AddGcRootsEntry(int children_count,
1271 int retainers_count) {
1272 ASSERT(gc_roots_entry_ == NULL);
1273 return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
1274 "(GC roots)",
1275 HeapObjectsMap::kGcRootsObjectId,
1276 0,
1277 children_count,
1278 retainers_count));
1279 }
1280
1281
1369 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, 1282 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type,
1370 const char* name, 1283 const char* name,
1371 uint64_t id, 1284 uint64_t id,
1372 int size, 1285 int size,
1373 int children_count, 1286 int children_count,
1374 int retainers_count) { 1287 int retainers_count) {
1375 HeapEntry* entry = GetNextEntryToInit(); 1288 HeapEntry* entry = GetNextEntryToInit();
1376 entry->Init(this, type, name, id, size, children_count, retainers_count); 1289 entry->Init(this, type, name, id, size, children_count, retainers_count);
1377 return entry; 1290 return entry;
1378 } 1291 }
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 HeapSnapshot* snapshot1, 1521 HeapSnapshot* snapshot1,
1609 HeapSnapshot* snapshot2) { 1522 HeapSnapshot* snapshot2) {
1610 return comparator_.Compare(snapshot1, snapshot2); 1523 return comparator_.Compare(snapshot1, snapshot2);
1611 } 1524 }
1612 1525
1613 1526
1614 HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder = 1527 HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder =
1615 reinterpret_cast<HeapEntry*>(1); 1528 reinterpret_cast<HeapEntry*>(1);
1616 1529
1617 HeapEntriesMap::HeapEntriesMap() 1530 HeapEntriesMap::HeapEntriesMap()
1618 : entries_(HeapObjectsMatch), 1531 : entries_(HeapThingsMatch),
1619 entries_count_(0), 1532 entries_count_(0),
1620 total_children_count_(0), 1533 total_children_count_(0),
1621 total_retainers_count_(0) { 1534 total_retainers_count_(0) {
1622 } 1535 }
1623 1536
1624 1537
1625 HeapEntriesMap::~HeapEntriesMap() { 1538 HeapEntriesMap::~HeapEntriesMap() {
1626 for (HashMap::Entry* p = entries_.Start(); p != NULL; p = entries_.Next(p)) { 1539 for (HashMap::Entry* p = entries_.Start(); p != NULL; p = entries_.Next(p)) {
1627 delete reinterpret_cast<EntryInfo*>(p->value); 1540 delete reinterpret_cast<EntryInfo*>(p->value);
1628 } 1541 }
1629 } 1542 }
1630 1543
1631 1544
1632 HeapEntry* HeapEntriesMap::Map(HeapObject* object) { 1545 HeapEntry* HeapEntriesMap::Map(HeapThing thing) {
1633 HashMap::Entry* cache_entry = entries_.Lookup(object, Hash(object), false); 1546 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
1634 if (cache_entry != NULL) { 1547 if (cache_entry != NULL) {
1635 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value); 1548 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value);
1636 return entry_info->entry; 1549 return entry_info->entry;
1637 } else { 1550 } else {
1638 return NULL; 1551 return NULL;
1639 } 1552 }
1640 } 1553 }
1641 1554
1642 1555
1643 void HeapEntriesMap::Pair(HeapObject* object, HeapEntry* entry) { 1556 void HeapEntriesMap::Pair(
1644 HashMap::Entry* cache_entry = entries_.Lookup(object, Hash(object), true); 1557 HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry) {
1558 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), true);
1645 ASSERT(cache_entry->value == NULL); 1559 ASSERT(cache_entry->value == NULL);
1646 cache_entry->value = new EntryInfo(entry); 1560 cache_entry->value = new EntryInfo(entry, allocator);
1647 ++entries_count_; 1561 ++entries_count_;
1648 } 1562 }
1649 1563
1650 1564
1651 void HeapEntriesMap::CountReference(HeapObject* from, HeapObject* to, 1565 void HeapEntriesMap::CountReference(HeapThing from, HeapThing to,
1652 int* prev_children_count, 1566 int* prev_children_count,
1653 int* prev_retainers_count) { 1567 int* prev_retainers_count) {
1654 HashMap::Entry* from_cache_entry = entries_.Lookup(from, Hash(from), false); 1568 HashMap::Entry* from_cache_entry = entries_.Lookup(from, Hash(from), false);
1655 HashMap::Entry* to_cache_entry = entries_.Lookup(to, Hash(to), false); 1569 HashMap::Entry* to_cache_entry = entries_.Lookup(to, Hash(to), false);
1656 ASSERT(from_cache_entry != NULL); 1570 ASSERT(from_cache_entry != NULL);
1657 ASSERT(to_cache_entry != NULL); 1571 ASSERT(to_cache_entry != NULL);
1658 EntryInfo* from_entry_info = 1572 EntryInfo* from_entry_info =
1659 reinterpret_cast<EntryInfo*>(from_cache_entry->value); 1573 reinterpret_cast<EntryInfo*>(from_cache_entry->value);
1660 EntryInfo* to_entry_info = 1574 EntryInfo* to_entry_info =
1661 reinterpret_cast<EntryInfo*>(to_cache_entry->value); 1575 reinterpret_cast<EntryInfo*>(to_cache_entry->value);
1662 if (prev_children_count) 1576 if (prev_children_count)
1663 *prev_children_count = from_entry_info->children_count; 1577 *prev_children_count = from_entry_info->children_count;
1664 if (prev_retainers_count) 1578 if (prev_retainers_count)
1665 *prev_retainers_count = to_entry_info->retainers_count; 1579 *prev_retainers_count = to_entry_info->retainers_count;
1666 ++from_entry_info->children_count; 1580 ++from_entry_info->children_count;
1667 ++to_entry_info->retainers_count; 1581 ++to_entry_info->retainers_count;
1668 ++total_children_count_; 1582 ++total_children_count_;
1669 ++total_retainers_count_; 1583 ++total_retainers_count_;
1670 } 1584 }
1671 1585
1672 1586
1587 void HeapEntriesMap::UpdateEntries() {
1588 for (HashMap::Entry* p = entries_.Start();
1589 p != NULL;
1590 p = entries_.Next(p)) {
1591 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value);
1592 entry_info->entry = entry_info->allocator->AllocateEntry(
1593 p->key,
1594 entry_info->children_count,
1595 entry_info->retainers_count);
1596 entry_info->children_count = 0;
1597 entry_info->retainers_count = 0;
1598 }
1599 }
1600
1601
1673 HeapObjectsSet::HeapObjectsSet() 1602 HeapObjectsSet::HeapObjectsSet()
1674 : entries_(HeapEntriesMap::HeapObjectsMatch) { 1603 : entries_(HeapEntriesMap::HeapThingsMatch) {
1675 } 1604 }
1676 1605
1677 1606
1678 void HeapObjectsSet::Clear() { 1607 void HeapObjectsSet::Clear() {
1679 entries_.Clear(); 1608 entries_.Clear();
1680 } 1609 }
1681 1610
1682 1611
1683 bool HeapObjectsSet::Contains(Object* obj) { 1612 bool HeapObjectsSet::Contains(Object* obj) {
1684 if (!obj->IsHeapObject()) return false; 1613 if (!obj->IsHeapObject()) return false;
1685 HeapObject* object = HeapObject::cast(obj); 1614 HeapObject* object = HeapObject::cast(obj);
1686 HashMap::Entry* cache_entry = 1615 HashMap::Entry* cache_entry =
1687 entries_.Lookup(object, HeapEntriesMap::Hash(object), false); 1616 entries_.Lookup(object, HeapEntriesMap::Hash(object), false);
1688 return cache_entry != NULL; 1617 return cache_entry != NULL;
1689 } 1618 }
1690 1619
1691 1620
1692 void HeapObjectsSet::Insert(Object* obj) { 1621 void HeapObjectsSet::Insert(Object* obj) {
1693 if (!obj->IsHeapObject()) return; 1622 if (!obj->IsHeapObject()) return;
1694 HeapObject* object = HeapObject::cast(obj); 1623 HeapObject* object = HeapObject::cast(obj);
1695 HashMap::Entry* cache_entry = 1624 HashMap::Entry* cache_entry =
1696 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); 1625 entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
1697 if (cache_entry->value == NULL) { 1626 if (cache_entry->value == NULL) {
1698 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder; 1627 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder;
1699 } 1628 }
1700 } 1629 }
1701 1630
1702 1631
1703 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot, 1632 HeapObject *const V8HeapExplorer::kInternalRootObject =
1704 v8::ActivityControl* control) 1633 reinterpret_cast<HeapObject*>(1);
1634 HeapObject *const V8HeapExplorer::kGcRootsObject =
1635 reinterpret_cast<HeapObject*>(2);
1636
1637
1638 V8HeapExplorer::V8HeapExplorer(
1639 HeapSnapshot* snapshot,
1640 SnapshottingProgressReportingInterface* progress)
1705 : snapshot_(snapshot), 1641 : snapshot_(snapshot),
1706 control_(control), 1642 collection_(snapshot_->collection()),
1707 collection_(snapshot->collection()), 1643 progress_(progress),
1708 filler_(NULL) { 1644 filler_(NULL) {
1709 } 1645 }
1710 1646
1711 class SnapshotCounter : public HeapSnapshotGenerator::SnapshotFillerInterface {
1712 public:
1713 explicit SnapshotCounter(HeapEntriesMap* entries)
1714 : entries_(entries) { }
1715 HeapEntry* AddEntry(HeapObject* obj) {
1716 entries_->Pair(obj, HeapEntriesMap::kHeapEntryPlaceholder);
1717 return HeapEntriesMap::kHeapEntryPlaceholder;
1718 }
1719 void SetIndexedReference(HeapGraphEdge::Type,
1720 HeapObject* parent_obj,
1721 HeapEntry*,
1722 int,
1723 Object* child_obj,
1724 HeapEntry*) {
1725 entries_->CountReference(parent_obj, HeapObject::cast(child_obj));
1726 }
1727 void SetNamedReference(HeapGraphEdge::Type,
1728 HeapObject* parent_obj,
1729 HeapEntry*,
1730 const char*,
1731 Object* child_obj,
1732 HeapEntry*) {
1733 entries_->CountReference(parent_obj, HeapObject::cast(child_obj));
1734 }
1735 void SetRootShortcutReference(Object* child_obj, HeapEntry*) {
1736 entries_->CountReference(
1737 HeapSnapshot::kInternalRootObject, HeapObject::cast(child_obj));
1738 }
1739 void SetRootGcRootsReference() {
1740 entries_->CountReference(
1741 HeapSnapshot::kInternalRootObject, HeapSnapshot::kGcRootsObject);
1742 }
1743 void SetStrongRootReference(Object* child_obj, HeapEntry*) {
1744 entries_->CountReference(
1745 HeapSnapshot::kGcRootsObject, HeapObject::cast(child_obj));
1746 }
1747 private:
1748 HeapEntriesMap* entries_;
1749 };
1750 1647
1751 1648 V8HeapExplorer::~V8HeapExplorer() {
1752 class SnapshotFiller : public HeapSnapshotGenerator::SnapshotFillerInterface {
1753 public:
1754 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
1755 : snapshot_(snapshot),
1756 collection_(snapshot->collection()),
1757 entries_(entries) { }
1758 HeapEntry* AddEntry(HeapObject* obj) {
1759 UNREACHABLE();
1760 return NULL;
1761 }
1762 void SetIndexedReference(HeapGraphEdge::Type type,
1763 HeapObject* parent_obj,
1764 HeapEntry* parent_entry,
1765 int index,
1766 Object* child_obj,
1767 HeapEntry* child_entry) {
1768 int child_index, retainer_index;
1769 entries_->CountReference(parent_obj,
1770 HeapObject::cast(child_obj),
1771 &child_index,
1772 &retainer_index);
1773 parent_entry->SetIndexedReference(
1774 type, child_index, index, child_entry, retainer_index);
1775 }
1776 void SetNamedReference(HeapGraphEdge::Type type,
1777 HeapObject* parent_obj,
1778 HeapEntry* parent_entry,
1779 const char* reference_name,
1780 Object* child_obj,
1781 HeapEntry* child_entry) {
1782 int child_index, retainer_index;
1783 entries_->CountReference(parent_obj, HeapObject::cast(child_obj),
1784 &child_index, &retainer_index);
1785 parent_entry->SetNamedReference(type,
1786 child_index,
1787 reference_name,
1788 child_entry,
1789 retainer_index);
1790 }
1791 void SetRootGcRootsReference() {
1792 int child_index, retainer_index;
1793 entries_->CountReference(HeapSnapshot::kInternalRootObject,
1794 HeapSnapshot::kGcRootsObject,
1795 &child_index,
1796 &retainer_index);
1797 snapshot_->root()->SetIndexedReference(HeapGraphEdge::kElement,
1798 child_index,
1799 child_index + 1,
1800 snapshot_->gc_roots(),
1801 retainer_index);
1802 }
1803 void SetRootShortcutReference(Object* child_obj,
1804 HeapEntry* child_entry) {
1805 int child_index, retainer_index;
1806 entries_->CountReference(HeapSnapshot::kInternalRootObject,
1807 HeapObject::cast(child_obj),
1808 &child_index,
1809 &retainer_index);
1810 snapshot_->root()->SetNamedReference(HeapGraphEdge::kShortcut,
1811 child_index,
1812 collection_->GetName(child_index + 1),
1813 child_entry,
1814 retainer_index);
1815 }
1816 void SetStrongRootReference(Object* child_obj,
1817 HeapEntry* child_entry) {
1818 int child_index, retainer_index;
1819 entries_->CountReference(HeapSnapshot::kGcRootsObject,
1820 HeapObject::cast(child_obj),
1821 &child_index,
1822 &retainer_index);
1823 snapshot_->gc_roots()->SetIndexedReference(HeapGraphEdge::kElement,
1824 child_index,
1825 child_index + 1,
1826 child_entry,
1827 retainer_index);
1828 }
1829 private:
1830 HeapSnapshot* snapshot_;
1831 HeapSnapshotsCollection* collection_;
1832 HeapEntriesMap* entries_;
1833 };
1834
1835 class SnapshotAllocator {
1836 public:
1837 explicit SnapshotAllocator(HeapSnapshot* snapshot)
1838 : snapshot_(snapshot) { }
1839 HeapEntry* GetEntry(
1840 HeapObject* obj, int children_count, int retainers_count) {
1841 HeapEntry* entry =
1842 snapshot_->AddEntry(obj, children_count, retainers_count);
1843 ASSERT(entry != NULL);
1844 return entry;
1845 }
1846 private:
1847 HeapSnapshot* snapshot_;
1848 };
1849
1850 class RootsReferencesExtractor : public ObjectVisitor {
1851 public:
1852 explicit RootsReferencesExtractor(HeapSnapshotGenerator* generator)
1853 : generator_(generator) {
1854 }
1855 void VisitPointers(Object** start, Object** end) {
1856 for (Object** p = start; p < end; p++) generator_->SetGcRootsReference(*p);
1857 }
1858 private:
1859 HeapSnapshotGenerator* generator_;
1860 };
1861
1862
1863 bool HeapSnapshotGenerator::GenerateSnapshot() {
1864 AssertNoAllocation no_alloc;
1865
1866 SetProgressTotal(4); // 2 passes + dominators + sizes.
1867
1868 // Pass 1. Iterate heap contents to count entries and references.
1869 if (!CountEntriesAndReferences()) return false;
1870
1871 // Allocate and fill entries in the snapshot, allocate references.
1872 snapshot_->AllocateEntries(entries_.entries_count(),
1873 entries_.total_children_count(),
1874 entries_.total_retainers_count());
1875 SnapshotAllocator allocator(snapshot_);
1876 entries_.UpdateEntries(&allocator);
1877
1878 // Pass 2. Fill references.
1879 if (!FillReferences()) return false;
1880
1881 if (!SetEntriesDominators()) return false;
1882 if (!ApproximateRetainedSizes()) return false;
1883
1884 progress_counter_ = progress_total_;
1885 if (!ReportProgress(true)) return false;
1886 return true;
1887 } 1649 }
1888 1650
1889 1651
1890 HeapEntry* HeapSnapshotGenerator::GetEntry(Object* obj) { 1652 HeapEntry* V8HeapExplorer::AllocateEntry(
1891 if (!obj->IsHeapObject()) return NULL; 1653 HeapThing ptr, int children_count, int retainers_count) {
1892 HeapObject* object = HeapObject::cast(obj); 1654 return AddEntry(
1893 HeapEntry* entry = entries_.Map(object); 1655 reinterpret_cast<HeapObject*>(ptr), children_count, retainers_count);
1894 // A new entry. 1656 }
1895 if (entry == NULL) entry = filler_->AddEntry(object); 1657
1896 return entry; 1658
1659 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
1660 int children_count,
1661 int retainers_count) {
1662 if (object == kInternalRootObject) {
1663 ASSERT(retainers_count == 0);
1664 return snapshot_->AddRootEntry(children_count);
1665 } else if (object == kGcRootsObject) {
1666 return snapshot_->AddGcRootsEntry(children_count, retainers_count);
1667 } else if (object->IsJSFunction()) {
1668 JSFunction* func = JSFunction::cast(object);
1669 SharedFunctionInfo* shared = func->shared();
1670 return AddEntry(object,
1671 HeapEntry::kClosure,
1672 collection_->GetName(String::cast(shared->name())),
1673 children_count,
1674 retainers_count);
1675 } else if (object->IsJSRegExp()) {
1676 JSRegExp* re = JSRegExp::cast(object);
1677 return AddEntry(object,
1678 HeapEntry::kRegExp,
1679 collection_->GetName(re->Pattern()),
1680 children_count,
1681 retainers_count);
1682 } else if (object->IsJSObject()) {
1683 return AddEntry(object,
1684 HeapEntry::kObject,
1685 collection_->GetName(GetConstructorNameForHeapProfile(
1686 JSObject::cast(object))),
1687 children_count,
1688 retainers_count);
1689 } else if (object->IsString()) {
1690 return AddEntry(object,
1691 HeapEntry::kString,
1692 collection_->GetName(String::cast(object)),
1693 children_count,
1694 retainers_count);
1695 } else if (object->IsCode()) {
1696 return AddEntry(object,
1697 HeapEntry::kCode,
1698 "",
1699 children_count,
1700 retainers_count);
1701 } else if (object->IsSharedFunctionInfo()) {
1702 SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
1703 return AddEntry(object,
1704 HeapEntry::kCode,
1705 collection_->GetName(String::cast(shared->name())),
1706 children_count,
1707 retainers_count);
1708 } else if (object->IsScript()) {
1709 Script* script = Script::cast(object);
1710 return AddEntry(object,
1711 HeapEntry::kCode,
1712 script->name()->IsString() ?
1713 collection_->GetName(String::cast(script->name())) : "",
1714 children_count,
1715 retainers_count);
1716 } else if (object->IsFixedArray()) {
1717 return AddEntry(object,
1718 HeapEntry::kArray,
1719 "",
1720 children_count,
1721 retainers_count);
1722 } else if (object->IsHeapNumber()) {
1723 return AddEntry(object,
1724 HeapEntry::kHeapNumber,
1725 "number",
1726 children_count,
1727 retainers_count);
1728 }
1729 return AddEntry(object,
1730 HeapEntry::kHidden,
1731 "system",
1732 children_count,
1733 retainers_count);
1734 }
1735
1736
1737 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
1738 HeapEntry::Type type,
1739 const char* name,
1740 int children_count,
1741 int retainers_count) {
1742 return snapshot_->AddEntry(type,
1743 name,
1744 collection_->GetObjectId(object->address()),
1745 object->Size(),
1746 children_count,
1747 retainers_count);
1748 }
1749
1750
1751 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) {
1752 filler->AddEntry(kInternalRootObject);
1753 filler->AddEntry(kGcRootsObject);
1754 }
1755
1756
1757 int V8HeapExplorer::EstimateObjectsCount() {
1758 HeapIterator iterator(HeapIterator::kFilterUnreachable);
1759 int objects_count = 0;
1760 for (HeapObject* obj = iterator.next();
1761 obj != NULL;
1762 obj = iterator.next(), ++objects_count) {}
1763 return objects_count;
1897 } 1764 }
1898 1765
1899 1766
1900 class IndexedReferencesExtractor : public ObjectVisitor { 1767 class IndexedReferencesExtractor : public ObjectVisitor {
1901 public: 1768 public:
1902 IndexedReferencesExtractor(HeapSnapshotGenerator* generator, 1769 IndexedReferencesExtractor(V8HeapExplorer* generator,
1903 HeapObject* parent_obj, 1770 HeapObject* parent_obj,
1904 HeapEntry* parent_entry, 1771 HeapEntry* parent_entry,
1905 HeapObjectsSet* known_references = NULL) 1772 HeapObjectsSet* known_references = NULL)
1906 : generator_(generator), 1773 : generator_(generator),
1907 parent_obj_(parent_obj), 1774 parent_obj_(parent_obj),
1908 parent_(parent_entry), 1775 parent_(parent_entry),
1909 known_references_(known_references), 1776 known_references_(known_references),
1910 next_index_(1) { 1777 next_index_(1) {
1911 } 1778 }
1912 void VisitPointers(Object** start, Object** end) { 1779 void VisitPointers(Object** start, Object** end) {
1913 for (Object** p = start; p < end; p++) { 1780 for (Object** p = start; p < end; p++) {
1914 if (!known_references_ || !known_references_->Contains(*p)) { 1781 if (!known_references_ || !known_references_->Contains(*p)) {
1915 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p); 1782 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p);
1916 } 1783 }
1917 } 1784 }
1918 } 1785 }
1919 private: 1786 private:
1920 HeapSnapshotGenerator* generator_; 1787 V8HeapExplorer* generator_;
1921 HeapObject* parent_obj_; 1788 HeapObject* parent_obj_;
1922 HeapEntry* parent_; 1789 HeapEntry* parent_;
1923 HeapObjectsSet* known_references_; 1790 HeapObjectsSet* known_references_;
1924 int next_index_; 1791 int next_index_;
1925 }; 1792 };
1926 1793
1927 1794
1928 void HeapSnapshotGenerator::ExtractReferences(HeapObject* obj) { 1795 void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
1929 HeapEntry* entry = GetEntry(obj); 1796 HeapEntry* entry = GetEntry(obj);
1930 if (entry == NULL) return; // No interest in this object. 1797 if (entry == NULL) return; // No interest in this object.
1931 1798
1932 known_references_.Clear(); 1799 known_references_.Clear();
1933 if (obj->IsJSGlobalProxy()) { 1800 if (obj->IsJSGlobalProxy()) {
1934 // We need to reference JS global objects from snapshot's root. 1801 // We need to reference JS global objects from snapshot's root.
1935 // We use JSGlobalProxy because this is what embedder (e.g. browser) 1802 // We use JSGlobalProxy because this is what embedder (e.g. browser)
1936 // uses for the global object. 1803 // uses for the global object.
1937 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj); 1804 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj);
1938 SetRootShortcutReference(proxy->map()->prototype()); 1805 SetRootShortcutReference(proxy->map()->prototype());
(...skipping 23 matching lines...) Expand all
1962 SetInternalReference(obj, entry, 1, cs->first()); 1829 SetInternalReference(obj, entry, 1, cs->first());
1963 SetInternalReference(obj, entry, 2, cs->second()); 1830 SetInternalReference(obj, entry, 2, cs->second());
1964 } 1831 }
1965 } else { 1832 } else {
1966 IndexedReferencesExtractor refs_extractor(this, obj, entry); 1833 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1967 obj->Iterate(&refs_extractor); 1834 obj->Iterate(&refs_extractor);
1968 } 1835 }
1969 } 1836 }
1970 1837
1971 1838
1972 void HeapSnapshotGenerator::ExtractClosureReferences(JSObject* js_obj, 1839 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
1973 HeapEntry* entry) { 1840 HeapEntry* entry) {
1974 if (js_obj->IsJSFunction()) { 1841 if (js_obj->IsJSFunction()) {
1975 HandleScope hs; 1842 HandleScope hs;
1976 JSFunction* func = JSFunction::cast(js_obj); 1843 JSFunction* func = JSFunction::cast(js_obj);
1977 Context* context = func->context(); 1844 Context* context = func->context();
1978 ZoneScope zscope(DELETE_ON_EXIT); 1845 ZoneScope zscope(DELETE_ON_EXIT);
1979 SerializedScopeInfo* serialized_scope_info = 1846 SerializedScopeInfo* serialized_scope_info =
1980 context->closure()->shared()->scope_info(); 1847 context->closure()->shared()->scope_info();
1981 ScopeInfo<ZoneListAllocationPolicy> zone_scope_info(serialized_scope_info); 1848 ScopeInfo<ZoneListAllocationPolicy> zone_scope_info(serialized_scope_info);
1982 int locals_number = zone_scope_info.NumberOfLocals(); 1849 int locals_number = zone_scope_info.NumberOfLocals();
1983 for (int i = 0; i < locals_number; ++i) { 1850 for (int i = 0; i < locals_number; ++i) {
1984 String* local_name = *zone_scope_info.LocalName(i); 1851 String* local_name = *zone_scope_info.LocalName(i);
1985 int idx = serialized_scope_info->ContextSlotIndex(local_name, NULL); 1852 int idx = serialized_scope_info->ContextSlotIndex(local_name, NULL);
1986 if (idx >= 0 && idx < context->length()) { 1853 if (idx >= 0 && idx < context->length()) {
1987 SetClosureReference(js_obj, entry, local_name, context->get(idx)); 1854 SetClosureReference(js_obj, entry, local_name, context->get(idx));
1988 } 1855 }
1989 } 1856 }
1990 SetInternalReference(js_obj, entry, "code", func->shared()); 1857 SetInternalReference(js_obj, entry, "code", func->shared());
1991 } 1858 }
1992 } 1859 }
1993 1860
1994 1861
1995 void HeapSnapshotGenerator::ExtractPropertyReferences(JSObject* js_obj, 1862 void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
1996 HeapEntry* entry) { 1863 HeapEntry* entry) {
1997 if (js_obj->HasFastProperties()) { 1864 if (js_obj->HasFastProperties()) {
1998 DescriptorArray* descs = js_obj->map()->instance_descriptors(); 1865 DescriptorArray* descs = js_obj->map()->instance_descriptors();
1999 for (int i = 0; i < descs->number_of_descriptors(); i++) { 1866 for (int i = 0; i < descs->number_of_descriptors(); i++) {
2000 switch (descs->GetType(i)) { 1867 switch (descs->GetType(i)) {
2001 case FIELD: { 1868 case FIELD: {
2002 int index = descs->GetFieldIndex(i); 1869 int index = descs->GetFieldIndex(i);
2003 SetPropertyReference( 1870 SetPropertyReference(
2004 js_obj, entry, descs->GetKey(i), js_obj->FastPropertyAt(index)); 1871 js_obj, entry, descs->GetKey(i), js_obj->FastPropertyAt(index));
2005 break; 1872 break;
2006 } 1873 }
(...skipping 20 matching lines...) Expand all
2027 String::cast(k), 1894 String::cast(k),
2028 JSGlobalPropertyCell::cast( 1895 JSGlobalPropertyCell::cast(
2029 target)->value()); 1896 target)->value());
2030 } 1897 }
2031 } 1898 }
2032 } 1899 }
2033 } 1900 }
2034 } 1901 }
2035 1902
2036 1903
2037 void HeapSnapshotGenerator::ExtractElementReferences(JSObject* js_obj, 1904 void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj,
2038 HeapEntry* entry) { 1905 HeapEntry* entry) {
2039 if (js_obj->HasFastElements()) { 1906 if (js_obj->HasFastElements()) {
2040 FixedArray* elements = FixedArray::cast(js_obj->elements()); 1907 FixedArray* elements = FixedArray::cast(js_obj->elements());
2041 int length = js_obj->IsJSArray() ? 1908 int length = js_obj->IsJSArray() ?
2042 Smi::cast(JSArray::cast(js_obj)->length())->value() : 1909 Smi::cast(JSArray::cast(js_obj)->length())->value() :
2043 elements->length(); 1910 elements->length();
2044 for (int i = 0; i < length; ++i) { 1911 for (int i = 0; i < length; ++i) {
2045 if (!elements->get(i)->IsTheHole()) { 1912 if (!elements->get(i)->IsTheHole()) {
2046 SetElementReference(js_obj, entry, i, elements->get(i)); 1913 SetElementReference(js_obj, entry, i, elements->get(i));
2047 } 1914 }
2048 } 1915 }
2049 } else if (js_obj->HasDictionaryElements()) { 1916 } else if (js_obj->HasDictionaryElements()) {
2050 NumberDictionary* dictionary = js_obj->element_dictionary(); 1917 NumberDictionary* dictionary = js_obj->element_dictionary();
2051 int length = dictionary->Capacity(); 1918 int length = dictionary->Capacity();
2052 for (int i = 0; i < length; ++i) { 1919 for (int i = 0; i < length; ++i) {
2053 Object* k = dictionary->KeyAt(i); 1920 Object* k = dictionary->KeyAt(i);
2054 if (dictionary->IsKey(k)) { 1921 if (dictionary->IsKey(k)) {
2055 ASSERT(k->IsNumber()); 1922 ASSERT(k->IsNumber());
2056 uint32_t index = static_cast<uint32_t>(k->Number()); 1923 uint32_t index = static_cast<uint32_t>(k->Number());
2057 SetElementReference(js_obj, entry, index, dictionary->ValueAt(i)); 1924 SetElementReference(js_obj, entry, index, dictionary->ValueAt(i));
2058 } 1925 }
2059 } 1926 }
2060 } 1927 }
2061 } 1928 }
2062 1929
2063 1930
2064 void HeapSnapshotGenerator::ExtractInternalReferences(JSObject* js_obj, 1931 void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj,
2065 HeapEntry* entry) { 1932 HeapEntry* entry) {
2066 int length = js_obj->GetInternalFieldCount(); 1933 int length = js_obj->GetInternalFieldCount();
2067 for (int i = 0; i < length; ++i) { 1934 for (int i = 0; i < length; ++i) {
2068 Object* o = js_obj->GetInternalField(i); 1935 Object* o = js_obj->GetInternalField(i);
2069 SetInternalReference(js_obj, entry, i, o); 1936 SetInternalReference(js_obj, entry, i, o);
2070 } 1937 }
2071 } 1938 }
2072 1939
2073 1940
2074 void HeapSnapshotGenerator::SetClosureReference(HeapObject* parent_obj, 1941 HeapEntry* V8HeapExplorer::GetEntry(Object* obj) {
2075 HeapEntry* parent_entry, 1942 if (!obj->IsHeapObject()) return NULL;
2076 String* reference_name, 1943 return filler_->FindOrAddEntry(obj);
2077 Object* child_obj) { 1944 }
1945
1946
1947 class RootsReferencesExtractor : public ObjectVisitor {
1948 public:
1949 explicit RootsReferencesExtractor(V8HeapExplorer* explorer)
1950 : explorer_(explorer) {
1951 }
1952 void VisitPointers(Object** start, Object** end) {
1953 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p);
1954 }
1955 private:
1956 V8HeapExplorer* explorer_;
1957 };
1958
1959
1960 bool V8HeapExplorer::IterateAndExtractReferences(
1961 SnapshotFillerInterface* filler) {
1962 filler_ = filler;
1963 HeapIterator iterator(HeapIterator::kFilterUnreachable);
1964 bool interrupted = false;
1965 // Heap iteration with filtering must be finished in any case.
1966 for (HeapObject* obj = iterator.next();
1967 obj != NULL;
1968 obj = iterator.next(), progress_->ProgressStep()) {
1969 if (!interrupted) {
1970 ExtractReferences(obj);
1971 if (!progress_->ProgressReport(false)) interrupted = true;
1972 }
1973 }
1974 if (interrupted) {
1975 filler_ = NULL;
1976 return false;
1977 }
1978 SetRootGcRootsReference();
1979 RootsReferencesExtractor extractor(this);
1980 Heap::IterateRoots(&extractor, VISIT_ALL);
1981 filler_ = NULL;
1982 return progress_->ProgressReport(false);
1983 }
1984
1985
1986 void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
1987 HeapEntry* parent_entry,
1988 String* reference_name,
1989 Object* child_obj) {
2078 HeapEntry* child_entry = GetEntry(child_obj); 1990 HeapEntry* child_entry = GetEntry(child_obj);
2079 if (child_entry != NULL) { 1991 if (child_entry != NULL) {
2080 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, 1992 filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
2081 parent_obj, 1993 parent_obj,
2082 parent_entry, 1994 parent_entry,
2083 collection_->GetName(reference_name), 1995 collection_->GetName(reference_name),
2084 child_obj, 1996 child_obj,
2085 child_entry); 1997 child_entry);
2086 known_references_.Insert(child_obj); 1998 known_references_.Insert(child_obj);
2087 } 1999 }
2088 } 2000 }
2089 2001
2090 2002
2091 void HeapSnapshotGenerator::SetElementReference(HeapObject* parent_obj, 2003 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
2092 HeapEntry* parent_entry, 2004 HeapEntry* parent_entry,
2093 int index, 2005 int index,
2094 Object* child_obj) { 2006 Object* child_obj) {
2095 HeapEntry* child_entry = GetEntry(child_obj); 2007 HeapEntry* child_entry = GetEntry(child_obj);
2096 if (child_entry != NULL) { 2008 if (child_entry != NULL) {
2097 filler_->SetIndexedReference(HeapGraphEdge::kElement, 2009 filler_->SetIndexedReference(HeapGraphEdge::kElement,
2098 parent_obj, 2010 parent_obj,
2099 parent_entry, 2011 parent_entry,
2100 index, 2012 index,
2101 child_obj, 2013 child_obj,
2102 child_entry); 2014 child_entry);
2103 known_references_.Insert(child_obj); 2015 known_references_.Insert(child_obj);
2104 } 2016 }
2105 } 2017 }
2106 2018
2107 2019
2108 void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj, 2020 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
2109 HeapEntry* parent_entry, 2021 HeapEntry* parent_entry,
2110 const char* reference_name, 2022 const char* reference_name,
2111 Object* child_obj) { 2023 Object* child_obj) {
2112 HeapEntry* child_entry = GetEntry(child_obj); 2024 HeapEntry* child_entry = GetEntry(child_obj);
2113 if (child_entry != NULL) { 2025 if (child_entry != NULL) {
2114 filler_->SetNamedReference(HeapGraphEdge::kInternal, 2026 filler_->SetNamedReference(HeapGraphEdge::kInternal,
2115 parent_obj, 2027 parent_obj,
2116 parent_entry, 2028 parent_entry,
2117 reference_name, 2029 reference_name,
2118 child_obj, 2030 child_obj,
2119 child_entry); 2031 child_entry);
2120 known_references_.Insert(child_obj); 2032 known_references_.Insert(child_obj);
2121 } 2033 }
2122 } 2034 }
2123 2035
2124 2036
2125 void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj, 2037 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
2126 HeapEntry* parent_entry, 2038 HeapEntry* parent_entry,
2127 int index, 2039 int index,
2128 Object* child_obj) { 2040 Object* child_obj) {
2129 HeapEntry* child_entry = GetEntry(child_obj); 2041 HeapEntry* child_entry = GetEntry(child_obj);
2130 if (child_entry != NULL) { 2042 if (child_entry != NULL) {
2131 filler_->SetNamedReference(HeapGraphEdge::kInternal, 2043 filler_->SetNamedReference(HeapGraphEdge::kInternal,
2132 parent_obj, 2044 parent_obj,
2133 parent_entry, 2045 parent_entry,
2134 collection_->GetName(index), 2046 collection_->GetName(index),
2135 child_obj, 2047 child_obj,
2136 child_entry); 2048 child_entry);
2137 known_references_.Insert(child_obj); 2049 known_references_.Insert(child_obj);
2138 } 2050 }
2139 } 2051 }
2140 2052
2141 2053
2142 void HeapSnapshotGenerator::SetHiddenReference(HeapObject* parent_obj, 2054 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
2143 HeapEntry* parent_entry, 2055 HeapEntry* parent_entry,
2144 int index, 2056 int index,
2145 Object* child_obj) { 2057 Object* child_obj) {
2146 HeapEntry* child_entry = GetEntry(child_obj); 2058 HeapEntry* child_entry = GetEntry(child_obj);
2147 if (child_entry != NULL) { 2059 if (child_entry != NULL) {
2148 filler_->SetIndexedReference(HeapGraphEdge::kHidden, 2060 filler_->SetIndexedReference(HeapGraphEdge::kHidden,
2149 parent_obj, 2061 parent_obj,
2150 parent_entry, 2062 parent_entry,
2151 index, 2063 index,
2152 child_obj, 2064 child_obj,
2153 child_entry); 2065 child_entry);
2154 } 2066 }
2155 } 2067 }
2156 2068
2157 2069
2158 void HeapSnapshotGenerator::SetPropertyReference(HeapObject* parent_obj, 2070 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
2159 HeapEntry* parent_entry, 2071 HeapEntry* parent_entry,
2160 String* reference_name, 2072 String* reference_name,
2161 Object* child_obj) { 2073 Object* child_obj) {
2162 HeapEntry* child_entry = GetEntry(child_obj); 2074 HeapEntry* child_entry = GetEntry(child_obj);
2163 if (child_entry != NULL) { 2075 if (child_entry != NULL) {
2164 HeapGraphEdge::Type type = reference_name->length() > 0 ? 2076 HeapGraphEdge::Type type = reference_name->length() > 0 ?
2165 HeapGraphEdge::kProperty : HeapGraphEdge::kInternal; 2077 HeapGraphEdge::kProperty : HeapGraphEdge::kInternal;
2166 filler_->SetNamedReference(type, 2078 filler_->SetNamedReference(type,
2167 parent_obj, 2079 parent_obj,
2168 parent_entry, 2080 parent_entry,
2169 collection_->GetName(reference_name), 2081 collection_->GetName(reference_name),
2170 child_obj, 2082 child_obj,
2171 child_entry); 2083 child_entry);
2172 known_references_.Insert(child_obj); 2084 known_references_.Insert(child_obj);
2173 } 2085 }
2174 } 2086 }
2175 2087
2176 2088
2177 void HeapSnapshotGenerator::SetPropertyShortcutReference( 2089 void V8HeapExplorer::SetPropertyShortcutReference(
2178 HeapObject* parent_obj, 2090 HeapObject* parent_obj,
2179 HeapEntry* parent_entry, 2091 HeapEntry* parent_entry,
2180 String* reference_name, 2092 String* reference_name,
2181 Object* child_obj) { 2093 Object* child_obj) {
2182 HeapEntry* child_entry = GetEntry(child_obj); 2094 HeapEntry* child_entry = GetEntry(child_obj);
2183 if (child_entry != NULL) { 2095 if (child_entry != NULL) {
2184 filler_->SetNamedReference(HeapGraphEdge::kShortcut, 2096 filler_->SetNamedReference(HeapGraphEdge::kShortcut,
2185 parent_obj, 2097 parent_obj,
2186 parent_entry, 2098 parent_entry,
2187 collection_->GetName(reference_name), 2099 collection_->GetName(reference_name),
2188 child_obj, 2100 child_obj,
2189 child_entry); 2101 child_entry);
2190 } 2102 }
2191 } 2103 }
2192 2104
2193 2105
2194 void HeapSnapshotGenerator::SetRootGcRootsReference() { 2106 void V8HeapExplorer::SetRootGcRootsReference() {
2195 filler_->SetRootGcRootsReference(); 2107 filler_->SetIndexedAutoIndexReference(
2196 } 2108 HeapGraphEdge::kElement,
2197 2109 kInternalRootObject, snapshot_->root(),
2198 2110 kGcRootsObject, snapshot_->gc_roots());
2199 void HeapSnapshotGenerator::SetRootShortcutReference(Object* child_obj) { 2111 }
2112
2113
2114 void V8HeapExplorer::SetRootShortcutReference(Object* child_obj) {
2200 HeapEntry* child_entry = GetEntry(child_obj); 2115 HeapEntry* child_entry = GetEntry(child_obj);
2201 ASSERT(child_entry != NULL); 2116 ASSERT(child_entry != NULL);
2202 filler_->SetRootShortcutReference(child_obj, child_entry); 2117 filler_->SetNamedAutoIndexReference(
2203 } 2118 HeapGraphEdge::kShortcut,
2204 2119 kInternalRootObject, snapshot_->root(),
2205 2120 child_obj, child_entry);
2206 void HeapSnapshotGenerator::SetGcRootsReference(Object* child_obj) { 2121 }
2122
2123
2124 void V8HeapExplorer::SetGcRootsReference(Object* child_obj) {
2207 HeapEntry* child_entry = GetEntry(child_obj); 2125 HeapEntry* child_entry = GetEntry(child_obj);
2208 if (child_entry != NULL) { 2126 if (child_entry != NULL) {
2209 filler_->SetStrongRootReference(child_obj, child_entry); 2127 filler_->SetIndexedAutoIndexReference(
2210 } 2128 HeapGraphEdge::kElement,
2129 kGcRootsObject, snapshot_->gc_roots(),
2130 child_obj, child_entry);
2131 }
2132 }
2133
2134
2135 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
2136 v8::ActivityControl* control)
2137 : snapshot_(snapshot),
2138 control_(control),
2139 v8_heap_explorer_(snapshot_, this) {
2140 }
2141
2142
2143 class SnapshotCounter : public SnapshotFillerInterface {
2144 public:
2145 SnapshotCounter(HeapEntriesAllocator* allocator, HeapEntriesMap* entries)
2146 : allocator_(allocator), entries_(entries) { }
2147 HeapEntry* AddEntry(HeapThing ptr) {
2148 entries_->Pair(ptr, allocator_, HeapEntriesMap::kHeapEntryPlaceholder);
2149 return HeapEntriesMap::kHeapEntryPlaceholder;
2150 }
2151 HeapEntry* FindOrAddEntry(HeapThing ptr) {
2152 HeapEntry* entry = entries_->Map(ptr);
2153 return entry != NULL ? entry : AddEntry(ptr);
2154 }
2155 void SetIndexedReference(HeapGraphEdge::Type,
2156 HeapThing parent_ptr,
2157 HeapEntry*,
2158 int,
2159 HeapThing child_ptr,
2160 HeapEntry*) {
2161 entries_->CountReference(parent_ptr, child_ptr);
2162 }
2163 void SetIndexedAutoIndexReference(HeapGraphEdge::Type,
2164 HeapThing parent_ptr,
2165 HeapEntry*,
2166 HeapThing child_ptr,
2167 HeapEntry*) {
2168 entries_->CountReference(parent_ptr, child_ptr);
2169 }
2170 void SetNamedReference(HeapGraphEdge::Type,
2171 HeapThing parent_ptr,
2172 HeapEntry*,
2173 const char*,
2174 HeapThing child_ptr,
2175 HeapEntry*) {
2176 entries_->CountReference(parent_ptr, child_ptr);
2177 }
2178 void SetNamedAutoIndexReference(HeapGraphEdge::Type,
2179 HeapThing parent_ptr,
2180 HeapEntry*,
2181 HeapThing child_ptr,
2182 HeapEntry*) {
2183 entries_->CountReference(parent_ptr, child_ptr);
2184 }
2185 private:
2186 HeapEntriesAllocator* allocator_;
2187 HeapEntriesMap* entries_;
2188 };
2189
2190
2191 class SnapshotFiller : public SnapshotFillerInterface {
2192 public:
2193 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
2194 : snapshot_(snapshot),
2195 collection_(snapshot->collection()),
2196 entries_(entries) { }
2197 HeapEntry* AddEntry(HeapThing ptr) {
2198 UNREACHABLE();
2199 return NULL;
2200 }
2201 HeapEntry* FindOrAddEntry(HeapThing ptr) {
2202 HeapEntry* entry = entries_->Map(ptr);
2203 return entry != NULL ? entry : AddEntry(ptr);
2204 }
2205 void SetIndexedReference(HeapGraphEdge::Type type,
2206 HeapThing parent_ptr,
2207 HeapEntry* parent_entry,
2208 int index,
2209 HeapThing child_ptr,
2210 HeapEntry* child_entry) {
2211 int child_index, retainer_index;
2212 entries_->CountReference(
2213 parent_ptr, child_ptr, &child_index, &retainer_index);
2214 parent_entry->SetIndexedReference(
2215 type, child_index, index, child_entry, retainer_index);
2216 }
2217 void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
2218 HeapThing parent_ptr,
2219 HeapEntry* parent_entry,
2220 HeapThing child_ptr,
2221 HeapEntry* child_entry) {
2222 int child_index, retainer_index;
2223 entries_->CountReference(
2224 parent_ptr, child_ptr, &child_index, &retainer_index);
2225 parent_entry->SetIndexedReference(
2226 type, child_index, child_index + 1, child_entry, retainer_index);
2227 }
2228 void SetNamedReference(HeapGraphEdge::Type type,
2229 HeapThing parent_ptr,
2230 HeapEntry* parent_entry,
2231 const char* reference_name,
2232 HeapThing child_ptr,
2233 HeapEntry* child_entry) {
2234 int child_index, retainer_index;
2235 entries_->CountReference(
2236 parent_ptr, child_ptr, &child_index, &retainer_index);
2237 parent_entry->SetNamedReference(
2238 type, child_index, reference_name, child_entry, retainer_index);
2239 }
2240 void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
2241 HeapThing parent_ptr,
2242 HeapEntry* parent_entry,
2243 HeapThing child_ptr,
2244 HeapEntry* child_entry) {
2245 int child_index, retainer_index;
2246 entries_->CountReference(
2247 parent_ptr, child_ptr, &child_index, &retainer_index);
2248 parent_entry->SetNamedReference(type,
2249 child_index,
2250 collection_->GetName(child_index + 1),
2251 child_entry,
2252 retainer_index);
2253 }
2254 private:
2255 HeapSnapshot* snapshot_;
2256 HeapSnapshotsCollection* collection_;
2257 HeapEntriesMap* entries_;
2258 };
2259
2260
2261 bool HeapSnapshotGenerator::GenerateSnapshot() {
2262 AssertNoAllocation no_alloc;
2263
2264 SetProgressTotal(4); // 2 passes + dominators + sizes.
2265
2266 // Pass 1. Iterate heap contents to count entries and references.
2267 if (!CountEntriesAndReferences()) return false;
2268
2269 // Allocate and fill entries in the snapshot, allocate references.
2270 snapshot_->AllocateEntries(entries_.entries_count(),
2271 entries_.total_children_count(),
2272 entries_.total_retainers_count());
2273 entries_.UpdateEntries();
2274
2275 // Pass 2. Fill references.
2276 if (!FillReferences()) return false;
2277
2278 if (!SetEntriesDominators()) return false;
2279 if (!ApproximateRetainedSizes()) return false;
2280
2281 progress_counter_ = progress_total_;
2282 if (!ProgressReport(true)) return false;
2283 return true;
2284 }
2285
2286
2287 void HeapSnapshotGenerator::ProgressStep() {
2288 ++progress_counter_;
2289 }
2290
2291
2292 bool HeapSnapshotGenerator::ProgressReport(bool force) {
2293 const int kProgressReportGranularity = 10000;
2294 if (control_ != NULL
2295 && (force || progress_counter_ % kProgressReportGranularity == 0)) {
2296 return
2297 control_->ReportProgressValue(progress_counter_, progress_total_) ==
2298 v8::ActivityControl::kContinue;
2299 }
2300 return true;
2211 } 2301 }
2212 2302
2213 2303
2214 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) { 2304 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
2215 if (control_ == NULL) return; 2305 if (control_ == NULL) return;
2216 2306 progress_total_ = v8_heap_explorer_.EstimateObjectsCount() * iterations_count;
2217 HeapIterator iterator(HeapIterator::kFilterUnreachable);
2218 int objects_count = 0;
2219 for (HeapObject* obj = iterator.next();
2220 obj != NULL;
2221 obj = iterator.next(), ++objects_count) {}
2222 progress_total_ = objects_count * iterations_count;
2223 progress_counter_ = 0; 2307 progress_counter_ = 0;
2224 } 2308 }
2225 2309
2226 2310
2227 bool HeapSnapshotGenerator::CountEntriesAndReferences() { 2311 bool HeapSnapshotGenerator::CountEntriesAndReferences() {
2228 SnapshotCounter counter(&entries_); 2312 SnapshotCounter counter(&v8_heap_explorer_, &entries_);
2229 filler_ = &counter; 2313 v8_heap_explorer_.AddRootEntries(&counter);
2230 filler_->AddEntry(HeapSnapshot::kInternalRootObject); 2314 return v8_heap_explorer_.IterateAndExtractReferences(&counter);
2231 filler_->AddEntry(HeapSnapshot::kGcRootsObject);
2232 return IterateAndExtractReferences();
2233 } 2315 }
2234 2316
2235 2317
2236 bool HeapSnapshotGenerator::FillReferences() { 2318 bool HeapSnapshotGenerator::FillReferences() {
2237 SnapshotFiller filler(snapshot_, &entries_); 2319 SnapshotFiller filler(snapshot_, &entries_);
2238 filler_ = &filler; 2320 return v8_heap_explorer_.IterateAndExtractReferences(&filler);
2239 return IterateAndExtractReferences(); 2321 }
2240 } 2322
2241 2323
2242
2243 void HeapSnapshotGenerator::FillReversePostorderIndexes( 2324 void HeapSnapshotGenerator::FillReversePostorderIndexes(
2244 Vector<HeapEntry*>* entries) { 2325 Vector<HeapEntry*>* entries) {
2245 snapshot_->ClearPaint(); 2326 snapshot_->ClearPaint();
2246 int current_entry = 0; 2327 int current_entry = 0;
2247 List<HeapEntry*> nodes_to_visit; 2328 List<HeapEntry*> nodes_to_visit;
2248 nodes_to_visit.Add(snapshot_->root()); 2329 nodes_to_visit.Add(snapshot_->root());
2249 snapshot_->root()->paint_reachable(); 2330 snapshot_->root()->paint_reachable();
2250 while (!nodes_to_visit.is_empty()) { 2331 while (!nodes_to_visit.is_empty()) {
2251 HeapEntry* entry = nodes_to_visit.last(); 2332 HeapEntry* entry = nodes_to_visit.last();
2252 Vector<HeapGraphEdge> children = entry->children(); 2333 Vector<HeapGraphEdge> children = entry->children();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 } 2396 }
2316 } 2397 }
2317 if (new_idom != NULL && dominators->at(i) != new_idom) { 2398 if (new_idom != NULL && dominators->at(i) != new_idom) {
2318 (*dominators)[i] = new_idom; 2399 (*dominators)[i] = new_idom;
2319 ++changed; 2400 ++changed;
2320 } 2401 }
2321 } 2402 }
2322 int remaining = entries_length - changed; 2403 int remaining = entries_length - changed;
2323 if (remaining < 0) remaining = 0; 2404 if (remaining < 0) remaining = 0;
2324 progress_counter_ = base_progress_counter + remaining; 2405 progress_counter_ = base_progress_counter + remaining;
2325 if (!ReportProgress(true)) return false; 2406 if (!ProgressReport(true)) return false;
2326 } 2407 }
2327 return true; 2408 return true;
2328 } 2409 }
2329 2410
2330 2411
2331 bool HeapSnapshotGenerator::SetEntriesDominators() { 2412 bool HeapSnapshotGenerator::SetEntriesDominators() {
2332 // This array is used for maintaining reverse postorder of nodes. 2413 // This array is used for maintaining reverse postorder of nodes.
2333 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length()); 2414 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length());
2334 FillReversePostorderIndexes(&ordered_entries); 2415 FillReversePostorderIndexes(&ordered_entries);
2335 ScopedVector<HeapEntry*> dominators(ordered_entries.length()); 2416 ScopedVector<HeapEntry*> dominators(ordered_entries.length());
2336 if (!BuildDominatorTree(ordered_entries, &dominators)) return false; 2417 if (!BuildDominatorTree(ordered_entries, &dominators)) return false;
2337 for (int i = 0; i < ordered_entries.length(); ++i) { 2418 for (int i = 0; i < ordered_entries.length(); ++i) {
2338 ASSERT(dominators[i] != NULL); 2419 ASSERT(dominators[i] != NULL);
2339 ordered_entries[i]->set_dominator(dominators[i]); 2420 ordered_entries[i]->set_dominator(dominators[i]);
2340 } 2421 }
2341 return true; 2422 return true;
2342 } 2423 }
2343 2424
2344 2425
2345 bool HeapSnapshotGenerator::ApproximateRetainedSizes() { 2426 bool HeapSnapshotGenerator::ApproximateRetainedSizes() {
2346 // As for the dominators tree we only know parent nodes, not 2427 // As for the dominators tree we only know parent nodes, not
2347 // children, to sum up total sizes we "bubble" node's self size 2428 // children, to sum up total sizes we "bubble" node's self size
2348 // adding it to all of its parents. 2429 // adding it to all of its parents.
2349 for (int i = 0; i < snapshot_->entries()->length(); ++i) { 2430 for (int i = 0; i < snapshot_->entries()->length(); ++i) {
2350 HeapEntry* entry = snapshot_->entries()->at(i); 2431 HeapEntry* entry = snapshot_->entries()->at(i);
2351 entry->set_retained_size(entry->self_size()); 2432 entry->set_retained_size(entry->self_size());
2352 } 2433 }
2353 for (int i = 0; 2434 for (int i = 0;
2354 i < snapshot_->entries()->length(); 2435 i < snapshot_->entries()->length();
2355 ++i, IncProgressCounter()) { 2436 ++i, ProgressStep()) {
2356 HeapEntry* entry = snapshot_->entries()->at(i); 2437 HeapEntry* entry = snapshot_->entries()->at(i);
2357 int entry_size = entry->self_size(); 2438 int entry_size = entry->self_size();
2358 for (HeapEntry* dominator = entry->dominator(); 2439 for (HeapEntry* dominator = entry->dominator();
2359 dominator != entry; 2440 dominator != entry;
2360 entry = dominator, dominator = entry->dominator()) { 2441 entry = dominator, dominator = entry->dominator()) {
2361 dominator->add_retained_size(entry_size); 2442 dominator->add_retained_size(entry_size);
2362 } 2443 }
2363 if (!ReportProgress()) return false; 2444 if (!ProgressReport()) return false;
2364 } 2445 }
2365 return true; 2446 return true;
2366 } 2447 }
2367 2448
2368 2449
2369 bool HeapSnapshotGenerator::IterateAndExtractReferences() {
2370 HeapIterator iterator(HeapIterator::kFilterUnreachable);
2371 bool interrupted = false;
2372 // Heap iteration with filtering must be finished in any case.
2373 for (HeapObject* obj = iterator.next();
2374 obj != NULL;
2375 obj = iterator.next(), IncProgressCounter()) {
2376 if (!interrupted) {
2377 ExtractReferences(obj);
2378 if (!ReportProgress()) interrupted = true;
2379 }
2380 }
2381 if (interrupted) return false;
2382 SetRootGcRootsReference();
2383 RootsReferencesExtractor extractor(this);
2384 Heap::IterateRoots(&extractor, VISIT_ALL);
2385 return ReportProgress();
2386 }
2387
2388
2389 void HeapSnapshotsDiff::CreateRoots(int additions_count, int deletions_count) { 2450 void HeapSnapshotsDiff::CreateRoots(int additions_count, int deletions_count) {
2390 raw_additions_root_ = 2451 raw_additions_root_ =
2391 NewArray<char>(HeapEntry::EntriesSize(1, additions_count, 0)); 2452 NewArray<char>(HeapEntry::EntriesSize(1, additions_count, 0));
2392 additions_root()->Init( 2453 additions_root()->Init(
2393 snapshot2_, HeapEntry::kHidden, "", 0, 0, additions_count, 0); 2454 snapshot2_, HeapEntry::kHidden, "", 0, 0, additions_count, 0);
2394 raw_deletions_root_ = 2455 raw_deletions_root_ =
2395 NewArray<char>(HeapEntry::EntriesSize(1, deletions_count, 0)); 2456 NewArray<char>(HeapEntry::EntriesSize(1, deletions_count, 0));
2396 deletions_root()->Init( 2457 deletions_root()->Init(
2397 snapshot1_, HeapEntry::kHidden, "", 0, 0, deletions_count, 0); 2458 snapshot1_, HeapEntry::kHidden, "", 0, 0, deletions_count, 0);
2398 } 2459 }
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2829 2890
2830 2891
2831 String* GetConstructorNameForHeapProfile(JSObject* object) { 2892 String* GetConstructorNameForHeapProfile(JSObject* object) {
2832 if (object->IsJSFunction()) return Heap::closure_symbol(); 2893 if (object->IsJSFunction()) return Heap::closure_symbol();
2833 return object->constructor_name(); 2894 return object->constructor_name();
2834 } 2895 }
2835 2896
2836 } } // namespace v8::internal 2897 } } // namespace v8::internal
2837 2898
2838 #endif // ENABLE_LOGGING_AND_PROFILING 2899 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698