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

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

Issue 6580038: [Isolates] Merge from bleeding_edge, revisions 5934-6100. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 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/profile-generator-inl.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 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 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 uint64_t id, 1379 uint64_t id,
1380 int size, 1380 int size,
1381 int children_count, 1381 int children_count,
1382 int retainers_count) { 1382 int retainers_count) {
1383 HeapEntry* entry = GetNextEntryToInit(); 1383 HeapEntry* entry = GetNextEntryToInit();
1384 entry->Init(this, type, name, id, size, children_count, retainers_count); 1384 entry->Init(this, type, name, id, size, children_count, retainers_count);
1385 return entry; 1385 return entry;
1386 } 1386 }
1387 1387
1388 1388
1389 void HeapSnapshot::FillReversePostorderIndexes(Vector<HeapEntry*>* entries) {
1390 ClearPaint();
1391 int current_entry = 0;
1392 List<HeapEntry*> nodes_to_visit;
1393 nodes_to_visit.Add(root());
1394 root()->paint_reachable();
1395 while (!nodes_to_visit.is_empty()) {
1396 HeapEntry* entry = nodes_to_visit.last();
1397 Vector<HeapGraphEdge> children = entry->children();
1398 bool has_new_edges = false;
1399 for (int i = 0; i < children.length(); ++i) {
1400 if (children[i].type() == HeapGraphEdge::kShortcut) continue;
1401 HeapEntry* child = children[i].to();
1402 if (!child->painted_reachable()) {
1403 nodes_to_visit.Add(child);
1404 child->paint_reachable();
1405 has_new_edges = true;
1406 }
1407 }
1408 if (!has_new_edges) {
1409 entry->set_ordered_index(current_entry);
1410 (*entries)[current_entry++] = entry;
1411 nodes_to_visit.RemoveLast();
1412 }
1413 }
1414 entries->Truncate(current_entry);
1415 }
1416
1417
1418 static int Intersect(int i1, int i2, const Vector<HeapEntry*>& dominators) {
1419 int finger1 = i1, finger2 = i2;
1420 while (finger1 != finger2) {
1421 while (finger1 < finger2) finger1 = dominators[finger1]->ordered_index();
1422 while (finger2 < finger1) finger2 = dominators[finger2]->ordered_index();
1423 }
1424 return finger1;
1425 }
1426
1427 // The algorithm is based on the article:
1428 // K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm"
1429 // Softw. Pract. Exper. 4 (2001), pp. 1–10.
1430 void HeapSnapshot::BuildDominatorTree(const Vector<HeapEntry*>& entries,
1431 Vector<HeapEntry*>* dominators) {
1432 if (entries.length() == 0) return;
1433 const int root_index = entries.length() - 1;
1434 for (int i = 0; i < root_index; ++i) (*dominators)[i] = NULL;
1435 (*dominators)[root_index] = entries[root_index];
1436 bool changed = true;
1437 while (changed) {
1438 changed = false;
1439 for (int i = root_index - 1; i >= 0; --i) {
1440 HeapEntry* new_idom = NULL;
1441 Vector<HeapGraphEdge*> rets = entries[i]->retainers();
1442 int j = 0;
1443 for (; j < rets.length(); ++j) {
1444 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue;
1445 HeapEntry* ret = rets[j]->From();
1446 if (dominators->at(ret->ordered_index()) != NULL) {
1447 new_idom = ret;
1448 break;
1449 }
1450 }
1451 for (++j; j < rets.length(); ++j) {
1452 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue;
1453 HeapEntry* ret = rets[j]->From();
1454 if (dominators->at(ret->ordered_index()) != NULL) {
1455 new_idom = entries[Intersect(ret->ordered_index(),
1456 new_idom->ordered_index(),
1457 *dominators)];
1458 }
1459 }
1460 if (new_idom != NULL && dominators->at(i) != new_idom) {
1461 (*dominators)[i] = new_idom;
1462 changed = true;
1463 }
1464 }
1465 }
1466 }
1467
1468
1469 void HeapSnapshot::SetDominatorsToSelf() { 1389 void HeapSnapshot::SetDominatorsToSelf() {
1470 for (int i = 0; i < entries_.length(); ++i) { 1390 for (int i = 0; i < entries_.length(); ++i) {
1471 HeapEntry* entry = entries_[i]; 1391 HeapEntry* entry = entries_[i];
1472 if (entry->dominator() == NULL) entry->set_dominator(entry); 1392 if (entry->dominator() == NULL) entry->set_dominator(entry);
1473 } 1393 }
1474 } 1394 }
1475 1395
1476 1396
1477 void HeapSnapshot::SetEntriesDominators() {
1478 // This array is used for maintaining reverse postorder of nodes.
1479 ScopedVector<HeapEntry*> ordered_entries(entries_.length());
1480 FillReversePostorderIndexes(&ordered_entries);
1481 ScopedVector<HeapEntry*> dominators(ordered_entries.length());
1482 BuildDominatorTree(ordered_entries, &dominators);
1483 for (int i = 0; i < ordered_entries.length(); ++i) {
1484 ASSERT(dominators[i] != NULL);
1485 ordered_entries[i]->set_dominator(dominators[i]);
1486 }
1487 // For nodes unreachable from root, set dominator to itself.
1488 SetDominatorsToSelf();
1489 }
1490
1491
1492 void HeapSnapshot::ApproximateRetainedSizes() {
1493 SetEntriesDominators();
1494 // As for the dominators tree we only know parent nodes, not
1495 // children, to sum up total sizes we traverse the tree level by
1496 // level upwards, starting from leaves.
1497 for (int i = 0; i < entries_.length(); ++i) {
1498 HeapEntry* entry = entries_[i];
1499 entry->set_retained_size(entry->self_size());
1500 entry->set_leaf();
1501 }
1502 while (true) {
1503 bool onlyLeaves = true;
1504 for (int i = 0; i < entries_.length(); ++i) {
1505 HeapEntry *entry = entries_[i], *dominator = entry->dominator();
1506 if (!entry->is_processed() && dominator != entry) {
1507 dominator->set_non_leaf();
1508 onlyLeaves = false;
1509 }
1510 }
1511 if (onlyLeaves) break;
1512
1513 for (int i = 0; i < entries_.length(); ++i) {
1514 HeapEntry *entry = entries_[i], *dominator = entry->dominator();
1515 if (entry->is_leaf() && dominator != entry) {
1516 dominator->add_retained_size(entry->retained_size());
1517 }
1518 }
1519
1520 // Mark all current leaves as processed, reset non-leaves back to leaves.
1521 for (int i = 0; i < entries_.length(); ++i) {
1522 HeapEntry* entry = entries_[i];
1523 if (entry->is_leaf())
1524 entry->set_processed();
1525 else if (entry->is_non_leaf())
1526 entry->set_leaf();
1527 }
1528 }
1529 }
1530
1531
1532 HeapEntry* HeapSnapshot::GetNextEntryToInit() { 1397 HeapEntry* HeapSnapshot::GetNextEntryToInit() {
1533 if (entries_.length() > 0) { 1398 if (entries_.length() > 0) {
1534 HeapEntry* last_entry = entries_.last(); 1399 HeapEntry* last_entry = entries_.last();
1535 entries_.Add(reinterpret_cast<HeapEntry*>( 1400 entries_.Add(reinterpret_cast<HeapEntry*>(
1536 reinterpret_cast<char*>(last_entry) + last_entry->EntrySize())); 1401 reinterpret_cast<char*>(last_entry) + last_entry->EntrySize()));
1537 } else { 1402 } else {
1538 entries_.Add(reinterpret_cast<HeapEntry*>(raw_entries_)); 1403 entries_.Add(reinterpret_cast<HeapEntry*>(raw_entries_));
1539 } 1404 }
1540 ASSERT(reinterpret_cast<char*>(entries_.last()) < 1405 ASSERT(reinterpret_cast<char*>(entries_.last()) <
1541 (raw_entries_ + raw_entries_size_)); 1406 (raw_entries_ + raw_entries_size_));
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1713 HeapSnapshotsCollection::~HeapSnapshotsCollection() { 1578 HeapSnapshotsCollection::~HeapSnapshotsCollection() {
1714 delete token_enumerator_; 1579 delete token_enumerator_;
1715 snapshots_.Iterate(DeleteHeapSnapshot); 1580 snapshots_.Iterate(DeleteHeapSnapshot);
1716 } 1581 }
1717 1582
1718 1583
1719 HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(HeapSnapshot::Type type, 1584 HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(HeapSnapshot::Type type,
1720 const char* name, 1585 const char* name,
1721 unsigned uid) { 1586 unsigned uid) {
1722 is_tracking_objects_ = true; // Start watching for heap objects moves. 1587 is_tracking_objects_ = true; // Start watching for heap objects moves.
1723 HeapSnapshot* snapshot = new HeapSnapshot(this, type, name, uid); 1588 return new HeapSnapshot(this, type, name, uid);
1724 snapshots_.Add(snapshot); 1589 }
1725 HashMap::Entry* entry = 1590
1726 snapshots_uids_.Lookup(reinterpret_cast<void*>(snapshot->uid()), 1591
1727 static_cast<uint32_t>(snapshot->uid()), 1592 void HeapSnapshotsCollection::SnapshotGenerationFinished(
1728 true); 1593 HeapSnapshot* snapshot) {
1729 ASSERT(entry->value == NULL); 1594 ids_.SnapshotGenerationFinished();
1730 entry->value = snapshot; 1595 if (snapshot != NULL) {
1731 return snapshot; 1596 snapshots_.Add(snapshot);
1597 HashMap::Entry* entry =
1598 snapshots_uids_.Lookup(reinterpret_cast<void*>(snapshot->uid()),
1599 static_cast<uint32_t>(snapshot->uid()),
1600 true);
1601 ASSERT(entry->value == NULL);
1602 entry->value = snapshot;
1603 }
1732 } 1604 }
1733 1605
1734 1606
1735 HeapSnapshot* HeapSnapshotsCollection::GetSnapshot(unsigned uid) { 1607 HeapSnapshot* HeapSnapshotsCollection::GetSnapshot(unsigned uid) {
1736 HashMap::Entry* entry = snapshots_uids_.Lookup(reinterpret_cast<void*>(uid), 1608 HashMap::Entry* entry = snapshots_uids_.Lookup(reinterpret_cast<void*>(uid),
1737 static_cast<uint32_t>(uid), 1609 static_cast<uint32_t>(uid),
1738 false); 1610 false);
1739 return entry != NULL ? reinterpret_cast<HeapSnapshot*>(entry->value) : NULL; 1611 return entry != NULL ? reinterpret_cast<HeapSnapshot*>(entry->value) : NULL;
1740 } 1612 }
1741 1613
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 if (!obj->IsHeapObject()) return; 1701 if (!obj->IsHeapObject()) return;
1830 HeapObject* object = HeapObject::cast(obj); 1702 HeapObject* object = HeapObject::cast(obj);
1831 HashMap::Entry* cache_entry = 1703 HashMap::Entry* cache_entry =
1832 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); 1704 entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
1833 if (cache_entry->value == NULL) { 1705 if (cache_entry->value == NULL) {
1834 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder; 1706 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder;
1835 } 1707 }
1836 } 1708 }
1837 1709
1838 1710
1839 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot) 1711 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
1712 v8::ActivityControl* control)
1840 : snapshot_(snapshot), 1713 : snapshot_(snapshot),
1714 control_(control),
1841 collection_(snapshot->collection()), 1715 collection_(snapshot->collection()),
1842 filler_(NULL) { 1716 filler_(NULL) {
1843 } 1717 }
1844 1718
1845 class SnapshotCounter : public HeapSnapshotGenerator::SnapshotFillerInterface { 1719 class SnapshotCounter : public HeapSnapshotGenerator::SnapshotFillerInterface {
1846 public: 1720 public:
1847 explicit SnapshotCounter(HeapEntriesMap* entries) 1721 explicit SnapshotCounter(HeapEntriesMap* entries)
1848 : entries_(entries) { } 1722 : entries_(entries) { }
1849 HeapEntry* AddEntry(HeapObject* obj) { 1723 HeapEntry* AddEntry(HeapObject* obj) {
1850 entries_->Pair(obj, HeapEntriesMap::kHeapEntryPlaceholder); 1724 entries_->Pair(obj, HeapEntriesMap::kHeapEntryPlaceholder);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1987 : generator_(generator) { 1861 : generator_(generator) {
1988 } 1862 }
1989 void VisitPointers(Object** start, Object** end) { 1863 void VisitPointers(Object** start, Object** end) {
1990 for (Object** p = start; p < end; p++) generator_->SetGcRootsReference(*p); 1864 for (Object** p = start; p < end; p++) generator_->SetGcRootsReference(*p);
1991 } 1865 }
1992 private: 1866 private:
1993 HeapSnapshotGenerator* generator_; 1867 HeapSnapshotGenerator* generator_;
1994 }; 1868 };
1995 1869
1996 1870
1997 void HeapSnapshotGenerator::GenerateSnapshot() { 1871 bool HeapSnapshotGenerator::GenerateSnapshot() {
1998 AssertNoAllocation no_alloc; 1872 AssertNoAllocation no_alloc;
1999 1873
1874 SetProgressTotal(4); // 2 passes + dominators + sizes.
1875
2000 // Pass 1. Iterate heap contents to count entries and references. 1876 // Pass 1. Iterate heap contents to count entries and references.
2001 SnapshotCounter counter(&entries_); 1877 if (!CountEntriesAndReferences()) return false;
2002 filler_ = &counter;
2003 filler_->AddEntry(HeapSnapshot::kInternalRootObject);
2004 filler_->AddEntry(HeapSnapshot::kGcRootsObject);
2005 HeapIterator iterator(HeapIterator::kPreciseFiltering);
2006 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
2007 ExtractReferences(obj);
2008 }
2009 SetRootGcRootsReference();
2010 RootsReferencesExtractor extractor(this);
2011 HEAP->IterateRoots(&extractor, VISIT_ONLY_STRONG);
2012 1878
2013 // Allocate and fill entries in the snapshot, allocate references. 1879 // Allocate and fill entries in the snapshot, allocate references.
2014 snapshot_->AllocateEntries(entries_.entries_count(), 1880 snapshot_->AllocateEntries(entries_.entries_count(),
2015 entries_.total_children_count(), 1881 entries_.total_children_count(),
2016 entries_.total_retainers_count()); 1882 entries_.total_retainers_count());
2017 SnapshotAllocator allocator(snapshot_); 1883 SnapshotAllocator allocator(snapshot_);
2018 entries_.UpdateEntries(&allocator); 1884 entries_.UpdateEntries(&allocator);
2019 1885
2020 // Pass 2. Fill references. 1886 // Pass 2. Fill references.
2021 SnapshotFiller filler(snapshot_, &entries_); 1887 if (!FillReferences()) return false;
2022 filler_ = &filler;
2023 iterator.reset();
2024 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
2025 ExtractReferences(obj);
2026 }
2027 SetRootGcRootsReference();
2028 HEAP->IterateRoots(&extractor, VISIT_ONLY_STRONG);
2029 1888
2030 snapshot_->ApproximateRetainedSizes(); 1889 if (!SetEntriesDominators()) return false;
1890 if (!ApproximateRetainedSizes()) return false;
1891
1892 progress_counter_ = progress_total_;
1893 if (!ReportProgress(true)) return false;
1894 return true;
2031 } 1895 }
2032 1896
2033 1897
2034 HeapEntry* HeapSnapshotGenerator::GetEntry(Object* obj) { 1898 HeapEntry* HeapSnapshotGenerator::GetEntry(Object* obj) {
2035 if (!obj->IsHeapObject()) return NULL; 1899 if (!obj->IsHeapObject()) return NULL;
2036 HeapObject* object = HeapObject::cast(obj); 1900 HeapObject* object = HeapObject::cast(obj);
2037 HeapEntry* entry = entries_.Map(object); 1901 HeapEntry* entry = entries_.Map(object);
2038 // A new entry. 1902 // A new entry.
2039 if (entry == NULL) entry = filler_->AddEntry(object); 1903 if (entry == NULL) entry = filler_->AddEntry(object);
2040 return entry; 1904 return entry;
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2348 2212
2349 2213
2350 void HeapSnapshotGenerator::SetGcRootsReference(Object* child_obj) { 2214 void HeapSnapshotGenerator::SetGcRootsReference(Object* child_obj) {
2351 HeapEntry* child_entry = GetEntry(child_obj); 2215 HeapEntry* child_entry = GetEntry(child_obj);
2352 if (child_entry != NULL) { 2216 if (child_entry != NULL) {
2353 filler_->SetStrongRootReference(child_obj, child_entry); 2217 filler_->SetStrongRootReference(child_obj, child_entry);
2354 } 2218 }
2355 } 2219 }
2356 2220
2357 2221
2222 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
2223 if (control_ == NULL) return;
2224
2225 HeapIterator iterator(HeapIterator::kFilterUnreachable);
2226 int objects_count = 0;
2227 for (HeapObject* obj = iterator.next();
2228 obj != NULL;
2229 obj = iterator.next(), ++objects_count) {}
2230 progress_total_ = objects_count * iterations_count;
2231 progress_counter_ = 0;
2232 }
2233
2234
2235 bool HeapSnapshotGenerator::CountEntriesAndReferences() {
2236 SnapshotCounter counter(&entries_);
2237 filler_ = &counter;
2238 filler_->AddEntry(HeapSnapshot::kInternalRootObject);
2239 filler_->AddEntry(HeapSnapshot::kGcRootsObject);
2240 return IterateAndExtractReferences();
2241 }
2242
2243
2244 bool HeapSnapshotGenerator::FillReferences() {
2245 SnapshotFiller filler(snapshot_, &entries_);
2246 filler_ = &filler;
2247 return IterateAndExtractReferences();
2248 }
2249
2250
2251 void HeapSnapshotGenerator::FillReversePostorderIndexes(
2252 Vector<HeapEntry*>* entries) {
2253 snapshot_->ClearPaint();
2254 int current_entry = 0;
2255 List<HeapEntry*> nodes_to_visit;
2256 nodes_to_visit.Add(snapshot_->root());
2257 snapshot_->root()->paint_reachable();
2258 while (!nodes_to_visit.is_empty()) {
2259 HeapEntry* entry = nodes_to_visit.last();
2260 Vector<HeapGraphEdge> children = entry->children();
2261 bool has_new_edges = false;
2262 for (int i = 0; i < children.length(); ++i) {
2263 if (children[i].type() == HeapGraphEdge::kShortcut) continue;
2264 HeapEntry* child = children[i].to();
2265 if (!child->painted_reachable()) {
2266 nodes_to_visit.Add(child);
2267 child->paint_reachable();
2268 has_new_edges = true;
2269 }
2270 }
2271 if (!has_new_edges) {
2272 entry->set_ordered_index(current_entry);
2273 (*entries)[current_entry++] = entry;
2274 nodes_to_visit.RemoveLast();
2275 }
2276 }
2277 entries->Truncate(current_entry);
2278 }
2279
2280
2281 static int Intersect(int i1, int i2, const Vector<HeapEntry*>& dominators) {
2282 int finger1 = i1, finger2 = i2;
2283 while (finger1 != finger2) {
2284 while (finger1 < finger2) finger1 = dominators[finger1]->ordered_index();
2285 while (finger2 < finger1) finger2 = dominators[finger2]->ordered_index();
2286 }
2287 return finger1;
2288 }
2289
2290 // The algorithm is based on the article:
2291 // K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm"
2292 // Softw. Pract. Exper. 4 (2001), pp. 1–10.
2293 bool HeapSnapshotGenerator::BuildDominatorTree(
2294 const Vector<HeapEntry*>& entries,
2295 Vector<HeapEntry*>* dominators) {
2296 if (entries.length() == 0) return true;
2297 const int entries_length = entries.length(), root_index = entries_length - 1;
2298 for (int i = 0; i < root_index; ++i) (*dominators)[i] = NULL;
2299 (*dominators)[root_index] = entries[root_index];
2300 int changed = 1;
2301 const int base_progress_counter = progress_counter_;
2302 while (changed != 0) {
2303 changed = 0;
2304 for (int i = root_index - 1; i >= 0; --i) {
2305 HeapEntry* new_idom = NULL;
2306 Vector<HeapGraphEdge*> rets = entries[i]->retainers();
2307 int j = 0;
2308 for (; j < rets.length(); ++j) {
2309 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue;
2310 HeapEntry* ret = rets[j]->From();
2311 if (dominators->at(ret->ordered_index()) != NULL) {
2312 new_idom = ret;
2313 break;
2314 }
2315 }
2316 for (++j; j < rets.length(); ++j) {
2317 if (rets[j]->type() == HeapGraphEdge::kShortcut) continue;
2318 HeapEntry* ret = rets[j]->From();
2319 if (dominators->at(ret->ordered_index()) != NULL) {
2320 new_idom = entries[Intersect(ret->ordered_index(),
2321 new_idom->ordered_index(),
2322 *dominators)];
2323 }
2324 }
2325 if (new_idom != NULL && dominators->at(i) != new_idom) {
2326 (*dominators)[i] = new_idom;
2327 ++changed;
2328 }
2329 }
2330 int remaining = entries_length - changed;
2331 if (remaining < 0) remaining = 0;
2332 progress_counter_ = base_progress_counter + remaining;
2333 if (!ReportProgress(true)) return false;
2334 }
2335 return true;
2336 }
2337
2338
2339 bool HeapSnapshotGenerator::SetEntriesDominators() {
2340 // This array is used for maintaining reverse postorder of nodes.
2341 ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length());
2342 FillReversePostorderIndexes(&ordered_entries);
2343 ScopedVector<HeapEntry*> dominators(ordered_entries.length());
2344 if (!BuildDominatorTree(ordered_entries, &dominators)) return false;
2345 for (int i = 0; i < ordered_entries.length(); ++i) {
2346 ASSERT(dominators[i] != NULL);
2347 ordered_entries[i]->set_dominator(dominators[i]);
2348 }
2349 return true;
2350 }
2351
2352
2353 bool HeapSnapshotGenerator::ApproximateRetainedSizes() {
2354 // As for the dominators tree we only know parent nodes, not
2355 // children, to sum up total sizes we "bubble" node's self size
2356 // adding it to all of its parents.
2357 for (int i = 0; i < snapshot_->entries()->length(); ++i) {
2358 HeapEntry* entry = snapshot_->entries()->at(i);
2359 entry->set_retained_size(entry->self_size());
2360 }
2361 for (int i = 0;
2362 i < snapshot_->entries()->length();
2363 ++i, IncProgressCounter()) {
2364 HeapEntry* entry = snapshot_->entries()->at(i);
2365 int entry_size = entry->self_size();
2366 for (HeapEntry* dominator = entry->dominator();
2367 dominator != entry;
2368 entry = dominator, dominator = entry->dominator()) {
2369 dominator->add_retained_size(entry_size);
2370 }
2371 if (!ReportProgress()) return false;
2372 }
2373 return true;
2374 }
2375
2376
2377 bool HeapSnapshotGenerator::IterateAndExtractReferences() {
2378 HeapIterator iterator(HeapIterator::kFilterUnreachable);
2379 bool interrupted = false;
2380 // Heap iteration with filtering must be finished in any case.
2381 for (HeapObject* obj = iterator.next();
2382 obj != NULL;
2383 obj = iterator.next(), IncProgressCounter()) {
2384 if (!interrupted) {
2385 ExtractReferences(obj);
2386 if (!ReportProgress()) interrupted = true;
2387 }
2388 }
2389 if (interrupted) return false;
2390 SetRootGcRootsReference();
2391 RootsReferencesExtractor extractor(this);
2392 HEAP->IterateRoots(&extractor, VISIT_ONLY_STRONG);
2393 return ReportProgress();
2394 }
2395
2396
2358 void HeapSnapshotsDiff::CreateRoots(int additions_count, int deletions_count) { 2397 void HeapSnapshotsDiff::CreateRoots(int additions_count, int deletions_count) {
2359 raw_additions_root_ = 2398 raw_additions_root_ =
2360 NewArray<char>(HeapEntry::EntriesSize(1, additions_count, 0)); 2399 NewArray<char>(HeapEntry::EntriesSize(1, additions_count, 0));
2361 additions_root()->Init( 2400 additions_root()->Init(
2362 snapshot2_, HeapEntry::kHidden, "", 0, 0, additions_count, 0); 2401 snapshot2_, HeapEntry::kHidden, "", 0, 0, additions_count, 0);
2363 raw_deletions_root_ = 2402 raw_deletions_root_ =
2364 NewArray<char>(HeapEntry::EntriesSize(1, deletions_count, 0)); 2403 NewArray<char>(HeapEntry::EntriesSize(1, deletions_count, 0));
2365 deletions_root()->Init( 2404 deletions_root()->Init(
2366 snapshot1_, HeapEntry::kHidden, "", 0, 0, deletions_count, 0); 2405 snapshot1_, HeapEntry::kHidden, "", 0, 0, deletions_count, 0);
2367 } 2406 }
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2798 2837
2799 2838
2800 String* GetConstructorNameForHeapProfile(JSObject* object) { 2839 String* GetConstructorNameForHeapProfile(JSObject* object) {
2801 if (object->IsJSFunction()) return HEAP->closure_symbol(); 2840 if (object->IsJSFunction()) return HEAP->closure_symbol();
2802 return object->constructor_name(); 2841 return object->constructor_name();
2803 } 2842 }
2804 2843
2805 } } // namespace v8::internal 2844 } } // namespace v8::internal
2806 2845
2807 #endif // ENABLE_LOGGING_AND_PROFILING 2846 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698