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

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

Issue 6626043: Add an interface for an embedder to provide information about native (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix GetCopy Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 11 matching lines...) Expand all
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
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::GetCopy(const char* src) {
108 int len = strlen(src);
109 Vector<char> dst = Vector<char>::New(len + 1);
110 OS::StrNCpy(dst, src, len);
111 dst[len] = '\0';
112 uint32_t hash = HashSequentialString(dst.start(), len);
113 return AddOrDisposeString(dst.start(), hash);
114 }
115
116
117 const char* StringsStorage::GetFormatted(const char* format, ...) {
118 va_list args;
119 va_start(args, format);
120 const char* result = GetVFormatted(format, args);
121 va_end(args);
122 return result;
123 }
124
125
126 const char* StringsStorage::AddOrDisposeString(char* str, uint32_t hash) {
127 HashMap::Entry* cache_entry = names_.Lookup(str, hash, true);
128 if (cache_entry->value == NULL) {
129 // New entry added.
130 cache_entry->value = str;
131 } else {
132 DeleteArray(str);
133 }
134 return reinterpret_cast<const char*>(cache_entry->value);
135 }
136
137
138 const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
139 Vector<char> str = Vector<char>::New(1024);
140 int len = OS::VSNPrintF(str, format, args);
141 if (len == -1) {
142 DeleteArray(str.start());
143 return format;
144 }
145 uint32_t hash = HashSequentialString(str.start(), len);
146 return AddOrDisposeString(str.start(), hash);
109 } 147 }
110 148
111 149
112 const char* StringsStorage::GetName(String* name) { 150 const char* StringsStorage::GetName(String* name) {
113 if (name->IsString()) { 151 if (name->IsString()) {
114 char* c_name = 152 return AddOrDisposeString(
115 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach(); 153 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach(),
116 HashMap::Entry* cache_entry = names_.Lookup(c_name, name->Hash(), true); 154 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 } 155 }
125 return ""; 156 return "";
126 } 157 }
127 158
128 159
129 const char* StringsStorage::GetName(int index) { 160 const char* StringsStorage::GetName(int index) {
130 ASSERT(index >= 0); 161 return GetFormatted("%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 } 162 }
143 163
144 164
145 const char* CodeEntry::kEmptyNamePrefix = ""; 165 const char* CodeEntry::kEmptyNamePrefix = "";
146 166
147 167
148 void CodeEntry::CopyData(const CodeEntry& source) { 168 void CodeEntry::CopyData(const CodeEntry& source) {
149 tag_ = source.tag_; 169 tag_ = source.tag_;
150 name_prefix_ = source.name_prefix_; 170 name_prefix_ = source.name_prefix_;
151 name_ = source.name_; 171 name_ = source.name_;
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 const char* HeapEntry::TypeAsString() { 1022 const char* HeapEntry::TypeAsString() {
1003 switch (type()) { 1023 switch (type()) {
1004 case kHidden: return "/hidden/"; 1024 case kHidden: return "/hidden/";
1005 case kObject: return "/object/"; 1025 case kObject: return "/object/";
1006 case kClosure: return "/closure/"; 1026 case kClosure: return "/closure/";
1007 case kString: return "/string/"; 1027 case kString: return "/string/";
1008 case kCode: return "/code/"; 1028 case kCode: return "/code/";
1009 case kArray: return "/array/"; 1029 case kArray: return "/array/";
1010 case kRegExp: return "/regexp/"; 1030 case kRegExp: return "/regexp/";
1011 case kHeapNumber: return "/number/"; 1031 case kHeapNumber: return "/number/";
1032 case kNative: return "/native/";
1012 default: return "???"; 1033 default: return "???";
1013 } 1034 }
1014 } 1035 }
1015 1036
1016 1037
1017 int HeapEntry::EntriesSize(int entries_count, 1038 int HeapEntry::EntriesSize(int entries_count,
1018 int children_count, 1039 int children_count,
1019 int retainers_count) { 1040 int retainers_count) {
1020 return sizeof(HeapEntry) * entries_count // NOLINT 1041 return sizeof(HeapEntry) * entries_count // NOLINT
1021 + sizeof(HeapGraphEdge) * children_count // NOLINT 1042 + sizeof(HeapGraphEdge) * children_count // NOLINT
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, 1219 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection,
1199 HeapSnapshot::Type type, 1220 HeapSnapshot::Type type,
1200 const char* title, 1221 const char* title,
1201 unsigned uid) 1222 unsigned uid)
1202 : collection_(collection), 1223 : collection_(collection),
1203 type_(type), 1224 type_(type),
1204 title_(title), 1225 title_(title),
1205 uid_(uid), 1226 uid_(uid),
1206 root_entry_(NULL), 1227 root_entry_(NULL),
1207 gc_roots_entry_(NULL), 1228 gc_roots_entry_(NULL),
1229 dom_subtrees_root_entry_(NULL),
1208 raw_entries_(NULL), 1230 raw_entries_(NULL),
1209 entries_sorted_(false), 1231 entries_sorted_(false),
1210 retaining_paths_(HeapEntry::Match) { 1232 retaining_paths_(HeapEntry::Match) {
1211 STATIC_ASSERT( 1233 STATIC_ASSERT(
1212 sizeof(HeapGraphEdge) == 1234 sizeof(HeapGraphEdge) ==
1213 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapGraphEdgeSize); // NOL INT 1235 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapGraphEdgeSize); // NOL INT
1214 STATIC_ASSERT( 1236 STATIC_ASSERT(
1215 sizeof(HeapEntry) == 1237 sizeof(HeapEntry) ==
1216 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapEntrySize); // NOLINT 1238 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapEntrySize); // NOLINT
1217 } 1239 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 ASSERT(gc_roots_entry_ == NULL); 1294 ASSERT(gc_roots_entry_ == NULL);
1273 return (gc_roots_entry_ = AddEntry(HeapEntry::kObject, 1295 return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
1274 "(GC roots)", 1296 "(GC roots)",
1275 HeapObjectsMap::kGcRootsObjectId, 1297 HeapObjectsMap::kGcRootsObjectId,
1276 0, 1298 0,
1277 children_count, 1299 children_count,
1278 retainers_count)); 1300 retainers_count));
1279 } 1301 }
1280 1302
1281 1303
1304 HeapEntry* HeapSnapshot::AddNativesRootEntry(int children_count,
1305 int retainers_count) {
1306 ASSERT(dom_subtrees_root_entry_ == NULL);
1307 return (dom_subtrees_root_entry_ = AddEntry(
1308 HeapEntry::kObject,
1309 "(Native objects)",
1310 HeapObjectsMap::kNativesRootObjectId,
1311 0,
1312 children_count,
1313 retainers_count));
1314 }
1315
1316
1282 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, 1317 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type,
1283 const char* name, 1318 const char* name,
1284 uint64_t id, 1319 uint64_t id,
1285 int size, 1320 int size,
1286 int children_count, 1321 int children_count,
1287 int retainers_count) { 1322 int retainers_count) {
1288 HeapEntry* entry = GetNextEntryToInit(); 1323 HeapEntry* entry = GetNextEntryToInit();
1289 entry->Init(this, type, name, id, size, children_count, retainers_count); 1324 entry->Init(this, type, name, id, size, children_count, retainers_count);
1290 return entry; 1325 return entry;
1291 } 1326 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1365 } 1400 }
1366 return &entries_; 1401 return &entries_;
1367 } 1402 }
1368 1403
1369 1404
1370 void HeapSnapshot::Print(int max_depth) { 1405 void HeapSnapshot::Print(int max_depth) {
1371 root()->Print(max_depth, 0); 1406 root()->Print(max_depth, 0);
1372 } 1407 }
1373 1408
1374 1409
1375 const uint64_t HeapObjectsMap::kInternalRootObjectId = 0; 1410 // We split IDs on evens for embedder objects (see
1376 const uint64_t HeapObjectsMap::kGcRootsObjectId = 1; 1411 // HeapObjectsMap::GenerateId) and odds for native objects.
1412 const uint64_t HeapObjectsMap::kInternalRootObjectId = 1;
1413 const uint64_t HeapObjectsMap::kGcRootsObjectId = 3;
1414 const uint64_t HeapObjectsMap::kNativesRootObjectId = 5;
1377 // Increase kFirstAvailableObjectId if new 'special' objects appear. 1415 // Increase kFirstAvailableObjectId if new 'special' objects appear.
1378 const uint64_t HeapObjectsMap::kFirstAvailableObjectId = 2; 1416 const uint64_t HeapObjectsMap::kFirstAvailableObjectId = 7;
1379 1417
1380 HeapObjectsMap::HeapObjectsMap() 1418 HeapObjectsMap::HeapObjectsMap()
1381 : initial_fill_mode_(true), 1419 : initial_fill_mode_(true),
1382 next_id_(kFirstAvailableObjectId), 1420 next_id_(kFirstAvailableObjectId),
1383 entries_map_(AddressesMatch), 1421 entries_map_(AddressesMatch),
1384 entries_(new List<EntryInfo>()) { } 1422 entries_(new List<EntryInfo>()) { }
1385 1423
1386 1424
1387 HeapObjectsMap::~HeapObjectsMap() { 1425 HeapObjectsMap::~HeapObjectsMap() {
1388 delete entries_; 1426 delete entries_;
1389 } 1427 }
1390 1428
1391 1429
1392 void HeapObjectsMap::SnapshotGenerationFinished() { 1430 void HeapObjectsMap::SnapshotGenerationFinished() {
1393 initial_fill_mode_ = false; 1431 initial_fill_mode_ = false;
1394 RemoveDeadEntries(); 1432 RemoveDeadEntries();
1395 } 1433 }
1396 1434
1397 1435
1398 uint64_t HeapObjectsMap::FindObject(Address addr) { 1436 uint64_t HeapObjectsMap::FindObject(Address addr) {
1399 if (!initial_fill_mode_) { 1437 if (!initial_fill_mode_) {
1400 uint64_t existing = FindEntry(addr); 1438 uint64_t existing = FindEntry(addr);
1401 if (existing != 0) return existing; 1439 if (existing != 0) return existing;
1402 } 1440 }
1403 uint64_t id = next_id_++; 1441 uint64_t id = next_id_;
1442 next_id_ += 2;
1404 AddEntry(addr, id); 1443 AddEntry(addr, id);
1405 return id; 1444 return id;
1406 } 1445 }
1407 1446
1408 1447
1409 void HeapObjectsMap::MoveObject(Address from, Address to) { 1448 void HeapObjectsMap::MoveObject(Address from, Address to) {
1410 if (from == to) return; 1449 if (from == to) return;
1411 HashMap::Entry* entry = entries_map_.Lookup(from, AddressHash(from), false); 1450 HashMap::Entry* entry = entries_map_.Lookup(from, AddressHash(from), false);
1412 if (entry != NULL) { 1451 if (entry != NULL) {
1413 void* value = entry->value; 1452 void* value = entry->value;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1461 for (int i = 0; i < dead_entries.length(); ++i) { 1500 for (int i = 0; i < dead_entries.length(); ++i) {
1462 void* raw_entry = dead_entries[i]; 1501 void* raw_entry = dead_entries[i];
1463 entries_map_.Remove( 1502 entries_map_.Remove(
1464 raw_entry, AddressHash(reinterpret_cast<Address>(raw_entry))); 1503 raw_entry, AddressHash(reinterpret_cast<Address>(raw_entry)));
1465 } 1504 }
1466 delete entries_; 1505 delete entries_;
1467 entries_ = new_entries; 1506 entries_ = new_entries;
1468 } 1507 }
1469 1508
1470 1509
1510 uint64_t HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
1511 uint64_t id = static_cast<uint64_t>(info->GetHash());
1512 const char* label = info->GetLabel();
1513 id ^= HashSequentialString(label, strlen(label));
1514 intptr_t element_count = info->GetElementCount();
1515 if (element_count != -1)
1516 id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count));
1517 return id << 1;
1518 }
1519
1520
1471 HeapSnapshotsCollection::HeapSnapshotsCollection() 1521 HeapSnapshotsCollection::HeapSnapshotsCollection()
1472 : is_tracking_objects_(false), 1522 : is_tracking_objects_(false),
1473 snapshots_uids_(HeapSnapshotsMatch), 1523 snapshots_uids_(HeapSnapshotsMatch),
1474 token_enumerator_(new TokenEnumerator()) { 1524 token_enumerator_(new TokenEnumerator()) {
1475 } 1525 }
1476 1526
1477 1527
1478 static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) { 1528 static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) {
1479 delete *snapshot_ptr; 1529 delete *snapshot_ptr;
1480 } 1530 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 1594
1545 void HeapEntriesMap::AllocateEntries() { 1595 void HeapEntriesMap::AllocateEntries() {
1546 for (HashMap::Entry* p = entries_.Start(); 1596 for (HashMap::Entry* p = entries_.Start();
1547 p != NULL; 1597 p != NULL;
1548 p = entries_.Next(p)) { 1598 p = entries_.Next(p)) {
1549 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value); 1599 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value);
1550 entry_info->entry = entry_info->allocator->AllocateEntry( 1600 entry_info->entry = entry_info->allocator->AllocateEntry(
1551 p->key, 1601 p->key,
1552 entry_info->children_count, 1602 entry_info->children_count,
1553 entry_info->retainers_count); 1603 entry_info->retainers_count);
1604 ASSERT(entry_info->entry != NULL);
1605 ASSERT(entry_info->entry != kHeapEntryPlaceholder);
1554 entry_info->children_count = 0; 1606 entry_info->children_count = 0;
1555 entry_info->retainers_count = 0; 1607 entry_info->retainers_count = 0;
1556 } 1608 }
1557 } 1609 }
1558 1610
1559 1611
1560 HeapEntry* HeapEntriesMap::Map(HeapThing thing) { 1612 HeapEntry* HeapEntriesMap::Map(HeapThing thing) {
1561 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false); 1613 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
1562 if (cache_entry != NULL) { 1614 if (cache_entry != NULL) {
1563 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value); 1615 EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1623 HeapObject* object = HeapObject::cast(obj); 1675 HeapObject* object = HeapObject::cast(obj);
1624 HashMap::Entry* cache_entry = 1676 HashMap::Entry* cache_entry =
1625 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); 1677 entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
1626 if (cache_entry->value == NULL) { 1678 if (cache_entry->value == NULL) {
1627 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder; 1679 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder;
1628 } 1680 }
1629 } 1681 }
1630 1682
1631 1683
1632 HeapObject *const V8HeapExplorer::kInternalRootObject = 1684 HeapObject *const V8HeapExplorer::kInternalRootObject =
1633 reinterpret_cast<HeapObject*>(1); 1685 reinterpret_cast<HeapObject*>(
1686 static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId));
1634 HeapObject *const V8HeapExplorer::kGcRootsObject = 1687 HeapObject *const V8HeapExplorer::kGcRootsObject =
1635 reinterpret_cast<HeapObject*>(2); 1688 reinterpret_cast<HeapObject*>(
1689 static_cast<intptr_t>(HeapObjectsMap::kGcRootsObjectId));
1636 1690
1637 1691
1638 V8HeapExplorer::V8HeapExplorer( 1692 V8HeapExplorer::V8HeapExplorer(
1639 HeapSnapshot* snapshot, 1693 HeapSnapshot* snapshot,
1640 SnapshottingProgressReportingInterface* progress) 1694 SnapshottingProgressReportingInterface* progress)
1641 : snapshot_(snapshot), 1695 : snapshot_(snapshot),
1642 collection_(snapshot_->collection()), 1696 collection_(snapshot_->collection()),
1643 progress_(progress), 1697 progress_(progress),
1644 filler_(NULL) { 1698 filler_(NULL) {
1645 } 1699 }
(...skipping 16 matching lines...) Expand all
1662 if (object == kInternalRootObject) { 1716 if (object == kInternalRootObject) {
1663 ASSERT(retainers_count == 0); 1717 ASSERT(retainers_count == 0);
1664 return snapshot_->AddRootEntry(children_count); 1718 return snapshot_->AddRootEntry(children_count);
1665 } else if (object == kGcRootsObject) { 1719 } else if (object == kGcRootsObject) {
1666 return snapshot_->AddGcRootsEntry(children_count, retainers_count); 1720 return snapshot_->AddGcRootsEntry(children_count, retainers_count);
1667 } else if (object->IsJSFunction()) { 1721 } else if (object->IsJSFunction()) {
1668 JSFunction* func = JSFunction::cast(object); 1722 JSFunction* func = JSFunction::cast(object);
1669 SharedFunctionInfo* shared = func->shared(); 1723 SharedFunctionInfo* shared = func->shared();
1670 return AddEntry(object, 1724 return AddEntry(object,
1671 HeapEntry::kClosure, 1725 HeapEntry::kClosure,
1672 collection_->GetName(String::cast(shared->name())), 1726 collection_->names()->GetName(String::cast(shared->name())),
1673 children_count, 1727 children_count,
1674 retainers_count); 1728 retainers_count);
1675 } else if (object->IsJSRegExp()) { 1729 } else if (object->IsJSRegExp()) {
1676 JSRegExp* re = JSRegExp::cast(object); 1730 JSRegExp* re = JSRegExp::cast(object);
1677 return AddEntry(object, 1731 return AddEntry(object,
1678 HeapEntry::kRegExp, 1732 HeapEntry::kRegExp,
1679 collection_->GetName(re->Pattern()), 1733 collection_->names()->GetName(re->Pattern()),
1680 children_count, 1734 children_count,
1681 retainers_count); 1735 retainers_count);
1682 } else if (object->IsJSObject()) { 1736 } else if (object->IsJSObject()) {
1683 return AddEntry(object, 1737 return AddEntry(object,
1684 HeapEntry::kObject, 1738 HeapEntry::kObject,
1685 collection_->GetName(GetConstructorNameForHeapProfile( 1739 collection_->names()->GetName(
1686 JSObject::cast(object))), 1740 GetConstructorNameForHeapProfile(
1741 JSObject::cast(object))),
1687 children_count, 1742 children_count,
1688 retainers_count); 1743 retainers_count);
1689 } else if (object->IsString()) { 1744 } else if (object->IsString()) {
1690 return AddEntry(object, 1745 return AddEntry(object,
1691 HeapEntry::kString, 1746 HeapEntry::kString,
1692 collection_->GetName(String::cast(object)), 1747 collection_->names()->GetName(String::cast(object)),
1693 children_count, 1748 children_count,
1694 retainers_count); 1749 retainers_count);
1695 } else if (object->IsCode()) { 1750 } else if (object->IsCode()) {
1696 return AddEntry(object, 1751 return AddEntry(object,
1697 HeapEntry::kCode, 1752 HeapEntry::kCode,
1698 "", 1753 "",
1699 children_count, 1754 children_count,
1700 retainers_count); 1755 retainers_count);
1701 } else if (object->IsSharedFunctionInfo()) { 1756 } else if (object->IsSharedFunctionInfo()) {
1702 SharedFunctionInfo* shared = SharedFunctionInfo::cast(object); 1757 SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
1703 return AddEntry(object, 1758 return AddEntry(object,
1704 HeapEntry::kCode, 1759 HeapEntry::kCode,
1705 collection_->GetName(String::cast(shared->name())), 1760 collection_->names()->GetName(String::cast(shared->name())),
1706 children_count, 1761 children_count,
1707 retainers_count); 1762 retainers_count);
1708 } else if (object->IsScript()) { 1763 } else if (object->IsScript()) {
1709 Script* script = Script::cast(object); 1764 Script* script = Script::cast(object);
1710 return AddEntry(object, 1765 return AddEntry(object,
1711 HeapEntry::kCode, 1766 HeapEntry::kCode,
1712 script->name()->IsString() ? 1767 script->name()->IsString() ?
1713 collection_->GetName(String::cast(script->name())) : "", 1768 collection_->names()->GetName(
1769 String::cast(script->name()))
1770 : "",
1714 children_count, 1771 children_count,
1715 retainers_count); 1772 retainers_count);
1716 } else if (object->IsFixedArray()) { 1773 } else if (object->IsFixedArray()) {
1717 return AddEntry(object, 1774 return AddEntry(object,
1718 HeapEntry::kArray, 1775 HeapEntry::kArray,
1719 "", 1776 "",
1720 children_count, 1777 children_count,
1721 retainers_count); 1778 retainers_count);
1722 } else if (object->IsHeapNumber()) { 1779 } else if (object->IsHeapNumber()) {
1723 return AddEntry(object, 1780 return AddEntry(object,
(...skipping 18 matching lines...) Expand all
1742 return snapshot_->AddEntry(type, 1799 return snapshot_->AddEntry(type,
1743 name, 1800 name,
1744 collection_->GetObjectId(object->address()), 1801 collection_->GetObjectId(object->address()),
1745 object->Size(), 1802 object->Size(),
1746 children_count, 1803 children_count,
1747 retainers_count); 1804 retainers_count);
1748 } 1805 }
1749 1806
1750 1807
1751 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { 1808 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) {
1752 filler->AddEntry(kInternalRootObject); 1809 filler->AddEntry(kInternalRootObject, this);
1753 filler->AddEntry(kGcRootsObject); 1810 filler->AddEntry(kGcRootsObject, this);
1754 } 1811 }
1755 1812
1756 1813
1757 int V8HeapExplorer::EstimateObjectsCount() { 1814 int V8HeapExplorer::EstimateObjectsCount() {
1758 HeapIterator iterator(HeapIterator::kFilterUnreachable); 1815 HeapIterator iterator(HeapIterator::kFilterUnreachable);
1759 int objects_count = 0; 1816 int objects_count = 0;
1760 for (HeapObject* obj = iterator.next(); 1817 for (HeapObject* obj = iterator.next();
1761 obj != NULL; 1818 obj != NULL;
1762 obj = iterator.next(), ++objects_count) {} 1819 obj = iterator.next(), ++objects_count) {}
1763 return objects_count; 1820 return objects_count;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 int length = js_obj->GetInternalFieldCount(); 1990 int length = js_obj->GetInternalFieldCount();
1934 for (int i = 0; i < length; ++i) { 1991 for (int i = 0; i < length; ++i) {
1935 Object* o = js_obj->GetInternalField(i); 1992 Object* o = js_obj->GetInternalField(i);
1936 SetInternalReference(js_obj, entry, i, o); 1993 SetInternalReference(js_obj, entry, i, o);
1937 } 1994 }
1938 } 1995 }
1939 1996
1940 1997
1941 HeapEntry* V8HeapExplorer::GetEntry(Object* obj) { 1998 HeapEntry* V8HeapExplorer::GetEntry(Object* obj) {
1942 if (!obj->IsHeapObject()) return NULL; 1999 if (!obj->IsHeapObject()) return NULL;
1943 return filler_->FindOrAddEntry(obj); 2000 return filler_->FindOrAddEntry(obj, this);
1944 } 2001 }
1945 2002
1946 2003
1947 class RootsReferencesExtractor : public ObjectVisitor { 2004 class RootsReferencesExtractor : public ObjectVisitor {
1948 public: 2005 public:
1949 explicit RootsReferencesExtractor(V8HeapExplorer* explorer) 2006 explicit RootsReferencesExtractor(V8HeapExplorer* explorer)
1950 : explorer_(explorer) { 2007 : explorer_(explorer) {
1951 } 2008 }
1952 void VisitPointers(Object** start, Object** end) { 2009 void VisitPointers(Object** start, Object** end) {
1953 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p); 2010 for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1985 2042
1986 void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj, 2043 void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
1987 HeapEntry* parent_entry, 2044 HeapEntry* parent_entry,
1988 String* reference_name, 2045 String* reference_name,
1989 Object* child_obj) { 2046 Object* child_obj) {
1990 HeapEntry* child_entry = GetEntry(child_obj); 2047 HeapEntry* child_entry = GetEntry(child_obj);
1991 if (child_entry != NULL) { 2048 if (child_entry != NULL) {
1992 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, 2049 filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
1993 parent_obj, 2050 parent_obj,
1994 parent_entry, 2051 parent_entry,
1995 collection_->GetName(reference_name), 2052 collection_->names()->GetName(reference_name),
1996 child_obj, 2053 child_obj,
1997 child_entry); 2054 child_entry);
1998 known_references_.Insert(child_obj); 2055 known_references_.Insert(child_obj);
1999 } 2056 }
2000 } 2057 }
2001 2058
2002 2059
2003 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, 2060 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
2004 HeapEntry* parent_entry, 2061 HeapEntry* parent_entry,
2005 int index, 2062 int index,
(...skipping 30 matching lines...) Expand all
2036 2093
2037 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, 2094 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
2038 HeapEntry* parent_entry, 2095 HeapEntry* parent_entry,
2039 int index, 2096 int index,
2040 Object* child_obj) { 2097 Object* child_obj) {
2041 HeapEntry* child_entry = GetEntry(child_obj); 2098 HeapEntry* child_entry = GetEntry(child_obj);
2042 if (child_entry != NULL) { 2099 if (child_entry != NULL) {
2043 filler_->SetNamedReference(HeapGraphEdge::kInternal, 2100 filler_->SetNamedReference(HeapGraphEdge::kInternal,
2044 parent_obj, 2101 parent_obj,
2045 parent_entry, 2102 parent_entry,
2046 collection_->GetName(index), 2103 collection_->names()->GetName(index),
2047 child_obj, 2104 child_obj,
2048 child_entry); 2105 child_entry);
2049 known_references_.Insert(child_obj); 2106 known_references_.Insert(child_obj);
2050 } 2107 }
2051 } 2108 }
2052 2109
2053 2110
2054 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, 2111 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
2055 HeapEntry* parent_entry, 2112 HeapEntry* parent_entry,
2056 int index, 2113 int index,
(...skipping 14 matching lines...) Expand all
2071 HeapEntry* parent_entry, 2128 HeapEntry* parent_entry,
2072 String* reference_name, 2129 String* reference_name,
2073 Object* child_obj) { 2130 Object* child_obj) {
2074 HeapEntry* child_entry = GetEntry(child_obj); 2131 HeapEntry* child_entry = GetEntry(child_obj);
2075 if (child_entry != NULL) { 2132 if (child_entry != NULL) {
2076 HeapGraphEdge::Type type = reference_name->length() > 0 ? 2133 HeapGraphEdge::Type type = reference_name->length() > 0 ?
2077 HeapGraphEdge::kProperty : HeapGraphEdge::kInternal; 2134 HeapGraphEdge::kProperty : HeapGraphEdge::kInternal;
2078 filler_->SetNamedReference(type, 2135 filler_->SetNamedReference(type,
2079 parent_obj, 2136 parent_obj,
2080 parent_entry, 2137 parent_entry,
2081 collection_->GetName(reference_name), 2138 collection_->names()->GetName(reference_name),
2082 child_obj, 2139 child_obj,
2083 child_entry); 2140 child_entry);
2084 known_references_.Insert(child_obj); 2141 known_references_.Insert(child_obj);
2085 } 2142 }
2086 } 2143 }
2087 2144
2088 2145
2089 void V8HeapExplorer::SetPropertyShortcutReference( 2146 void V8HeapExplorer::SetPropertyShortcutReference(
2090 HeapObject* parent_obj, 2147 HeapObject* parent_obj,
2091 HeapEntry* parent_entry, 2148 HeapEntry* parent_entry,
2092 String* reference_name, 2149 String* reference_name,
2093 Object* child_obj) { 2150 Object* child_obj) {
2094 HeapEntry* child_entry = GetEntry(child_obj); 2151 HeapEntry* child_entry = GetEntry(child_obj);
2095 if (child_entry != NULL) { 2152 if (child_entry != NULL) {
2096 filler_->SetNamedReference(HeapGraphEdge::kShortcut, 2153 filler_->SetNamedReference(HeapGraphEdge::kShortcut,
2097 parent_obj, 2154 parent_obj,
2098 parent_entry, 2155 parent_entry,
2099 collection_->GetName(reference_name), 2156 collection_->names()->GetName(reference_name),
2100 child_obj, 2157 child_obj,
2101 child_entry); 2158 child_entry);
2102 } 2159 }
2103 } 2160 }
2104 2161
2105 2162
2106 void V8HeapExplorer::SetRootGcRootsReference() { 2163 void V8HeapExplorer::SetRootGcRootsReference() {
2107 filler_->SetIndexedAutoIndexReference( 2164 filler_->SetIndexedAutoIndexReference(
2108 HeapGraphEdge::kElement, 2165 HeapGraphEdge::kElement,
2109 kInternalRootObject, snapshot_->root(), 2166 kInternalRootObject, snapshot_->root(),
(...skipping 15 matching lines...) Expand all
2125 HeapEntry* child_entry = GetEntry(child_obj); 2182 HeapEntry* child_entry = GetEntry(child_obj);
2126 if (child_entry != NULL) { 2183 if (child_entry != NULL) {
2127 filler_->SetIndexedAutoIndexReference( 2184 filler_->SetIndexedAutoIndexReference(
2128 HeapGraphEdge::kElement, 2185 HeapGraphEdge::kElement,
2129 kGcRootsObject, snapshot_->gc_roots(), 2186 kGcRootsObject, snapshot_->gc_roots(),
2130 child_obj, child_entry); 2187 child_obj, child_entry);
2131 } 2188 }
2132 } 2189 }
2133 2190
2134 2191
2192 class GlobalHandlesExtractor : public ObjectVisitor {
2193 public:
2194 explicit GlobalHandlesExtractor(NativeObjectsExplorer* explorer)
2195 : explorer_(explorer) {}
2196 virtual ~GlobalHandlesExtractor() {}
2197 virtual void VisitPointers(Object** start, Object** end) {
2198 UNREACHABLE();
2199 }
2200 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {
2201 explorer_->VisitSubtreeWrapper(p, class_id);
2202 }
2203 private:
2204 NativeObjectsExplorer* explorer_;
2205 };
2206
2207 HeapThing const NativeObjectsExplorer::kNativesRootObject =
2208 reinterpret_cast<HeapThing>(
2209 static_cast<intptr_t>(HeapObjectsMap::kNativesRootObjectId));
2210
2211
2212 NativeObjectsExplorer::NativeObjectsExplorer(
2213 HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress)
2214 : snapshot_(snapshot),
2215 collection_(snapshot_->collection()),
2216 progress_(progress),
2217 embedder_queried_(false),
2218 objects_by_info_(RetainedInfosMatch),
2219 filler_(NULL) {
2220 }
2221
2222
2223 NativeObjectsExplorer::~NativeObjectsExplorer() {
2224 for (HashMap::Entry* p = objects_by_info_.Start();
2225 p != NULL;
2226 p = objects_by_info_.Next(p)) {
2227 v8::RetainedObjectInfo* info =
2228 reinterpret_cast<v8::RetainedObjectInfo*>(p->key);
2229 info->Dispose();
2230 List<HeapObject*>* objects =
2231 reinterpret_cast<List<HeapObject*>* >(p->value);
2232 delete objects;
2233 }
2234 }
2235
2236
2237 HeapEntry* NativeObjectsExplorer::AllocateEntry(
2238 HeapThing ptr, int children_count, int retainers_count) {
2239 if (ptr == kNativesRootObject) {
2240 return snapshot_->AddNativesRootEntry(children_count, retainers_count);
2241 } else {
2242 v8::RetainedObjectInfo* info =
2243 reinterpret_cast<v8::RetainedObjectInfo*>(ptr);
2244 intptr_t elements = info->GetElementCount();
2245 intptr_t size = info->GetSizeInBytes();
2246 return snapshot_->AddEntry(
2247 HeapEntry::kNative,
2248 elements != -1 ?
2249 collection_->names()->GetFormatted(
2250 "%s / %" V8_PTR_PREFIX "d entries",
2251 info->GetLabel(),
2252 info->GetElementCount()) :
2253 collection_->names()->GetCopy(info->GetLabel()),
2254 HeapObjectsMap::GenerateId(info),
2255 size != -1 ? static_cast<int>(size) : 0,
2256 children_count,
2257 retainers_count);
2258 }
2259 }
2260
2261
2262 void NativeObjectsExplorer::AddRootEntries(SnapshotFillerInterface* filler) {
2263 if (EstimateObjectsCount() <= 0) return;
2264 filler->AddEntry(kNativesRootObject, this);
2265 }
2266
2267
2268 int NativeObjectsExplorer::EstimateObjectsCount() {
2269 FillRetainedObjects();
2270 return objects_by_info_.occupancy();
2271 }
2272
2273
2274 void NativeObjectsExplorer::FillRetainedObjects() {
2275 if (embedder_queried_) return;
2276 // Record objects that are joined into ObjectGroups.
2277 Heap::CallGlobalGCPrologueCallback();
2278 List<ObjectGroup*>* groups = GlobalHandles::ObjectGroups();
2279 for (int i = 0; i < groups->length(); ++i) {
2280 ObjectGroup* group = groups->at(i);
2281 if (group->info_ == NULL) continue;
2282 List<HeapObject*>* list = GetListMaybeDisposeInfo(group->info_);
2283 for (int j = 0; j < group->objects_.length(); ++j) {
2284 HeapObject* obj = HeapObject::cast(*group->objects_[j]);
2285 list->Add(obj);
2286 in_groups_.Insert(obj);
2287 }
2288 group->info_ = NULL; // Acquire info object ownership.
2289 }
2290 GlobalHandles::RemoveObjectGroups();
2291 Heap::CallGlobalGCEpilogueCallback();
2292 // Record objects that are not in ObjectGroups, but have class ID.
2293 GlobalHandlesExtractor extractor(this);
2294 GlobalHandles::IterateAllRootsWithClassIds(&extractor);
2295 embedder_queried_ = true;
2296 }
2297
2298
2299 List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo(
2300 v8::RetainedObjectInfo* info) {
2301 HashMap::Entry* entry =
2302 objects_by_info_.Lookup(info, InfoHash(info), true);
2303 if (entry->value != NULL) {
2304 info->Dispose();
2305 } else {
2306 entry->value = new List<HeapObject*>(4);
2307 }
2308 return reinterpret_cast<List<HeapObject*>* >(entry->value);
2309 }
2310
2311
2312 bool NativeObjectsExplorer::IterateAndExtractReferences(
2313 SnapshotFillerInterface* filler) {
2314 if (EstimateObjectsCount() <= 0) return true;
2315 filler_ = filler;
2316 FillRetainedObjects();
2317 for (HashMap::Entry* p = objects_by_info_.Start();
2318 p != NULL;
2319 p = objects_by_info_.Next(p)) {
2320 v8::RetainedObjectInfo* info =
2321 reinterpret_cast<v8::RetainedObjectInfo*>(p->key);
2322 SetNativeRootReference(info);
2323 List<HeapObject*>* objects =
2324 reinterpret_cast<List<HeapObject*>* >(p->value);
2325 for (int i = 0; i < objects->length(); ++i) {
2326 SetWrapperNativeReferences(objects->at(i), info);
2327 }
2328 }
2329 SetRootNativesRootReference();
2330 filler_ = NULL;
2331 return true;
2332 }
2333
2334
2335 void NativeObjectsExplorer::SetNativeRootReference(
2336 v8::RetainedObjectInfo* info) {
2337 HeapEntry* child_entry = filler_->FindOrAddEntry(info, this);
2338 ASSERT(child_entry != NULL);
2339 filler_->SetIndexedAutoIndexReference(
2340 HeapGraphEdge::kElement,
2341 kNativesRootObject, snapshot_->dom_subtrees_root(),
2342 info, child_entry);
2343 }
2344
2345
2346 void NativeObjectsExplorer::SetWrapperNativeReferences(
2347 HeapObject* wrapper, v8::RetainedObjectInfo* info) {
2348 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper);
2349 ASSERT(wrapper_entry != NULL);
2350 HeapEntry* info_entry = filler_->FindOrAddEntry(info, this);
2351 ASSERT(info_entry != NULL);
2352 filler_->SetNamedReference(HeapGraphEdge::kInternal,
2353 wrapper, wrapper_entry,
2354 "Native",
2355 info, info_entry);
2356 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement,
2357 info, info_entry,
2358 wrapper, wrapper_entry);
2359 }
2360
2361
2362 void NativeObjectsExplorer::SetRootNativesRootReference() {
2363 filler_->SetIndexedAutoIndexReference(
2364 HeapGraphEdge::kElement,
2365 V8HeapExplorer::kInternalRootObject, snapshot_->root(),
2366 kNativesRootObject, snapshot_->dom_subtrees_root());
2367 }
2368
2369
2370 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) {
2371 if (in_groups_.Contains(*p)) return;
2372 v8::RetainedObjectInfo* info =
2373 HeapProfiler::ExecuteWrapperClassCallback(class_id, p);
2374 if (info == NULL) return;
2375 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p));
2376 }
2377
2378
2135 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot, 2379 HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
2136 v8::ActivityControl* control) 2380 v8::ActivityControl* control)
2137 : snapshot_(snapshot), 2381 : snapshot_(snapshot),
2138 control_(control), 2382 control_(control),
2139 v8_heap_explorer_(snapshot_, this) { 2383 v8_heap_explorer_(snapshot_, this),
2384 dom_explorer_(snapshot_, this) {
2140 } 2385 }
2141 2386
2142 2387
2143 class SnapshotCounter : public SnapshotFillerInterface { 2388 class SnapshotCounter : public SnapshotFillerInterface {
2144 public: 2389 public:
2145 SnapshotCounter(HeapEntriesAllocator* allocator, HeapEntriesMap* entries) 2390 explicit SnapshotCounter(HeapEntriesMap* entries) : entries_(entries) { }
2146 : allocator_(allocator), entries_(entries) { } 2391 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
2147 HeapEntry* AddEntry(HeapThing ptr) { 2392 entries_->Pair(ptr, allocator, HeapEntriesMap::kHeapEntryPlaceholder);
2148 entries_->Pair(ptr, allocator_, HeapEntriesMap::kHeapEntryPlaceholder);
2149 return HeapEntriesMap::kHeapEntryPlaceholder; 2393 return HeapEntriesMap::kHeapEntryPlaceholder;
2150 } 2394 }
2151 HeapEntry* FindOrAddEntry(HeapThing ptr) { 2395 HeapEntry* FindEntry(HeapThing ptr) {
2152 HeapEntry* entry = entries_->Map(ptr); 2396 return entries_->Map(ptr);
2153 return entry != NULL ? entry : AddEntry(ptr); 2397 }
2398 HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
2399 HeapEntry* entry = FindEntry(ptr);
2400 return entry != NULL ? entry : AddEntry(ptr, allocator);
2154 } 2401 }
2155 void SetIndexedReference(HeapGraphEdge::Type, 2402 void SetIndexedReference(HeapGraphEdge::Type,
2156 HeapThing parent_ptr, 2403 HeapThing parent_ptr,
2157 HeapEntry*, 2404 HeapEntry*,
2158 int, 2405 int,
2159 HeapThing child_ptr, 2406 HeapThing child_ptr,
2160 HeapEntry*) { 2407 HeapEntry*) {
2161 entries_->CountReference(parent_ptr, child_ptr); 2408 entries_->CountReference(parent_ptr, child_ptr);
2162 } 2409 }
2163 void SetIndexedAutoIndexReference(HeapGraphEdge::Type, 2410 void SetIndexedAutoIndexReference(HeapGraphEdge::Type,
(...skipping 12 matching lines...) Expand all
2176 entries_->CountReference(parent_ptr, child_ptr); 2423 entries_->CountReference(parent_ptr, child_ptr);
2177 } 2424 }
2178 void SetNamedAutoIndexReference(HeapGraphEdge::Type, 2425 void SetNamedAutoIndexReference(HeapGraphEdge::Type,
2179 HeapThing parent_ptr, 2426 HeapThing parent_ptr,
2180 HeapEntry*, 2427 HeapEntry*,
2181 HeapThing child_ptr, 2428 HeapThing child_ptr,
2182 HeapEntry*) { 2429 HeapEntry*) {
2183 entries_->CountReference(parent_ptr, child_ptr); 2430 entries_->CountReference(parent_ptr, child_ptr);
2184 } 2431 }
2185 private: 2432 private:
2186 HeapEntriesAllocator* allocator_;
2187 HeapEntriesMap* entries_; 2433 HeapEntriesMap* entries_;
2188 }; 2434 };
2189 2435
2190 2436
2191 class SnapshotFiller : public SnapshotFillerInterface { 2437 class SnapshotFiller : public SnapshotFillerInterface {
2192 public: 2438 public:
2193 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) 2439 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
2194 : snapshot_(snapshot), 2440 : snapshot_(snapshot),
2195 collection_(snapshot->collection()), 2441 collection_(snapshot->collection()),
2196 entries_(entries) { } 2442 entries_(entries) { }
2197 HeapEntry* AddEntry(HeapThing ptr) { 2443 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
2198 UNREACHABLE(); 2444 UNREACHABLE();
2199 return NULL; 2445 return NULL;
2200 } 2446 }
2201 HeapEntry* FindOrAddEntry(HeapThing ptr) { 2447 HeapEntry* FindEntry(HeapThing ptr) {
2202 HeapEntry* entry = entries_->Map(ptr); 2448 return entries_->Map(ptr);
2203 return entry != NULL ? entry : AddEntry(ptr); 2449 }
2450 HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
2451 HeapEntry* entry = FindEntry(ptr);
2452 return entry != NULL ? entry : AddEntry(ptr, allocator);
2204 } 2453 }
2205 void SetIndexedReference(HeapGraphEdge::Type type, 2454 void SetIndexedReference(HeapGraphEdge::Type type,
2206 HeapThing parent_ptr, 2455 HeapThing parent_ptr,
2207 HeapEntry* parent_entry, 2456 HeapEntry* parent_entry,
2208 int index, 2457 int index,
2209 HeapThing child_ptr, 2458 HeapThing child_ptr,
2210 HeapEntry* child_entry) { 2459 HeapEntry* child_entry) {
2211 int child_index, retainer_index; 2460 int child_index, retainer_index;
2212 entries_->CountReference( 2461 entries_->CountReference(
2213 parent_ptr, child_ptr, &child_index, &retainer_index); 2462 parent_ptr, child_ptr, &child_index, &retainer_index);
(...skipping 26 matching lines...) Expand all
2240 void SetNamedAutoIndexReference(HeapGraphEdge::Type type, 2489 void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
2241 HeapThing parent_ptr, 2490 HeapThing parent_ptr,
2242 HeapEntry* parent_entry, 2491 HeapEntry* parent_entry,
2243 HeapThing child_ptr, 2492 HeapThing child_ptr,
2244 HeapEntry* child_entry) { 2493 HeapEntry* child_entry) {
2245 int child_index, retainer_index; 2494 int child_index, retainer_index;
2246 entries_->CountReference( 2495 entries_->CountReference(
2247 parent_ptr, child_ptr, &child_index, &retainer_index); 2496 parent_ptr, child_ptr, &child_index, &retainer_index);
2248 parent_entry->SetNamedReference(type, 2497 parent_entry->SetNamedReference(type,
2249 child_index, 2498 child_index,
2250 collection_->GetName(child_index + 1), 2499 collection_->names()->GetName(child_index + 1),
2251 child_entry, 2500 child_entry,
2252 retainer_index); 2501 retainer_index);
2253 } 2502 }
2254 private: 2503 private:
2255 HeapSnapshot* snapshot_; 2504 HeapSnapshot* snapshot_;
2256 HeapSnapshotsCollection* collection_; 2505 HeapSnapshotsCollection* collection_;
2257 HeapEntriesMap* entries_; 2506 HeapEntriesMap* entries_;
2258 }; 2507 };
2259 2508
2260 2509
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 return 2545 return
2297 control_->ReportProgressValue(progress_counter_, progress_total_) == 2546 control_->ReportProgressValue(progress_counter_, progress_total_) ==
2298 v8::ActivityControl::kContinue; 2547 v8::ActivityControl::kContinue;
2299 } 2548 }
2300 return true; 2549 return true;
2301 } 2550 }
2302 2551
2303 2552
2304 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) { 2553 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
2305 if (control_ == NULL) return; 2554 if (control_ == NULL) return;
2306 progress_total_ = v8_heap_explorer_.EstimateObjectsCount() * iterations_count; 2555 progress_total_ = (
2556 v8_heap_explorer_.EstimateObjectsCount() +
2557 dom_explorer_.EstimateObjectsCount()) * iterations_count;
2307 progress_counter_ = 0; 2558 progress_counter_ = 0;
2308 } 2559 }
2309 2560
2310 2561
2311 bool HeapSnapshotGenerator::CountEntriesAndReferences() { 2562 bool HeapSnapshotGenerator::CountEntriesAndReferences() {
2312 SnapshotCounter counter(&v8_heap_explorer_, &entries_); 2563 SnapshotCounter counter(&entries_);
2313 v8_heap_explorer_.AddRootEntries(&counter); 2564 v8_heap_explorer_.AddRootEntries(&counter);
2314 return v8_heap_explorer_.IterateAndExtractReferences(&counter); 2565 dom_explorer_.AddRootEntries(&counter);
2566 return
2567 v8_heap_explorer_.IterateAndExtractReferences(&counter) &&
2568 dom_explorer_.IterateAndExtractReferences(&counter);
2315 } 2569 }
2316 2570
2317 2571
2318 bool HeapSnapshotGenerator::FillReferences() { 2572 bool HeapSnapshotGenerator::FillReferences() {
2319 SnapshotFiller filler(snapshot_, &entries_); 2573 SnapshotFiller filler(snapshot_, &entries_);
2320 return v8_heap_explorer_.IterateAndExtractReferences(&filler); 2574 return
2575 v8_heap_explorer_.IterateAndExtractReferences(&filler) &&
2576 dom_explorer_.IterateAndExtractReferences(&filler);
2321 } 2577 }
2322 2578
2323 2579
2324 void HeapSnapshotGenerator::FillReversePostorderIndexes( 2580 void HeapSnapshotGenerator::FillReversePostorderIndexes(
2325 Vector<HeapEntry*>* entries) { 2581 Vector<HeapEntry*>* entries) {
2326 snapshot_->ClearPaint(); 2582 snapshot_->ClearPaint();
2327 int current_entry = 0; 2583 int current_entry = 0;
2328 List<HeapEntry*> nodes_to_visit; 2584 List<HeapEntry*> nodes_to_visit;
2329 nodes_to_visit.Add(snapshot_->root()); 2585 nodes_to_visit.Add(snapshot_->root());
2330 snapshot_->root()->paint_reachable(); 2586 snapshot_->root()->paint_reachable();
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
2728 "," JSON_S("children")) 2984 "," JSON_S("children"))
2729 "," JSON_S("types") ":" JSON_A( 2985 "," JSON_S("types") ":" JSON_A(
2730 JSON_A( 2986 JSON_A(
2731 JSON_S("hidden") 2987 JSON_S("hidden")
2732 "," JSON_S("array") 2988 "," JSON_S("array")
2733 "," JSON_S("string") 2989 "," JSON_S("string")
2734 "," JSON_S("object") 2990 "," JSON_S("object")
2735 "," JSON_S("code") 2991 "," JSON_S("code")
2736 "," JSON_S("closure") 2992 "," JSON_S("closure")
2737 "," JSON_S("regexp") 2993 "," JSON_S("regexp")
2738 "," JSON_S("number")) 2994 "," JSON_S("number")
2995 "," JSON_S("native"))
2739 "," JSON_S("string") 2996 "," JSON_S("string")
2740 "," JSON_S("number") 2997 "," JSON_S("number")
2741 "," JSON_S("number") 2998 "," JSON_S("number")
2742 "," JSON_S("number") 2999 "," JSON_S("number")
2743 "," JSON_S("number") 3000 "," JSON_S("number")
2744 "," JSON_S("number") 3001 "," JSON_S("number")
2745 "," JSON_O( 3002 "," JSON_O(
2746 JSON_S("fields") ":" JSON_A( 3003 JSON_S("fields") ":" JSON_A(
2747 JSON_S("type") 3004 JSON_S("type")
2748 "," JSON_S("name_or_index") 3005 "," JSON_S("name_or_index")
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2890 3147
2891 3148
2892 String* GetConstructorNameForHeapProfile(JSObject* object) { 3149 String* GetConstructorNameForHeapProfile(JSObject* object) {
2893 if (object->IsJSFunction()) return Heap::closure_symbol(); 3150 if (object->IsJSFunction()) return Heap::closure_symbol();
2894 return object->constructor_name(); 3151 return object->constructor_name();
2895 } 3152 }
2896 3153
2897 } } // namespace v8::internal 3154 } } // namespace v8::internal
2898 3155
2899 #endif // ENABLE_LOGGING_AND_PROFILING 3156 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698