Chromium Code Reviews

Side by Side Diff: src/heap-snapshot-generator.cc

Issue 213673006: Show references from weak containers as weak in heap snapshots. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« no previous file with comments | « src/heap-snapshot-generator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1083 matching lines...)
1094 } 1094 }
1095 return false; 1095 return false;
1096 } 1096 }
1097 V8HeapExplorer* generator_; 1097 V8HeapExplorer* generator_;
1098 HeapObject* parent_obj_; 1098 HeapObject* parent_obj_;
1099 int parent_; 1099 int parent_;
1100 int next_index_; 1100 int next_index_;
1101 }; 1101 };
1102 1102
1103 1103
1104 void V8HeapExplorer::ExtractReferences(HeapObject* obj) { 1104 void V8HeapExplorer::ExtractReferencesPass1(HeapObject* obj) {
1105 if (obj->IsFixedArray()) return; // FixedArrays are processed on pass 2.
1106
1105 HeapEntry* heap_entry = GetEntry(obj); 1107 HeapEntry* heap_entry = GetEntry(obj);
1106 if (heap_entry == NULL) return; // No interest in this object. 1108 if (heap_entry == NULL) return; // No interest in this object.
1107 int entry = heap_entry->index(); 1109 int entry = heap_entry->index();
1108 1110
1109 if (obj->IsJSGlobalProxy()) { 1111 if (obj->IsJSGlobalProxy()) {
1110 ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj)); 1112 ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj));
1111 } else if (obj->IsJSArrayBuffer()) { 1113 } else if (obj->IsJSArrayBuffer()) {
1112 ExtractJSArrayBufferReferences(entry, JSArrayBuffer::cast(obj)); 1114 ExtractJSArrayBufferReferences(entry, JSArrayBuffer::cast(obj));
1113 } else if (obj->IsJSObject()) { 1115 } else if (obj->IsJSObject()) {
1114 ExtractJSObjectReferences(entry, JSObject::cast(obj)); 1116 ExtractJSObjectReferences(entry, JSObject::cast(obj));
1115 } else if (obj->IsString()) { 1117 } else if (obj->IsString()) {
1116 ExtractStringReferences(entry, String::cast(obj)); 1118 ExtractStringReferences(entry, String::cast(obj));
1117 } else if (obj->IsContext()) {
1118 ExtractContextReferences(entry, Context::cast(obj));
1119 } else if (obj->IsMap()) { 1119 } else if (obj->IsMap()) {
1120 ExtractMapReferences(entry, Map::cast(obj)); 1120 ExtractMapReferences(entry, Map::cast(obj));
1121 } else if (obj->IsSharedFunctionInfo()) { 1121 } else if (obj->IsSharedFunctionInfo()) {
1122 ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj)); 1122 ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj));
1123 } else if (obj->IsScript()) { 1123 } else if (obj->IsScript()) {
1124 ExtractScriptReferences(entry, Script::cast(obj)); 1124 ExtractScriptReferences(entry, Script::cast(obj));
1125 } else if (obj->IsAccessorPair()) { 1125 } else if (obj->IsAccessorPair()) {
1126 ExtractAccessorPairReferences(entry, AccessorPair::cast(obj)); 1126 ExtractAccessorPairReferences(entry, AccessorPair::cast(obj));
1127 } else if (obj->IsCodeCache()) { 1127 } else if (obj->IsCodeCache()) {
1128 ExtractCodeCacheReferences(entry, CodeCache::cast(obj)); 1128 ExtractCodeCacheReferences(entry, CodeCache::cast(obj));
(...skipping 10 matching lines...)
1139 } 1139 }
1140 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); 1140 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1141 1141
1142 // Extract unvisited fields as hidden references and restore tags 1142 // Extract unvisited fields as hidden references and restore tags
1143 // of visited fields. 1143 // of visited fields.
1144 IndexedReferencesExtractor refs_extractor(this, obj, entry); 1144 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1145 obj->Iterate(&refs_extractor); 1145 obj->Iterate(&refs_extractor);
1146 } 1146 }
1147 1147
1148 1148
1149 void V8HeapExplorer::ExtractReferencesPass2(HeapObject* obj) {
1150 if (!obj->IsFixedArray()) return;
1151
1152 HeapEntry* heap_entry = GetEntry(obj);
yurys 2014/04/01 15:51:55 Consider extracting common prologue and epilogue o
alph 2014/04/01 16:30:03 Done.
1153 if (heap_entry == NULL) return; // No interest in this object.
1154 int entry = heap_entry->index();
1155
1156 if (obj->IsContext()) {
1157 ExtractContextReferences(entry, Context::cast(obj));
1158 } else {
1159 ExtractFixedArrayReferences(entry, FixedArray::cast(obj));
1160 }
1161
1162 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1163
1164 // Extract unvisited fields as hidden references and restore tags
1165 // of visited fields.
1166 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1167 obj->Iterate(&refs_extractor);
1168 }
1169
1170
1149 void V8HeapExplorer::ExtractJSGlobalProxyReferences( 1171 void V8HeapExplorer::ExtractJSGlobalProxyReferences(
1150 int entry, JSGlobalProxy* proxy) { 1172 int entry, JSGlobalProxy* proxy) {
1151 SetInternalReference(proxy, entry, 1173 SetInternalReference(proxy, entry,
1152 "native_context", proxy->native_context(), 1174 "native_context", proxy->native_context(),
1153 JSGlobalProxy::kNativeContextOffset); 1175 JSGlobalProxy::kNativeContextOffset);
1154 } 1176 }
1155 1177
1156 1178
1157 void V8HeapExplorer::ExtractJSObjectReferences( 1179 void V8HeapExplorer::ExtractJSObjectReferences(
1158 int entry, JSObject* js_obj) { 1180 int entry, JSObject* js_obj) {
(...skipping 154 matching lines...)
1313 1335
1314 void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) { 1336 void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
1315 if (map->HasTransitionArray()) { 1337 if (map->HasTransitionArray()) {
1316 TransitionArray* transitions = map->transitions(); 1338 TransitionArray* transitions = map->transitions();
1317 int transitions_entry = GetEntry(transitions)->index(); 1339 int transitions_entry = GetEntry(transitions)->index();
1318 Object* back_pointer = transitions->back_pointer_storage(); 1340 Object* back_pointer = transitions->back_pointer_storage();
1319 TagObject(back_pointer, "(back pointer)"); 1341 TagObject(back_pointer, "(back pointer)");
1320 SetInternalReference(transitions, transitions_entry, 1342 SetInternalReference(transitions, transitions_entry,
1321 "back_pointer", back_pointer); 1343 "back_pointer", back_pointer);
1322 TagObject(transitions, "(transition array)"); 1344 TagObject(transitions, "(transition array)");
1345 MarkAsWeakContainer(transitions);
1323 SetInternalReference(map, entry, 1346 SetInternalReference(map, entry,
1324 "transitions", transitions, 1347 "transitions", transitions,
1325 Map::kTransitionsOrBackPointerOffset); 1348 Map::kTransitionsOrBackPointerOffset);
1326 } else { 1349 } else {
1327 Object* back_pointer = map->GetBackPointer(); 1350 Object* back_pointer = map->GetBackPointer();
1328 TagObject(back_pointer, "(back pointer)"); 1351 TagObject(back_pointer, "(back pointer)");
1329 SetInternalReference(map, entry, 1352 SetInternalReference(map, entry,
1330 "back_pointer", back_pointer, 1353 "back_pointer", back_pointer,
1331 Map::kTransitionsOrBackPointerOffset); 1354 Map::kTransitionsOrBackPointerOffset);
1332 } 1355 }
1333 DescriptorArray* descriptors = map->instance_descriptors(); 1356 DescriptorArray* descriptors = map->instance_descriptors();
1334 TagObject(descriptors, "(map descriptors)"); 1357 TagObject(descriptors, "(map descriptors)");
1335 SetInternalReference(map, entry, 1358 SetInternalReference(map, entry,
1336 "descriptors", descriptors, 1359 "descriptors", descriptors,
1337 Map::kDescriptorsOffset); 1360 Map::kDescriptorsOffset);
1338 1361
1362 MarkAsWeakContainer(map->code_cache());
1339 SetInternalReference(map, entry, 1363 SetInternalReference(map, entry,
1340 "code_cache", map->code_cache(), 1364 "code_cache", map->code_cache(),
1341 Map::kCodeCacheOffset); 1365 Map::kCodeCacheOffset);
1342 SetInternalReference(map, entry, 1366 SetInternalReference(map, entry,
1343 "prototype", map->prototype(), Map::kPrototypeOffset); 1367 "prototype", map->prototype(), Map::kPrototypeOffset);
1344 SetInternalReference(map, entry, 1368 SetInternalReference(map, entry,
1345 "constructor", map->constructor(), 1369 "constructor", map->constructor(),
1346 Map::kConstructorOffset); 1370 Map::kConstructorOffset);
1347 TagObject(map->dependent_code(), "(dependent code)"); 1371 TagObject(map->dependent_code(), "(dependent code)");
1372 MarkAsWeakContainer(map->dependent_code());
1348 SetInternalReference(map, entry, 1373 SetInternalReference(map, entry,
1349 "dependent_code", map->dependent_code(), 1374 "dependent_code", map->dependent_code(),
1350 Map::kDependentCodeOffset); 1375 Map::kDependentCodeOffset);
1351 } 1376 }
1352 1377
1353 1378
1354 void V8HeapExplorer::ExtractSharedFunctionInfoReferences( 1379 void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
1355 int entry, SharedFunctionInfo* shared) { 1380 int entry, SharedFunctionInfo* shared) {
1356 HeapObject* obj = shared; 1381 HeapObject* obj = shared;
1357 String* shared_name = shared->DebugName(); 1382 String* shared_name = shared->DebugName();
(...skipping 141 matching lines...)
1499 void V8HeapExplorer::ExtractCellReferences(int entry, Cell* cell) { 1524 void V8HeapExplorer::ExtractCellReferences(int entry, Cell* cell) {
1500 SetInternalReference(cell, entry, "value", cell->value(), Cell::kValueOffset); 1525 SetInternalReference(cell, entry, "value", cell->value(), Cell::kValueOffset);
1501 } 1526 }
1502 1527
1503 1528
1504 void V8HeapExplorer::ExtractPropertyCellReferences(int entry, 1529 void V8HeapExplorer::ExtractPropertyCellReferences(int entry,
1505 PropertyCell* cell) { 1530 PropertyCell* cell) {
1506 ExtractCellReferences(entry, cell); 1531 ExtractCellReferences(entry, cell);
1507 SetInternalReference(cell, entry, "type", cell->type(), 1532 SetInternalReference(cell, entry, "type", cell->type(),
1508 PropertyCell::kTypeOffset); 1533 PropertyCell::kTypeOffset);
1534 MarkAsWeakContainer(cell->dependent_code());
1509 SetInternalReference(cell, entry, "dependent_code", cell->dependent_code(), 1535 SetInternalReference(cell, entry, "dependent_code", cell->dependent_code(),
1510 PropertyCell::kDependentCodeOffset); 1536 PropertyCell::kDependentCodeOffset);
1511 } 1537 }
1512 1538
1513 1539
1514 void V8HeapExplorer::ExtractAllocationSiteReferences(int entry, 1540 void V8HeapExplorer::ExtractAllocationSiteReferences(int entry,
1515 AllocationSite* site) { 1541 AllocationSite* site) {
1516 SetInternalReference(site, entry, "transition_info", site->transition_info(), 1542 SetInternalReference(site, entry, "transition_info", site->transition_info(),
1517 AllocationSite::kTransitionInfoOffset); 1543 AllocationSite::kTransitionInfoOffset);
1518 SetInternalReference(site, entry, "nested_site", site->nested_site(), 1544 SetInternalReference(site, entry, "nested_site", site->nested_site(),
1519 AllocationSite::kNestedSiteOffset); 1545 AllocationSite::kNestedSiteOffset);
1546 MarkAsWeakContainer(site->dependent_code());
1520 SetInternalReference(site, entry, "dependent_code", site->dependent_code(), 1547 SetInternalReference(site, entry, "dependent_code", site->dependent_code(),
1521 AllocationSite::kDependentCodeOffset); 1548 AllocationSite::kDependentCodeOffset);
1522 // Do not visit weak_next as it is not visited by the StaticVisitor, 1549 // Do not visit weak_next as it is not visited by the StaticVisitor,
1523 // and we're not very interested in weak_next field here. 1550 // and we're not very interested in weak_next field here.
1524 STATIC_CHECK(AllocationSite::kWeakNextOffset >= 1551 STATIC_CHECK(AllocationSite::kWeakNextOffset >=
1525 AllocationSite::BodyDescriptor::kEndOffset); 1552 AllocationSite::BodyDescriptor::kEndOffset);
1526 } 1553 }
1527 1554
1528 1555
1529 class JSArrayBufferDataEntryAllocator : public HeapEntriesAllocator { 1556 class JSArrayBufferDataEntryAllocator : public HeapEntriesAllocator {
(...skipping 25 matching lines...)
1555 return; 1582 return;
1556 size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length()); 1583 size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length());
1557 JSArrayBufferDataEntryAllocator allocator(data_size, this); 1584 JSArrayBufferDataEntryAllocator allocator(data_size, this);
1558 HeapEntry* data_entry = 1585 HeapEntry* data_entry =
1559 filler_->FindOrAddEntry(buffer->backing_store(), &allocator); 1586 filler_->FindOrAddEntry(buffer->backing_store(), &allocator);
1560 filler_->SetNamedReference(HeapGraphEdge::kInternal, 1587 filler_->SetNamedReference(HeapGraphEdge::kInternal,
1561 entry, "backing_store", data_entry); 1588 entry, "backing_store", data_entry);
1562 } 1589 }
1563 1590
1564 1591
1592 void V8HeapExplorer::ExtractFixedArrayReferences(int entry, FixedArray* array) {
1593 bool is_weak = weak_containers_.Contains(array);
1594 for (int i = 0, l = array->length(); i < l; ++i) {
1595 if (is_weak) {
1596 SetWeakReference(array, entry,
1597 i, array->get(i), array->OffsetOfElementAt(i));
1598 } else {
1599 SetInternalReference(array, entry,
1600 i, array->get(i), array->OffsetOfElementAt(i));
1601 }
1602 }
1603 }
1604
1605
1565 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) { 1606 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) {
1566 if (!js_obj->IsJSFunction()) return; 1607 if (!js_obj->IsJSFunction()) return;
1567 1608
1568 JSFunction* func = JSFunction::cast(js_obj); 1609 JSFunction* func = JSFunction::cast(js_obj);
1569 if (func->shared()->bound()) { 1610 if (func->shared()->bound()) {
1570 FixedArray* bindings = func->function_bindings(); 1611 FixedArray* bindings = func->function_bindings();
1571 SetNativeBindReference(js_obj, entry, "bound_this", 1612 SetNativeBindReference(js_obj, entry, "bound_this",
1572 bindings->get(JSFunction::kBoundThisIndex)); 1613 bindings->get(JSFunction::kBoundThisIndex));
1573 SetNativeBindReference(js_obj, entry, "bound_function", 1614 SetNativeBindReference(js_obj, entry, "bound_function",
1574 bindings->get(JSFunction::kBoundFunctionIndex)); 1615 bindings->get(JSFunction::kBoundFunctionIndex));
(...skipping 251 matching lines...)
1826 // Make sure builtin code objects get their builtin tags 1867 // Make sure builtin code objects get their builtin tags
1827 // first. Otherwise a particular JSFunction object could set 1868 // first. Otherwise a particular JSFunction object could set
1828 // its custom name to a generic builtin. 1869 // its custom name to a generic builtin.
1829 SetRootGcRootsReference(); 1870 SetRootGcRootsReference();
1830 RootsReferencesExtractor extractor(heap_); 1871 RootsReferencesExtractor extractor(heap_);
1831 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); 1872 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG);
1832 extractor.SetCollectingAllReferences(); 1873 extractor.SetCollectingAllReferences();
1833 heap_->IterateRoots(&extractor, VISIT_ALL); 1874 heap_->IterateRoots(&extractor, VISIT_ALL);
1834 extractor.FillReferences(this); 1875 extractor.FillReferences(this);
1835 1876
1877 // We have to do two passes as sometimes FixedArrays are used
1878 // to weakly hold their items, and it's impossible to distinguish
1879 // between these cases without processing the array owner first.
1880 bool interrupted =
1881 IterateAndExtractSinglePass<&V8HeapExplorer::ExtractReferencesPass1>() ||
1882 IterateAndExtractSinglePass<&V8HeapExplorer::ExtractReferencesPass2>();
1883
1884 if (interrupted) {
1885 filler_ = NULL;
1886 return false;
1887 }
1888
1889 filler_ = NULL;
1890 return progress_->ProgressReport(true);
1891 }
1892
1893
1894 template<V8HeapExplorer::ExtractReferencesMethod extractor>
1895 bool V8HeapExplorer::IterateAndExtractSinglePass() {
1836 // Now iterate the whole heap. 1896 // Now iterate the whole heap.
1837 bool interrupted = false; 1897 bool interrupted = false;
1838 HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable); 1898 HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable);
1839 // Heap iteration with filtering must be finished in any case. 1899 // Heap iteration with filtering must be finished in any case.
1840 for (HeapObject* obj = iterator.next(); 1900 for (HeapObject* obj = iterator.next();
1841 obj != NULL; 1901 obj != NULL;
1842 obj = iterator.next(), progress_->ProgressStep()) { 1902 obj = iterator.next(), progress_->ProgressStep()) {
1843 if (!interrupted) { 1903 if (interrupted) continue;
1844 ExtractReferences(obj); 1904 (this->*extractor)(obj);
1845 if (!progress_->ProgressReport(false)) interrupted = true; 1905 if (!progress_->ProgressReport(false)) interrupted = true;
1846 }
1847 } 1906 }
1848 if (interrupted) { 1907 return interrupted;
1849 filler_ = NULL;
1850 return false;
1851 }
1852
1853 filler_ = NULL;
1854 return progress_->ProgressReport(true);
1855 } 1908 }
1856 1909
1857 1910
1858 bool V8HeapExplorer::IsEssentialObject(Object* object) { 1911 bool V8HeapExplorer::IsEssentialObject(Object* object) {
1859 return object->IsHeapObject() 1912 return object->IsHeapObject()
1860 && !object->IsOddball() 1913 && !object->IsOddball()
1861 && object != heap_->empty_byte_array() 1914 && object != heap_->empty_byte_array()
1862 && object != heap_->empty_fixed_array() 1915 && object != heap_->empty_fixed_array()
1863 && object != heap_->empty_descriptor_array() 1916 && object != heap_->empty_descriptor_array()
1864 && object != heap_->fixed_array_map() 1917 && object != heap_->fixed_array_map()
(...skipping 115 matching lines...)
1980 if (IsEssentialObject(child_obj)) { 2033 if (IsEssentialObject(child_obj)) {
1981 filler_->SetNamedReference(HeapGraphEdge::kWeak, 2034 filler_->SetNamedReference(HeapGraphEdge::kWeak,
1982 parent_entry, 2035 parent_entry,
1983 reference_name, 2036 reference_name,
1984 child_entry); 2037 child_entry);
1985 } 2038 }
1986 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 2039 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
1987 } 2040 }
1988 2041
1989 2042
2043 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
2044 int parent_entry,
2045 int index,
2046 Object* child_obj,
2047 int field_offset) {
2048 ASSERT(parent_entry == GetEntry(parent_obj)->index());
2049 HeapEntry* child_entry = GetEntry(child_obj);
2050 if (child_entry == NULL) return;
2051 if (IsEssentialObject(child_obj)) {
2052 filler_->SetNamedReference(HeapGraphEdge::kWeak,
2053 parent_entry,
2054 names_->GetFormatted("%d", index),
2055 child_entry);
2056 }
2057 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
2058 }
2059
2060
1990 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, 2061 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
1991 int parent_entry, 2062 int parent_entry,
1992 Name* reference_name, 2063 Name* reference_name,
1993 Object* child_obj, 2064 Object* child_obj,
1994 const char* name_format_string, 2065 const char* name_format_string,
1995 int field_offset) { 2066 int field_offset) {
1996 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 2067 ASSERT(parent_entry == GetEntry(parent_obj)->index());
1997 HeapEntry* child_entry = GetEntry(child_obj); 2068 HeapEntry* child_entry = GetEntry(child_obj);
1998 if (child_entry != NULL) { 2069 if (child_entry != NULL) {
1999 HeapGraphEdge::Type type = 2070 HeapGraphEdge::Type type =
(...skipping 107 matching lines...)
2107 void V8HeapExplorer::TagObject(Object* obj, const char* tag) { 2178 void V8HeapExplorer::TagObject(Object* obj, const char* tag) {
2108 if (IsEssentialObject(obj)) { 2179 if (IsEssentialObject(obj)) {
2109 HeapEntry* entry = GetEntry(obj); 2180 HeapEntry* entry = GetEntry(obj);
2110 if (entry->name()[0] == '\0') { 2181 if (entry->name()[0] == '\0') {
2111 entry->set_name(tag); 2182 entry->set_name(tag);
2112 } 2183 }
2113 } 2184 }
2114 } 2185 }
2115 2186
2116 2187
2188 void V8HeapExplorer::MarkAsWeakContainer(Object* object) {
2189 if (IsEssentialObject(object)) {
yurys 2014/04/01 15:51:55 Can you add an assert that the object passed in is
alph 2014/04/01 16:30:03 Done.
2190 weak_containers_.Insert(object);
2191 }
2192 }
2193
2194
2117 class GlobalObjectsEnumerator : public ObjectVisitor { 2195 class GlobalObjectsEnumerator : public ObjectVisitor {
2118 public: 2196 public:
2119 virtual void VisitPointers(Object** start, Object** end) { 2197 virtual void VisitPointers(Object** start, Object** end) {
2120 for (Object** p = start; p < end; p++) { 2198 for (Object** p = start; p < end; p++) {
2121 if ((*p)->IsNativeContext()) { 2199 if ((*p)->IsNativeContext()) {
2122 Context* context = Context::cast(*p); 2200 Context* context = Context::cast(*p);
2123 JSObject* proxy = context->global_proxy(); 2201 JSObject* proxy = context->global_proxy();
2124 if (proxy->IsJSGlobalProxy()) { 2202 if (proxy->IsJSGlobalProxy()) {
2125 Object* global = proxy->map()->prototype(); 2203 Object* global = proxy->map()->prototype();
2126 if (global->IsJSGlobalObject()) { 2204 if (global->IsJSGlobalObject()) {
(...skipping 370 matching lines...)
2497 #endif 2575 #endif
2498 2576
2499 // The following code uses heap iterators, so we want the heap to be 2577 // The following code uses heap iterators, so we want the heap to be
2500 // stable. It should follow TagGlobalObjects as that can allocate. 2578 // stable. It should follow TagGlobalObjects as that can allocate.
2501 DisallowHeapAllocation no_alloc; 2579 DisallowHeapAllocation no_alloc;
2502 2580
2503 #ifdef VERIFY_HEAP 2581 #ifdef VERIFY_HEAP
2504 debug_heap->Verify(); 2582 debug_heap->Verify();
2505 #endif 2583 #endif
2506 2584
2507 SetProgressTotal(1); // 1 pass. 2585 SetProgressTotal(2); // 2 passes.
2508 2586
2509 #ifdef VERIFY_HEAP 2587 #ifdef VERIFY_HEAP
2510 debug_heap->Verify(); 2588 debug_heap->Verify();
2511 #endif 2589 #endif
2512 2590
2513 if (!FillReferences()) return false; 2591 if (!FillReferences()) return false;
2514 2592
2515 snapshot_->FillChildren(); 2593 snapshot_->FillChildren();
2516 snapshot_->RememberLastJSObjectId(); 2594 snapshot_->RememberLastJSObjectId();
2517 2595
(...skipping 558 matching lines...)
3076 writer_->AddString("\"<dummy>\""); 3154 writer_->AddString("\"<dummy>\"");
3077 for (int i = 1; i < sorted_strings.length(); ++i) { 3155 for (int i = 1; i < sorted_strings.length(); ++i) {
3078 writer_->AddCharacter(','); 3156 writer_->AddCharacter(',');
3079 SerializeString(sorted_strings[i]); 3157 SerializeString(sorted_strings[i]);
3080 if (writer_->aborted()) return; 3158 if (writer_->aborted()) return;
3081 } 3159 }
3082 } 3160 }
3083 3161
3084 3162
3085 } } // namespace v8::internal 3163 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap-snapshot-generator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine