Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifdef ENABLE_LOGGING_AND_PROFILING | 28 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 29 | 29 |
| 30 #include "v8.h" | 30 #include "v8.h" |
| 31 #include "global-handles.h" | 31 #include "global-handles.h" |
| 32 #include "heap-profiler.h" | |
| 32 #include "scopeinfo.h" | 33 #include "scopeinfo.h" |
| 33 #include "top.h" | 34 #include "top.h" |
| 34 #include "unicode.h" | 35 #include "unicode.h" |
| 35 #include "zone-inl.h" | 36 #include "zone-inl.h" |
| 36 | 37 |
| 37 #include "profile-generator-inl.h" | 38 #include "profile-generator-inl.h" |
| 38 | 39 |
| 39 namespace v8 { | 40 namespace v8 { |
| 40 namespace internal { | 41 namespace internal { |
| 41 | 42 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 } | 88 } |
| 88 } | 89 } |
| 89 } | 90 } |
| 90 | 91 |
| 91 | 92 |
| 92 StringsStorage::StringsStorage() | 93 StringsStorage::StringsStorage() |
| 93 : names_(StringsMatch) { | 94 : names_(StringsMatch) { |
| 94 } | 95 } |
| 95 | 96 |
| 96 | 97 |
| 97 static void DeleteIndexName(char** name_ptr) { | |
| 98 DeleteArray(*name_ptr); | |
| 99 } | |
| 100 | |
| 101 | |
| 102 StringsStorage::~StringsStorage() { | 98 StringsStorage::~StringsStorage() { |
| 103 for (HashMap::Entry* p = names_.Start(); | 99 for (HashMap::Entry* p = names_.Start(); |
| 104 p != NULL; | 100 p != NULL; |
| 105 p = names_.Next(p)) { | 101 p = names_.Next(p)) { |
| 106 DeleteArray(reinterpret_cast<const char*>(p->value)); | 102 DeleteArray(reinterpret_cast<const char*>(p->value)); |
| 107 } | 103 } |
| 108 index_names_.Iterate(DeleteIndexName); | 104 } |
| 105 | |
| 106 | |
| 107 const char* StringsStorage::PrintF(const char* format, ...) { | |
| 108 va_list args; | |
| 109 va_start(args, format); | |
| 110 const char* result = VPrintF(format, args); | |
| 111 va_end(args); | |
| 112 return result; | |
| 113 } | |
| 114 | |
| 115 | |
| 116 const char* StringsStorage::AddOrDisposeString(char* str, uint32_t hash) { | |
| 117 HashMap::Entry* cache_entry = names_.Lookup(str, hash, true); | |
| 118 if (cache_entry->value == NULL) { | |
| 119 // New entry added. | |
| 120 cache_entry->value = str; | |
| 121 } else { | |
| 122 DeleteArray(str); | |
| 123 } | |
| 124 return reinterpret_cast<const char*>(cache_entry->value); | |
| 125 } | |
| 126 | |
| 127 | |
| 128 const char* StringsStorage::VPrintF(const char* format, va_list args) { | |
| 129 Vector<char> str = Vector<char>::New(1024); | |
| 130 int len = OS::VSNPrintF(str, format, args); | |
| 131 if (len == -1) { | |
| 132 DeleteArray(str.start()); | |
| 133 return format; | |
| 134 } | |
| 135 uint32_t hash = HashSequentialString(str.start(), len); | |
| 136 return AddOrDisposeString(str.start(), hash); | |
| 109 } | 137 } |
| 110 | 138 |
| 111 | 139 |
| 112 const char* StringsStorage::GetName(String* name) { | 140 const char* StringsStorage::GetName(String* name) { |
| 113 if (name->IsString()) { | 141 if (name->IsString()) { |
| 114 char* c_name = | 142 return AddOrDisposeString( |
| 115 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach(); | 143 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach(), |
| 116 HashMap::Entry* cache_entry = names_.Lookup(c_name, name->Hash(), true); | 144 name->Hash()); |
| 117 if (cache_entry->value == NULL) { | |
| 118 // New entry added. | |
| 119 cache_entry->value = c_name; | |
| 120 } else { | |
| 121 DeleteArray(c_name); | |
| 122 } | |
| 123 return reinterpret_cast<const char*>(cache_entry->value); | |
| 124 } | 145 } |
| 125 return ""; | 146 return ""; |
| 126 } | 147 } |
| 127 | 148 |
| 128 | 149 |
| 129 const char* StringsStorage::GetName(int index) { | 150 const char* StringsStorage::GetName(int index) { |
| 130 ASSERT(index >= 0); | 151 return PrintF("%d", index); |
| 131 if (index_names_.length() <= index) { | |
| 132 index_names_.AddBlock( | |
| 133 NULL, index - index_names_.length() + 1); | |
| 134 } | |
| 135 if (index_names_[index] == NULL) { | |
| 136 const int kMaximumNameLength = 32; | |
| 137 char* name = NewArray<char>(kMaximumNameLength); | |
| 138 OS::SNPrintF(Vector<char>(name, kMaximumNameLength), "%d", index); | |
| 139 index_names_[index] = name; | |
| 140 } | |
| 141 return index_names_[index]; | |
| 142 } | 152 } |
| 143 | 153 |
| 144 | 154 |
| 145 const char* CodeEntry::kEmptyNamePrefix = ""; | 155 const char* CodeEntry::kEmptyNamePrefix = ""; |
| 146 | 156 |
| 147 | 157 |
| 148 void CodeEntry::CopyData(const CodeEntry& source) { | 158 void CodeEntry::CopyData(const CodeEntry& source) { |
| 149 tag_ = source.tag_; | 159 tag_ = source.tag_; |
| 150 name_prefix_ = source.name_prefix_; | 160 name_prefix_ = source.name_prefix_; |
| 151 name_ = source.name_; | 161 name_ = source.name_; |
| (...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1002 const char* HeapEntry::TypeAsString() { | 1012 const char* HeapEntry::TypeAsString() { |
| 1003 switch (type()) { | 1013 switch (type()) { |
| 1004 case kHidden: return "/hidden/"; | 1014 case kHidden: return "/hidden/"; |
| 1005 case kObject: return "/object/"; | 1015 case kObject: return "/object/"; |
| 1006 case kClosure: return "/closure/"; | 1016 case kClosure: return "/closure/"; |
| 1007 case kString: return "/string/"; | 1017 case kString: return "/string/"; |
| 1008 case kCode: return "/code/"; | 1018 case kCode: return "/code/"; |
| 1009 case kArray: return "/array/"; | 1019 case kArray: return "/array/"; |
| 1010 case kRegExp: return "/regexp/"; | 1020 case kRegExp: return "/regexp/"; |
| 1011 case kHeapNumber: return "/number/"; | 1021 case kHeapNumber: return "/number/"; |
| 1022 case kNative: return "/native/"; | |
| 1012 default: return "???"; | 1023 default: return "???"; |
| 1013 } | 1024 } |
| 1014 } | 1025 } |
| 1015 | 1026 |
| 1016 | 1027 |
| 1017 int HeapEntry::EntriesSize(int entries_count, | 1028 int HeapEntry::EntriesSize(int entries_count, |
| 1018 int children_count, | 1029 int children_count, |
| 1019 int retainers_count) { | 1030 int retainers_count) { |
| 1020 return sizeof(HeapEntry) * entries_count // NOLINT | 1031 return sizeof(HeapEntry) * entries_count // NOLINT |
| 1021 + sizeof(HeapGraphEdge) * children_count // NOLINT | 1032 + sizeof(HeapGraphEdge) * children_count // NOLINT |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1198 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, | 1209 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, |
| 1199 HeapSnapshot::Type type, | 1210 HeapSnapshot::Type type, |
| 1200 const char* title, | 1211 const char* title, |
| 1201 unsigned uid) | 1212 unsigned uid) |
| 1202 : collection_(collection), | 1213 : collection_(collection), |
| 1203 type_(type), | 1214 type_(type), |
| 1204 title_(title), | 1215 title_(title), |
| 1205 uid_(uid), | 1216 uid_(uid), |
| 1206 root_entry_(NULL), | 1217 root_entry_(NULL), |
| 1207 gc_roots_entry_(NULL), | 1218 gc_roots_entry_(NULL), |
| 1219 dom_subtrees_root_entry_(NULL), | |
| 1208 raw_entries_(NULL), | 1220 raw_entries_(NULL), |
| 1209 entries_sorted_(false), | 1221 entries_sorted_(false), |
| 1210 retaining_paths_(HeapEntry::Match) { | 1222 retaining_paths_(HeapEntry::Match) { |
| 1211 STATIC_ASSERT( | 1223 STATIC_ASSERT( |
| 1212 sizeof(HeapGraphEdge) == | 1224 sizeof(HeapGraphEdge) == |
| 1213 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapGraphEdgeSize); // NOL INT | 1225 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapGraphEdgeSize); // NOL INT |
| 1214 STATIC_ASSERT( | 1226 STATIC_ASSERT( |
| 1215 sizeof(HeapEntry) == | 1227 sizeof(HeapEntry) == |
| 1216 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapEntrySize); // NOLINT | 1228 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapEntrySize); // NOLINT |
| 1217 } | 1229 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1272 ASSERT(gc_roots_entry_ == NULL); | 1284 ASSERT(gc_roots_entry_ == NULL); |
| 1273 return (gc_roots_entry_ = AddEntry(HeapEntry::kObject, | 1285 return (gc_roots_entry_ = AddEntry(HeapEntry::kObject, |
| 1274 "(GC roots)", | 1286 "(GC roots)", |
| 1275 HeapObjectsMap::kGcRootsObjectId, | 1287 HeapObjectsMap::kGcRootsObjectId, |
| 1276 0, | 1288 0, |
| 1277 children_count, | 1289 children_count, |
| 1278 retainers_count)); | 1290 retainers_count)); |
| 1279 } | 1291 } |
| 1280 | 1292 |
| 1281 | 1293 |
| 1294 HeapEntry* HeapSnapshot::AddNativesRootEntry(int children_count, | |
| 1295 int retainers_count) { | |
| 1296 ASSERT(dom_subtrees_root_entry_ == NULL); | |
| 1297 return (dom_subtrees_root_entry_ = AddEntry( | |
| 1298 HeapEntry::kObject, | |
| 1299 "(Native objects)", | |
| 1300 HeapObjectsMap::kNativesRootObjectId, | |
| 1301 0, | |
| 1302 children_count, | |
| 1303 retainers_count)); | |
| 1304 } | |
| 1305 | |
| 1306 | |
| 1282 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, | 1307 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, |
| 1283 const char* name, | 1308 const char* name, |
| 1284 uint64_t id, | 1309 uint64_t id, |
| 1285 int size, | 1310 int size, |
| 1286 int children_count, | 1311 int children_count, |
| 1287 int retainers_count) { | 1312 int retainers_count) { |
| 1288 HeapEntry* entry = GetNextEntryToInit(); | 1313 HeapEntry* entry = GetNextEntryToInit(); |
| 1289 entry->Init(this, type, name, id, size, children_count, retainers_count); | 1314 entry->Init(this, type, name, id, size, children_count, retainers_count); |
| 1290 return entry; | 1315 return entry; |
| 1291 } | 1316 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1365 } | 1390 } |
| 1366 return &entries_; | 1391 return &entries_; |
| 1367 } | 1392 } |
| 1368 | 1393 |
| 1369 | 1394 |
| 1370 void HeapSnapshot::Print(int max_depth) { | 1395 void HeapSnapshot::Print(int max_depth) { |
| 1371 root()->Print(max_depth, 0); | 1396 root()->Print(max_depth, 0); |
| 1372 } | 1397 } |
| 1373 | 1398 |
| 1374 | 1399 |
| 1375 const uint64_t HeapObjectsMap::kInternalRootObjectId = 0; | 1400 const uint64_t HeapObjectsMap::kInternalRootObjectId = 1; |
|
Vitaly Repeshko
2011/03/09 14:15:49
Document why these have to be odd.
mnaganov (inactive)
2011/03/09 15:26:32
Done.
| |
| 1376 const uint64_t HeapObjectsMap::kGcRootsObjectId = 1; | 1401 const uint64_t HeapObjectsMap::kGcRootsObjectId = 3; |
| 1402 const uint64_t HeapObjectsMap::kNativesRootObjectId = 5; | |
| 1377 // Increase kFirstAvailableObjectId if new 'special' objects appear. | 1403 // Increase kFirstAvailableObjectId if new 'special' objects appear. |
| 1378 const uint64_t HeapObjectsMap::kFirstAvailableObjectId = 2; | 1404 const uint64_t HeapObjectsMap::kFirstAvailableObjectId = 7; |
| 1379 | 1405 |
| 1380 HeapObjectsMap::HeapObjectsMap() | 1406 HeapObjectsMap::HeapObjectsMap() |
| 1381 : initial_fill_mode_(true), | 1407 : initial_fill_mode_(true), |
| 1382 next_id_(kFirstAvailableObjectId), | 1408 next_id_(kFirstAvailableObjectId), |
| 1383 entries_map_(AddressesMatch), | 1409 entries_map_(AddressesMatch), |
| 1384 entries_(new List<EntryInfo>()) { } | 1410 entries_(new List<EntryInfo>()) { } |
| 1385 | 1411 |
| 1386 | 1412 |
| 1387 HeapObjectsMap::~HeapObjectsMap() { | 1413 HeapObjectsMap::~HeapObjectsMap() { |
| 1388 delete entries_; | 1414 delete entries_; |
| 1389 } | 1415 } |
| 1390 | 1416 |
| 1391 | 1417 |
| 1392 void HeapObjectsMap::SnapshotGenerationFinished() { | 1418 void HeapObjectsMap::SnapshotGenerationFinished() { |
| 1393 initial_fill_mode_ = false; | 1419 initial_fill_mode_ = false; |
| 1394 RemoveDeadEntries(); | 1420 RemoveDeadEntries(); |
| 1395 } | 1421 } |
| 1396 | 1422 |
| 1397 | 1423 |
| 1398 uint64_t HeapObjectsMap::FindObject(Address addr) { | 1424 uint64_t HeapObjectsMap::FindObject(Address addr) { |
| 1399 if (!initial_fill_mode_) { | 1425 if (!initial_fill_mode_) { |
| 1400 uint64_t existing = FindEntry(addr); | 1426 uint64_t existing = FindEntry(addr); |
| 1401 if (existing != 0) return existing; | 1427 if (existing != 0) return existing; |
| 1402 } | 1428 } |
| 1403 uint64_t id = next_id_++; | 1429 uint64_t id = next_id_; |
| 1430 next_id_ += 2; | |
| 1404 AddEntry(addr, id); | 1431 AddEntry(addr, id); |
| 1405 return id; | 1432 return id; |
| 1406 } | 1433 } |
| 1407 | 1434 |
| 1408 | 1435 |
| 1409 void HeapObjectsMap::MoveObject(Address from, Address to) { | 1436 void HeapObjectsMap::MoveObject(Address from, Address to) { |
| 1410 if (from == to) return; | 1437 if (from == to) return; |
| 1411 HashMap::Entry* entry = entries_map_.Lookup(from, AddressHash(from), false); | 1438 HashMap::Entry* entry = entries_map_.Lookup(from, AddressHash(from), false); |
| 1412 if (entry != NULL) { | 1439 if (entry != NULL) { |
| 1413 void* value = entry->value; | 1440 void* value = entry->value; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1461 for (int i = 0; i < dead_entries.length(); ++i) { | 1488 for (int i = 0; i < dead_entries.length(); ++i) { |
| 1462 void* raw_entry = dead_entries[i]; | 1489 void* raw_entry = dead_entries[i]; |
| 1463 entries_map_.Remove( | 1490 entries_map_.Remove( |
| 1464 raw_entry, AddressHash(reinterpret_cast<Address>(raw_entry))); | 1491 raw_entry, AddressHash(reinterpret_cast<Address>(raw_entry))); |
| 1465 } | 1492 } |
| 1466 delete entries_; | 1493 delete entries_; |
| 1467 entries_ = new_entries; | 1494 entries_ = new_entries; |
| 1468 } | 1495 } |
| 1469 | 1496 |
| 1470 | 1497 |
| 1498 uint64_t HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) { | |
| 1499 uint64_t id = static_cast<uint64_t>(info->GetHash()); | |
| 1500 const char* label = info->GetLabel(); | |
| 1501 id ^= HashSequentialString(label, strlen(label)); | |
| 1502 intptr_t element_count = info->GetElementCount(); | |
| 1503 if (element_count != -1) | |
| 1504 id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count)); | |
| 1505 return id << 1; | |
| 1506 } | |
| 1507 | |
| 1508 | |
| 1471 HeapSnapshotsCollection::HeapSnapshotsCollection() | 1509 HeapSnapshotsCollection::HeapSnapshotsCollection() |
| 1472 : is_tracking_objects_(false), | 1510 : is_tracking_objects_(false), |
| 1473 snapshots_uids_(HeapSnapshotsMatch), | 1511 snapshots_uids_(HeapSnapshotsMatch), |
| 1474 token_enumerator_(new TokenEnumerator()) { | 1512 token_enumerator_(new TokenEnumerator()) { |
| 1475 } | 1513 } |
| 1476 | 1514 |
| 1477 | 1515 |
| 1478 static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) { | 1516 static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) { |
| 1479 delete *snapshot_ptr; | 1517 delete *snapshot_ptr; |
| 1480 } | 1518 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1510 | 1548 |
| 1511 | 1549 |
| 1512 HeapSnapshot* HeapSnapshotsCollection::GetSnapshot(unsigned uid) { | 1550 HeapSnapshot* HeapSnapshotsCollection::GetSnapshot(unsigned uid) { |
| 1513 HashMap::Entry* entry = snapshots_uids_.Lookup(reinterpret_cast<void*>(uid), | 1551 HashMap::Entry* entry = snapshots_uids_.Lookup(reinterpret_cast<void*>(uid), |
| 1514 static_cast<uint32_t>(uid), | 1552 static_cast<uint32_t>(uid), |
| 1515 false); | 1553 false); |
| 1516 return entry != NULL ? reinterpret_cast<HeapSnapshot*>(entry->value) : NULL; | 1554 return entry != NULL ? reinterpret_cast<HeapSnapshot*>(entry->value) : NULL; |
| 1517 } | 1555 } |
| 1518 | 1556 |
| 1519 | 1557 |
| 1558 const char* HeapSnapshotsCollection::PrintF(const char* format, ...) { | |
| 1559 va_list args; | |
| 1560 va_start(args, format); | |
| 1561 const char* result = names_.VPrintF(format, args); | |
| 1562 va_end(args); | |
| 1563 return result; | |
| 1564 } | |
| 1565 | |
| 1566 | |
| 1520 HeapSnapshotsDiff* HeapSnapshotsCollection::CompareSnapshots( | 1567 HeapSnapshotsDiff* HeapSnapshotsCollection::CompareSnapshots( |
| 1521 HeapSnapshot* snapshot1, | 1568 HeapSnapshot* snapshot1, |
| 1522 HeapSnapshot* snapshot2) { | 1569 HeapSnapshot* snapshot2) { |
| 1523 return comparator_.Compare(snapshot1, snapshot2); | 1570 return comparator_.Compare(snapshot1, snapshot2); |
| 1524 } | 1571 } |
| 1525 | 1572 |
| 1526 | 1573 |
| 1527 HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder = | 1574 HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder = |
| 1528 reinterpret_cast<HeapEntry*>(1); | 1575 reinterpret_cast<HeapEntry*>(1); |
| 1529 | 1576 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1544 | 1591 |
| 1545 void HeapEntriesMap::AllocateEntries() { | 1592 void HeapEntriesMap::AllocateEntries() { |
| 1546 for (HashMap::Entry* p = entries_.Start(); | 1593 for (HashMap::Entry* p = entries_.Start(); |
| 1547 p != NULL; | 1594 p != NULL; |
| 1548 p = entries_.Next(p)) { | 1595 p = entries_.Next(p)) { |
| 1549 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value); | 1596 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value); |
| 1550 entry_info->entry = entry_info->allocator->AllocateEntry( | 1597 entry_info->entry = entry_info->allocator->AllocateEntry( |
| 1551 p->key, | 1598 p->key, |
| 1552 entry_info->children_count, | 1599 entry_info->children_count, |
| 1553 entry_info->retainers_count); | 1600 entry_info->retainers_count); |
| 1601 ASSERT(entry_info->entry != NULL); | |
| 1602 ASSERT(entry_info->entry != kHeapEntryPlaceholder); | |
| 1554 entry_info->children_count = 0; | 1603 entry_info->children_count = 0; |
| 1555 entry_info->retainers_count = 0; | 1604 entry_info->retainers_count = 0; |
| 1556 } | 1605 } |
| 1557 } | 1606 } |
| 1558 | 1607 |
| 1559 | 1608 |
| 1560 HeapEntry* HeapEntriesMap::Map(HeapThing thing) { | 1609 HeapEntry* HeapEntriesMap::Map(HeapThing thing) { |
| 1561 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false); | 1610 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false); |
| 1562 if (cache_entry != NULL) { | 1611 if (cache_entry != NULL) { |
| 1563 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value); | 1612 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1625 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); | 1674 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); |
| 1626 if (cache_entry->value == NULL) { | 1675 if (cache_entry->value == NULL) { |
| 1627 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder; | 1676 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder; |
| 1628 } | 1677 } |
| 1629 } | 1678 } |
| 1630 | 1679 |
| 1631 | 1680 |
| 1632 HeapObject *const V8HeapExplorer::kInternalRootObject = | 1681 HeapObject *const V8HeapExplorer::kInternalRootObject = |
| 1633 reinterpret_cast<HeapObject*>(1); | 1682 reinterpret_cast<HeapObject*>(1); |
| 1634 HeapObject *const V8HeapExplorer::kGcRootsObject = | 1683 HeapObject *const V8HeapExplorer::kGcRootsObject = |
| 1635 reinterpret_cast<HeapObject*>(2); | 1684 reinterpret_cast<HeapObject*>(3); |
|
Vitaly Repeshko
2011/03/09 14:15:49
Shouldn't the constants defined above be reused he
mnaganov (inactive)
2011/03/09 15:26:32
Done.
| |
| 1636 | 1685 |
| 1637 | 1686 |
| 1638 V8HeapExplorer::V8HeapExplorer( | 1687 V8HeapExplorer::V8HeapExplorer( |
| 1639 HeapSnapshot* snapshot, | 1688 HeapSnapshot* snapshot, |
| 1640 SnapshottingProgressReportingInterface* progress) | 1689 SnapshottingProgressReportingInterface* progress) |
| 1641 : snapshot_(snapshot), | 1690 : snapshot_(snapshot), |
| 1642 collection_(snapshot_->collection()), | 1691 collection_(snapshot_->collection()), |
| 1643 progress_(progress), | 1692 progress_(progress), |
| 1644 filler_(NULL) { | 1693 filler_(NULL) { |
| 1645 } | 1694 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1742 return snapshot_->AddEntry(type, | 1791 return snapshot_->AddEntry(type, |
| 1743 name, | 1792 name, |
| 1744 collection_->GetObjectId(object->address()), | 1793 collection_->GetObjectId(object->address()), |
| 1745 object->Size(), | 1794 object->Size(), |
| 1746 children_count, | 1795 children_count, |
| 1747 retainers_count); | 1796 retainers_count); |
| 1748 } | 1797 } |
| 1749 | 1798 |
| 1750 | 1799 |
| 1751 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { | 1800 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { |
| 1752 filler->AddEntry(kInternalRootObject); | 1801 filler->AddEntry(kInternalRootObject, this); |
| 1753 filler->AddEntry(kGcRootsObject); | 1802 filler->AddEntry(kGcRootsObject, this); |
| 1754 } | 1803 } |
| 1755 | 1804 |
| 1756 | 1805 |
| 1757 int V8HeapExplorer::EstimateObjectsCount() { | 1806 int V8HeapExplorer::EstimateObjectsCount() { |
| 1758 HeapIterator iterator(HeapIterator::kFilterUnreachable); | 1807 HeapIterator iterator(HeapIterator::kFilterUnreachable); |
| 1759 int objects_count = 0; | 1808 int objects_count = 0; |
| 1760 for (HeapObject* obj = iterator.next(); | 1809 for (HeapObject* obj = iterator.next(); |
| 1761 obj != NULL; | 1810 obj != NULL; |
| 1762 obj = iterator.next(), ++objects_count) {} | 1811 obj = iterator.next(), ++objects_count) {} |
| 1763 return objects_count; | 1812 return objects_count; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1933 int length = js_obj->GetInternalFieldCount(); | 1982 int length = js_obj->GetInternalFieldCount(); |
| 1934 for (int i = 0; i < length; ++i) { | 1983 for (int i = 0; i < length; ++i) { |
| 1935 Object* o = js_obj->GetInternalField(i); | 1984 Object* o = js_obj->GetInternalField(i); |
| 1936 SetInternalReference(js_obj, entry, i, o); | 1985 SetInternalReference(js_obj, entry, i, o); |
| 1937 } | 1986 } |
| 1938 } | 1987 } |
| 1939 | 1988 |
| 1940 | 1989 |
| 1941 HeapEntry* V8HeapExplorer::GetEntry(Object* obj) { | 1990 HeapEntry* V8HeapExplorer::GetEntry(Object* obj) { |
| 1942 if (!obj->IsHeapObject()) return NULL; | 1991 if (!obj->IsHeapObject()) return NULL; |
| 1943 return filler_->FindOrAddEntry(obj); | 1992 return filler_->FindOrAddEntry(obj, this); |
| 1944 } | 1993 } |
| 1945 | 1994 |
| 1946 | 1995 |
| 1947 class RootsReferencesExtractor : public ObjectVisitor { | 1996 class RootsReferencesExtractor : public ObjectVisitor { |
| 1948 public: | 1997 public: |
| 1949 explicit RootsReferencesExtractor(V8HeapExplorer* explorer) | 1998 explicit RootsReferencesExtractor(V8HeapExplorer* explorer) |
| 1950 : explorer_(explorer) { | 1999 : explorer_(explorer) { |
| 1951 } | 2000 } |
| 1952 void VisitPointers(Object** start, Object** end) { | 2001 void VisitPointers(Object** start, Object** end) { |
| 1953 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p); | 2002 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2125 HeapEntry* child_entry = GetEntry(child_obj); | 2174 HeapEntry* child_entry = GetEntry(child_obj); |
| 2126 if (child_entry != NULL) { | 2175 if (child_entry != NULL) { |
| 2127 filler_->SetIndexedAutoIndexReference( | 2176 filler_->SetIndexedAutoIndexReference( |
| 2128 HeapGraphEdge::kElement, | 2177 HeapGraphEdge::kElement, |
| 2129 kGcRootsObject, snapshot_->gc_roots(), | 2178 kGcRootsObject, snapshot_->gc_roots(), |
| 2130 child_obj, child_entry); | 2179 child_obj, child_entry); |
| 2131 } | 2180 } |
| 2132 } | 2181 } |
| 2133 | 2182 |
| 2134 | 2183 |
| 2184 class GlobalHandlesExtractor : public ObjectVisitor { | |
| 2185 public: | |
| 2186 explicit GlobalHandlesExtractor(NativeObjectsExplorer* explorer) | |
| 2187 : explorer_(explorer) {} | |
| 2188 virtual ~GlobalHandlesExtractor() {} | |
| 2189 virtual void VisitPointers(Object** start, Object** end) { | |
| 2190 UNREACHABLE(); | |
| 2191 } | |
| 2192 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) { | |
| 2193 explorer_->VisitSubtreeWrapper(p, class_id); | |
| 2194 } | |
| 2195 private: | |
| 2196 NativeObjectsExplorer* explorer_; | |
| 2197 }; | |
| 2198 | |
| 2199 HeapThing const NativeObjectsExplorer::kNativesRootObject = | |
| 2200 reinterpret_cast<HeapThing>(5); | |
|
Vitaly Repeshko
2011/03/09 14:15:49
Same as above.
mnaganov (inactive)
2011/03/09 15:26:32
Done.
| |
| 2201 | |
| 2202 | |
| 2203 NativeObjectsExplorer::NativeObjectsExplorer( | |
| 2204 HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress) | |
| 2205 : snapshot_(snapshot), | |
| 2206 collection_(snapshot_->collection()), | |
| 2207 progress_(progress), | |
| 2208 embedder_queried_(false), | |
| 2209 objects_by_info_(RetainedInfosMatch), | |
| 2210 filler_(NULL) { | |
| 2211 } | |
| 2212 | |
| 2213 | |
| 2214 NativeObjectsExplorer::~NativeObjectsExplorer() { | |
| 2215 for (HashMap::Entry* p = objects_by_info_.Start(); | |
| 2216 p != NULL; | |
| 2217 p = objects_by_info_.Next(p)) { | |
| 2218 v8::RetainedObjectInfo* info = | |
| 2219 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | |
| 2220 info->Dispose(); | |
| 2221 List<HeapObject*>* objects = | |
| 2222 reinterpret_cast<List<HeapObject*>* >(p->value); | |
| 2223 delete objects; | |
| 2224 } | |
| 2225 } | |
| 2226 | |
| 2227 | |
| 2228 HeapEntry* NativeObjectsExplorer::AllocateEntry( | |
| 2229 HeapThing ptr, int children_count, int retainers_count) { | |
| 2230 if (ptr == kNativesRootObject) { | |
| 2231 return snapshot_->AddNativesRootEntry(children_count, retainers_count); | |
| 2232 } else { | |
| 2233 v8::RetainedObjectInfo* info = | |
| 2234 reinterpret_cast<v8::RetainedObjectInfo*>(ptr); | |
| 2235 intptr_t elements = info->GetElementCount(); | |
| 2236 intptr_t size = info->GetSizeInBytes(); | |
| 2237 return snapshot_->AddEntry( | |
| 2238 HeapEntry::kNative, | |
| 2239 elements != -1 ? | |
| 2240 collection_->PrintF("%s / %" V8_PTR_PREFIX "d entries", | |
| 2241 info->GetLabel(), | |
| 2242 info->GetElementCount()) : | |
| 2243 info->GetLabel(), | |
|
Vitaly Repeshko
2011/03/09 14:15:49
What if the returned label's lifetime is tied to t
mnaganov (inactive)
2011/03/09 15:26:32
Fixed.
| |
| 2244 HeapObjectsMap::GenerateId(info), | |
| 2245 size != -1 ? static_cast<int>(size) : 0, | |
| 2246 children_count, | |
| 2247 retainers_count); | |
| 2248 } | |
| 2249 } | |
| 2250 | |
| 2251 | |
| 2252 void NativeObjectsExplorer::AddRootEntries(SnapshotFillerInterface* filler) { | |
| 2253 if (EstimateObjectsCount() <= 0) return; | |
| 2254 filler->AddEntry(kNativesRootObject, this); | |
| 2255 } | |
| 2256 | |
| 2257 | |
| 2258 int NativeObjectsExplorer::EstimateObjectsCount() { | |
| 2259 FillRetainedObjects(); | |
| 2260 return objects_by_info_.occupancy(); | |
| 2261 } | |
| 2262 | |
| 2263 | |
| 2264 void NativeObjectsExplorer::FillRetainedObjects() { | |
| 2265 if (embedder_queried_) return; | |
| 2266 // Record objects that are joined into ObjectGroups. | |
| 2267 Heap::call_global_gc_prologue_callback(); | |
| 2268 List<ObjectGroup*>* groups = GlobalHandles::ObjectGroups(); | |
| 2269 for (int i = 0; i < groups->length(); ++i) { | |
| 2270 ObjectGroup* group = groups->at(i); | |
| 2271 if (group->info_ == NULL) continue; | |
| 2272 List<HeapObject*>* list = GetListMaybeDisposeInfo(group->info_); | |
| 2273 for (int j = 0; j < group->objects_.length(); ++j) { | |
| 2274 HeapObject* obj = HeapObject::cast(*group->objects_[j]); | |
| 2275 list->Add(obj); | |
| 2276 in_groups_.Insert(obj); | |
| 2277 } | |
| 2278 group->info_ = NULL; // Acquire info object ownership. | |
| 2279 } | |
| 2280 GlobalHandles::RemoveObjectGroups(); | |
| 2281 Heap::call_global_gc_epilogue_callback(); | |
| 2282 // Record objects that are not in ObjectGroups, but have class ID. | |
| 2283 GlobalHandlesExtractor extractor(this); | |
| 2284 GlobalHandles::IterateAllRootsWithClassIds(&extractor); | |
| 2285 embedder_queried_ = true; | |
| 2286 } | |
| 2287 | |
| 2288 | |
| 2289 List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo( | |
| 2290 v8::RetainedObjectInfo* info) { | |
| 2291 HashMap::Entry* entry = | |
| 2292 objects_by_info_.Lookup(info, InfoHash(info), true); | |
| 2293 if (entry->value != NULL) { | |
| 2294 info->Dispose(); | |
| 2295 } else { | |
| 2296 entry->value = new List<HeapObject*>(4); | |
| 2297 } | |
| 2298 return reinterpret_cast<List<HeapObject*>* >(entry->value); | |
| 2299 } | |
| 2300 | |
| 2301 | |
| 2302 bool NativeObjectsExplorer::IterateAndExtractReferences( | |
| 2303 SnapshotFillerInterface* filler) { | |
| 2304 if (EstimateObjectsCount() <= 0) return true; | |
| 2305 filler_ = filler; | |
| 2306 FillRetainedObjects(); | |
| 2307 for (HashMap::Entry* p = objects_by_info_.Start(); | |
| 2308 p != NULL; | |
| 2309 p = objects_by_info_.Next(p)) { | |
| 2310 v8::RetainedObjectInfo* info = | |
| 2311 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | |
| 2312 SetNativeRootReference(info); | |
| 2313 List<HeapObject*>* objects = | |
| 2314 reinterpret_cast<List<HeapObject*>* >(p->value); | |
| 2315 for (int i = 0; i < objects->length(); ++i) { | |
| 2316 SetWrapperNativeReferences(objects->at(i), info); | |
| 2317 } | |
| 2318 } | |
| 2319 SetRootNativesRootReference(); | |
| 2320 filler_ = NULL; | |
| 2321 return true; | |
| 2322 } | |
| 2323 | |
| 2324 | |
| 2325 void NativeObjectsExplorer::SetNativeRootReference( | |
| 2326 v8::RetainedObjectInfo* info) { | |
| 2327 HeapEntry* child_entry = filler_->FindOrAddEntry(info, this); | |
| 2328 ASSERT(child_entry != NULL); | |
| 2329 filler_->SetIndexedAutoIndexReference( | |
| 2330 HeapGraphEdge::kElement, | |
| 2331 kNativesRootObject, snapshot_->dom_subtrees_root(), | |
| 2332 info, child_entry); | |
| 2333 } | |
| 2334 | |
| 2335 | |
| 2336 void NativeObjectsExplorer::SetWrapperNativeReferences( | |
| 2337 HeapObject* wrapper, v8::RetainedObjectInfo* info) { | |
| 2338 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper); | |
| 2339 ASSERT(wrapper_entry != NULL); | |
| 2340 HeapEntry* info_entry = filler_->FindOrAddEntry(info, this); | |
| 2341 ASSERT(info_entry != NULL); | |
| 2342 filler_->SetNamedReference(HeapGraphEdge::kInternal, | |
| 2343 wrapper, wrapper_entry, | |
| 2344 "Native", | |
| 2345 info, info_entry); | |
| 2346 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, | |
| 2347 info, info_entry, | |
| 2348 wrapper, wrapper_entry); | |
| 2349 } | |
| 2350 | |
| 2351 | |
| 2352 void NativeObjectsExplorer::SetRootNativesRootReference() { | |
| 2353 filler_->SetIndexedAutoIndexReference( | |
| 2354 HeapGraphEdge::kElement, | |
| 2355 V8HeapExplorer::kInternalRootObject, snapshot_->root(), | |
| 2356 kNativesRootObject, snapshot_->dom_subtrees_root()); | |
| 2357 } | |
| 2358 | |
| 2359 | |
| 2360 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { | |
| 2361 if (in_groups_.Contains(*p)) return; | |
| 2362 v8::RetainedObjectInfo* info = | |
| 2363 HeapProfiler::ExecuteWrapperClassCallback(class_id, p); | |
| 2364 if (info == NULL) return; | |
| 2365 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); | |
| 2366 } | |
| 2367 | |
| 2368 | |
| 2135 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot, | 2369 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot, |
| 2136 v8::ActivityControl* control) | 2370 v8::ActivityControl* control) |
| 2137 : snapshot_(snapshot), | 2371 : snapshot_(snapshot), |
| 2138 control_(control), | 2372 control_(control), |
| 2139 v8_heap_explorer_(snapshot_, this) { | 2373 v8_heap_explorer_(snapshot_, this), |
| 2374 dom_explorer_(snapshot_, this) { | |
| 2140 } | 2375 } |
| 2141 | 2376 |
| 2142 | 2377 |
| 2143 class SnapshotCounter : public SnapshotFillerInterface { | 2378 class SnapshotCounter : public SnapshotFillerInterface { |
| 2144 public: | 2379 public: |
| 2145 SnapshotCounter(HeapEntriesAllocator* allocator, HeapEntriesMap* entries) | 2380 explicit SnapshotCounter(HeapEntriesMap* entries) : entries_(entries) { } |
| 2146 : allocator_(allocator), entries_(entries) { } | 2381 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { |
| 2147 HeapEntry* AddEntry(HeapThing ptr) { | 2382 entries_->Pair(ptr, allocator, HeapEntriesMap::kHeapEntryPlaceholder); |
| 2148 entries_->Pair(ptr, allocator_, HeapEntriesMap::kHeapEntryPlaceholder); | |
| 2149 return HeapEntriesMap::kHeapEntryPlaceholder; | 2383 return HeapEntriesMap::kHeapEntryPlaceholder; |
| 2150 } | 2384 } |
| 2151 HeapEntry* FindOrAddEntry(HeapThing ptr) { | 2385 HeapEntry* FindEntry(HeapThing ptr) { |
| 2152 HeapEntry* entry = entries_->Map(ptr); | 2386 return entries_->Map(ptr); |
| 2153 return entry != NULL ? entry : AddEntry(ptr); | 2387 } |
| 2388 HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { | |
| 2389 HeapEntry* entry = FindEntry(ptr); | |
| 2390 return entry != NULL ? entry : AddEntry(ptr, allocator); | |
| 2154 } | 2391 } |
| 2155 void SetIndexedReference(HeapGraphEdge::Type, | 2392 void SetIndexedReference(HeapGraphEdge::Type, |
| 2156 HeapThing parent_ptr, | 2393 HeapThing parent_ptr, |
| 2157 HeapEntry*, | 2394 HeapEntry*, |
| 2158 int, | 2395 int, |
| 2159 HeapThing child_ptr, | 2396 HeapThing child_ptr, |
| 2160 HeapEntry*) { | 2397 HeapEntry*) { |
| 2161 entries_->CountReference(parent_ptr, child_ptr); | 2398 entries_->CountReference(parent_ptr, child_ptr); |
| 2162 } | 2399 } |
| 2163 void SetIndexedAutoIndexReference(HeapGraphEdge::Type, | 2400 void SetIndexedAutoIndexReference(HeapGraphEdge::Type, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2176 entries_->CountReference(parent_ptr, child_ptr); | 2413 entries_->CountReference(parent_ptr, child_ptr); |
| 2177 } | 2414 } |
| 2178 void SetNamedAutoIndexReference(HeapGraphEdge::Type, | 2415 void SetNamedAutoIndexReference(HeapGraphEdge::Type, |
| 2179 HeapThing parent_ptr, | 2416 HeapThing parent_ptr, |
| 2180 HeapEntry*, | 2417 HeapEntry*, |
| 2181 HeapThing child_ptr, | 2418 HeapThing child_ptr, |
| 2182 HeapEntry*) { | 2419 HeapEntry*) { |
| 2183 entries_->CountReference(parent_ptr, child_ptr); | 2420 entries_->CountReference(parent_ptr, child_ptr); |
| 2184 } | 2421 } |
| 2185 private: | 2422 private: |
| 2186 HeapEntriesAllocator* allocator_; | |
| 2187 HeapEntriesMap* entries_; | 2423 HeapEntriesMap* entries_; |
| 2188 }; | 2424 }; |
| 2189 | 2425 |
| 2190 | 2426 |
| 2191 class SnapshotFiller : public SnapshotFillerInterface { | 2427 class SnapshotFiller : public SnapshotFillerInterface { |
| 2192 public: | 2428 public: |
| 2193 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) | 2429 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) |
| 2194 : snapshot_(snapshot), | 2430 : snapshot_(snapshot), |
| 2195 collection_(snapshot->collection()), | 2431 collection_(snapshot->collection()), |
| 2196 entries_(entries) { } | 2432 entries_(entries) { } |
| 2197 HeapEntry* AddEntry(HeapThing ptr) { | 2433 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { |
| 2198 UNREACHABLE(); | 2434 UNREACHABLE(); |
| 2199 return NULL; | 2435 return NULL; |
| 2200 } | 2436 } |
| 2201 HeapEntry* FindOrAddEntry(HeapThing ptr) { | 2437 HeapEntry* FindEntry(HeapThing ptr) { |
| 2202 HeapEntry* entry = entries_->Map(ptr); | 2438 return entries_->Map(ptr); |
| 2203 return entry != NULL ? entry : AddEntry(ptr); | 2439 } |
| 2440 HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { | |
| 2441 HeapEntry* entry = FindEntry(ptr); | |
| 2442 return entry != NULL ? entry : AddEntry(ptr, allocator); | |
| 2204 } | 2443 } |
| 2205 void SetIndexedReference(HeapGraphEdge::Type type, | 2444 void SetIndexedReference(HeapGraphEdge::Type type, |
| 2206 HeapThing parent_ptr, | 2445 HeapThing parent_ptr, |
| 2207 HeapEntry* parent_entry, | 2446 HeapEntry* parent_entry, |
| 2208 int index, | 2447 int index, |
| 2209 HeapThing child_ptr, | 2448 HeapThing child_ptr, |
| 2210 HeapEntry* child_entry) { | 2449 HeapEntry* child_entry) { |
| 2211 int child_index, retainer_index; | 2450 int child_index, retainer_index; |
| 2212 entries_->CountReference( | 2451 entries_->CountReference( |
| 2213 parent_ptr, child_ptr, &child_index, &retainer_index); | 2452 parent_ptr, child_ptr, &child_index, &retainer_index); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2296 return | 2535 return |
| 2297 control_->ReportProgressValue(progress_counter_, progress_total_) == | 2536 control_->ReportProgressValue(progress_counter_, progress_total_) == |
| 2298 v8::ActivityControl::kContinue; | 2537 v8::ActivityControl::kContinue; |
| 2299 } | 2538 } |
| 2300 return true; | 2539 return true; |
| 2301 } | 2540 } |
| 2302 | 2541 |
| 2303 | 2542 |
| 2304 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) { | 2543 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) { |
| 2305 if (control_ == NULL) return; | 2544 if (control_ == NULL) return; |
| 2306 progress_total_ = v8_heap_explorer_.EstimateObjectsCount() * iterations_count; | 2545 progress_total_ = ( |
| 2546 v8_heap_explorer_.EstimateObjectsCount() + | |
| 2547 dom_explorer_.EstimateObjectsCount()) * iterations_count; | |
| 2307 progress_counter_ = 0; | 2548 progress_counter_ = 0; |
| 2308 } | 2549 } |
| 2309 | 2550 |
| 2310 | 2551 |
| 2311 bool HeapSnapshotGenerator::CountEntriesAndReferences() { | 2552 bool HeapSnapshotGenerator::CountEntriesAndReferences() { |
| 2312 SnapshotCounter counter(&v8_heap_explorer_, &entries_); | 2553 SnapshotCounter counter(&entries_); |
| 2313 v8_heap_explorer_.AddRootEntries(&counter); | 2554 v8_heap_explorer_.AddRootEntries(&counter); |
| 2314 return v8_heap_explorer_.IterateAndExtractReferences(&counter); | 2555 dom_explorer_.AddRootEntries(&counter); |
| 2556 return | |
| 2557 v8_heap_explorer_.IterateAndExtractReferences(&counter) && | |
| 2558 dom_explorer_.IterateAndExtractReferences(&counter); | |
| 2315 } | 2559 } |
| 2316 | 2560 |
| 2317 | 2561 |
| 2318 bool HeapSnapshotGenerator::FillReferences() { | 2562 bool HeapSnapshotGenerator::FillReferences() { |
| 2319 SnapshotFiller filler(snapshot_, &entries_); | 2563 SnapshotFiller filler(snapshot_, &entries_); |
| 2320 return v8_heap_explorer_.IterateAndExtractReferences(&filler); | 2564 return |
| 2565 v8_heap_explorer_.IterateAndExtractReferences(&filler) && | |
| 2566 dom_explorer_.IterateAndExtractReferences(&filler); | |
| 2321 } | 2567 } |
| 2322 | 2568 |
| 2323 | 2569 |
| 2324 void HeapSnapshotGenerator::FillReversePostorderIndexes( | 2570 void HeapSnapshotGenerator::FillReversePostorderIndexes( |
| 2325 Vector<HeapEntry*>* entries) { | 2571 Vector<HeapEntry*>* entries) { |
| 2326 snapshot_->ClearPaint(); | 2572 snapshot_->ClearPaint(); |
| 2327 int current_entry = 0; | 2573 int current_entry = 0; |
| 2328 List<HeapEntry*> nodes_to_visit; | 2574 List<HeapEntry*> nodes_to_visit; |
| 2329 nodes_to_visit.Add(snapshot_->root()); | 2575 nodes_to_visit.Add(snapshot_->root()); |
| 2330 snapshot_->root()->paint_reachable(); | 2576 snapshot_->root()->paint_reachable(); |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2728 "," JSON_S("children")) | 2974 "," JSON_S("children")) |
| 2729 "," JSON_S("types") ":" JSON_A( | 2975 "," JSON_S("types") ":" JSON_A( |
| 2730 JSON_A( | 2976 JSON_A( |
| 2731 JSON_S("hidden") | 2977 JSON_S("hidden") |
| 2732 "," JSON_S("array") | 2978 "," JSON_S("array") |
| 2733 "," JSON_S("string") | 2979 "," JSON_S("string") |
| 2734 "," JSON_S("object") | 2980 "," JSON_S("object") |
| 2735 "," JSON_S("code") | 2981 "," JSON_S("code") |
| 2736 "," JSON_S("closure") | 2982 "," JSON_S("closure") |
| 2737 "," JSON_S("regexp") | 2983 "," JSON_S("regexp") |
| 2738 "," JSON_S("number")) | 2984 "," JSON_S("number") |
| 2985 "," JSON_S("native")) | |
| 2739 "," JSON_S("string") | 2986 "," JSON_S("string") |
| 2740 "," JSON_S("number") | 2987 "," JSON_S("number") |
| 2741 "," JSON_S("number") | 2988 "," JSON_S("number") |
| 2742 "," JSON_S("number") | 2989 "," JSON_S("number") |
| 2743 "," JSON_S("number") | 2990 "," JSON_S("number") |
| 2744 "," JSON_S("number") | 2991 "," JSON_S("number") |
| 2745 "," JSON_O( | 2992 "," JSON_O( |
| 2746 JSON_S("fields") ":" JSON_A( | 2993 JSON_S("fields") ":" JSON_A( |
| 2747 JSON_S("type") | 2994 JSON_S("type") |
| 2748 "," JSON_S("name_or_index") | 2995 "," JSON_S("name_or_index") |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2890 | 3137 |
| 2891 | 3138 |
| 2892 String* GetConstructorNameForHeapProfile(JSObject* object) { | 3139 String* GetConstructorNameForHeapProfile(JSObject* object) { |
| 2893 if (object->IsJSFunction()) return Heap::closure_symbol(); | 3140 if (object->IsJSFunction()) return Heap::closure_symbol(); |
| 2894 return object->constructor_name(); | 3141 return object->constructor_name(); |
| 2895 } | 3142 } |
| 2896 | 3143 |
| 2897 } } // namespace v8::internal | 3144 } } // namespace v8::internal |
| 2898 | 3145 |
| 2899 #endif // ENABLE_LOGGING_AND_PROFILING | 3146 #endif // ENABLE_LOGGING_AND_PROFILING |
| OLD | NEW |