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 |