OLD | NEW |
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...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 bool V8HeapExplorer::ExtractReferencesPass1(int entry, HeapObject* obj) { |
1105 HeapEntry* heap_entry = GetEntry(obj); | 1105 if (obj->IsFixedArray()) return false; // FixedArrays are processed on pass 2 |
1106 if (heap_entry == NULL) return; // No interest in this object. | |
1107 int entry = heap_entry->index(); | |
1108 | 1106 |
1109 if (obj->IsJSGlobalProxy()) { | 1107 if (obj->IsJSGlobalProxy()) { |
1110 ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj)); | 1108 ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj)); |
1111 } else if (obj->IsJSArrayBuffer()) { | 1109 } else if (obj->IsJSArrayBuffer()) { |
1112 ExtractJSArrayBufferReferences(entry, JSArrayBuffer::cast(obj)); | 1110 ExtractJSArrayBufferReferences(entry, JSArrayBuffer::cast(obj)); |
1113 } else if (obj->IsJSObject()) { | 1111 } else if (obj->IsJSObject()) { |
1114 ExtractJSObjectReferences(entry, JSObject::cast(obj)); | 1112 ExtractJSObjectReferences(entry, JSObject::cast(obj)); |
1115 } else if (obj->IsString()) { | 1113 } else if (obj->IsString()) { |
1116 ExtractStringReferences(entry, String::cast(obj)); | 1114 ExtractStringReferences(entry, String::cast(obj)); |
1117 } else if (obj->IsContext()) { | |
1118 ExtractContextReferences(entry, Context::cast(obj)); | |
1119 } else if (obj->IsMap()) { | 1115 } else if (obj->IsMap()) { |
1120 ExtractMapReferences(entry, Map::cast(obj)); | 1116 ExtractMapReferences(entry, Map::cast(obj)); |
1121 } else if (obj->IsSharedFunctionInfo()) { | 1117 } else if (obj->IsSharedFunctionInfo()) { |
1122 ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj)); | 1118 ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj)); |
1123 } else if (obj->IsScript()) { | 1119 } else if (obj->IsScript()) { |
1124 ExtractScriptReferences(entry, Script::cast(obj)); | 1120 ExtractScriptReferences(entry, Script::cast(obj)); |
1125 } else if (obj->IsAccessorPair()) { | 1121 } else if (obj->IsAccessorPair()) { |
1126 ExtractAccessorPairReferences(entry, AccessorPair::cast(obj)); | 1122 ExtractAccessorPairReferences(entry, AccessorPair::cast(obj)); |
1127 } else if (obj->IsCodeCache()) { | 1123 } else if (obj->IsCodeCache()) { |
1128 ExtractCodeCacheReferences(entry, CodeCache::cast(obj)); | 1124 ExtractCodeCacheReferences(entry, CodeCache::cast(obj)); |
1129 } else if (obj->IsCode()) { | 1125 } else if (obj->IsCode()) { |
1130 ExtractCodeReferences(entry, Code::cast(obj)); | 1126 ExtractCodeReferences(entry, Code::cast(obj)); |
1131 } else if (obj->IsBox()) { | 1127 } else if (obj->IsBox()) { |
1132 ExtractBoxReferences(entry, Box::cast(obj)); | 1128 ExtractBoxReferences(entry, Box::cast(obj)); |
1133 } else if (obj->IsCell()) { | 1129 } else if (obj->IsCell()) { |
1134 ExtractCellReferences(entry, Cell::cast(obj)); | 1130 ExtractCellReferences(entry, Cell::cast(obj)); |
1135 } else if (obj->IsPropertyCell()) { | 1131 } else if (obj->IsPropertyCell()) { |
1136 ExtractPropertyCellReferences(entry, PropertyCell::cast(obj)); | 1132 ExtractPropertyCellReferences(entry, PropertyCell::cast(obj)); |
1137 } else if (obj->IsAllocationSite()) { | 1133 } else if (obj->IsAllocationSite()) { |
1138 ExtractAllocationSiteReferences(entry, AllocationSite::cast(obj)); | 1134 ExtractAllocationSiteReferences(entry, AllocationSite::cast(obj)); |
1139 } | 1135 } |
1140 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | 1136 return true; |
1141 | |
1142 // Extract unvisited fields as hidden references and restore tags | |
1143 // of visited fields. | |
1144 IndexedReferencesExtractor refs_extractor(this, obj, entry); | |
1145 obj->Iterate(&refs_extractor); | |
1146 } | 1137 } |
1147 | 1138 |
1148 | 1139 |
| 1140 bool V8HeapExplorer::ExtractReferencesPass2(int entry, HeapObject* obj) { |
| 1141 if (!obj->IsFixedArray()) return false; |
| 1142 |
| 1143 if (obj->IsContext()) { |
| 1144 ExtractContextReferences(entry, Context::cast(obj)); |
| 1145 } else { |
| 1146 ExtractFixedArrayReferences(entry, FixedArray::cast(obj)); |
| 1147 } |
| 1148 return true; |
| 1149 } |
| 1150 |
| 1151 |
1149 void V8HeapExplorer::ExtractJSGlobalProxyReferences( | 1152 void V8HeapExplorer::ExtractJSGlobalProxyReferences( |
1150 int entry, JSGlobalProxy* proxy) { | 1153 int entry, JSGlobalProxy* proxy) { |
1151 SetInternalReference(proxy, entry, | 1154 SetInternalReference(proxy, entry, |
1152 "native_context", proxy->native_context(), | 1155 "native_context", proxy->native_context(), |
1153 JSGlobalProxy::kNativeContextOffset); | 1156 JSGlobalProxy::kNativeContextOffset); |
1154 } | 1157 } |
1155 | 1158 |
1156 | 1159 |
1157 void V8HeapExplorer::ExtractJSObjectReferences( | 1160 void V8HeapExplorer::ExtractJSObjectReferences( |
1158 int entry, JSObject* js_obj) { | 1161 int entry, JSObject* js_obj) { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 | 1316 |
1314 void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) { | 1317 void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) { |
1315 if (map->HasTransitionArray()) { | 1318 if (map->HasTransitionArray()) { |
1316 TransitionArray* transitions = map->transitions(); | 1319 TransitionArray* transitions = map->transitions(); |
1317 int transitions_entry = GetEntry(transitions)->index(); | 1320 int transitions_entry = GetEntry(transitions)->index(); |
1318 Object* back_pointer = transitions->back_pointer_storage(); | 1321 Object* back_pointer = transitions->back_pointer_storage(); |
1319 TagObject(back_pointer, "(back pointer)"); | 1322 TagObject(back_pointer, "(back pointer)"); |
1320 SetInternalReference(transitions, transitions_entry, | 1323 SetInternalReference(transitions, transitions_entry, |
1321 "back_pointer", back_pointer); | 1324 "back_pointer", back_pointer); |
1322 TagObject(transitions, "(transition array)"); | 1325 TagObject(transitions, "(transition array)"); |
| 1326 MarkAsWeakContainer(transitions); |
1323 SetInternalReference(map, entry, | 1327 SetInternalReference(map, entry, |
1324 "transitions", transitions, | 1328 "transitions", transitions, |
1325 Map::kTransitionsOrBackPointerOffset); | 1329 Map::kTransitionsOrBackPointerOffset); |
1326 } else { | 1330 } else { |
1327 Object* back_pointer = map->GetBackPointer(); | 1331 Object* back_pointer = map->GetBackPointer(); |
1328 TagObject(back_pointer, "(back pointer)"); | 1332 TagObject(back_pointer, "(back pointer)"); |
1329 SetInternalReference(map, entry, | 1333 SetInternalReference(map, entry, |
1330 "back_pointer", back_pointer, | 1334 "back_pointer", back_pointer, |
1331 Map::kTransitionsOrBackPointerOffset); | 1335 Map::kTransitionsOrBackPointerOffset); |
1332 } | 1336 } |
1333 DescriptorArray* descriptors = map->instance_descriptors(); | 1337 DescriptorArray* descriptors = map->instance_descriptors(); |
1334 TagObject(descriptors, "(map descriptors)"); | 1338 TagObject(descriptors, "(map descriptors)"); |
1335 SetInternalReference(map, entry, | 1339 SetInternalReference(map, entry, |
1336 "descriptors", descriptors, | 1340 "descriptors", descriptors, |
1337 Map::kDescriptorsOffset); | 1341 Map::kDescriptorsOffset); |
1338 | 1342 |
| 1343 MarkAsWeakContainer(map->code_cache()); |
1339 SetInternalReference(map, entry, | 1344 SetInternalReference(map, entry, |
1340 "code_cache", map->code_cache(), | 1345 "code_cache", map->code_cache(), |
1341 Map::kCodeCacheOffset); | 1346 Map::kCodeCacheOffset); |
1342 SetInternalReference(map, entry, | 1347 SetInternalReference(map, entry, |
1343 "prototype", map->prototype(), Map::kPrototypeOffset); | 1348 "prototype", map->prototype(), Map::kPrototypeOffset); |
1344 SetInternalReference(map, entry, | 1349 SetInternalReference(map, entry, |
1345 "constructor", map->constructor(), | 1350 "constructor", map->constructor(), |
1346 Map::kConstructorOffset); | 1351 Map::kConstructorOffset); |
1347 TagObject(map->dependent_code(), "(dependent code)"); | 1352 TagObject(map->dependent_code(), "(dependent code)"); |
| 1353 MarkAsWeakContainer(map->dependent_code()); |
1348 SetInternalReference(map, entry, | 1354 SetInternalReference(map, entry, |
1349 "dependent_code", map->dependent_code(), | 1355 "dependent_code", map->dependent_code(), |
1350 Map::kDependentCodeOffset); | 1356 Map::kDependentCodeOffset); |
1351 } | 1357 } |
1352 | 1358 |
1353 | 1359 |
1354 void V8HeapExplorer::ExtractSharedFunctionInfoReferences( | 1360 void V8HeapExplorer::ExtractSharedFunctionInfoReferences( |
1355 int entry, SharedFunctionInfo* shared) { | 1361 int entry, SharedFunctionInfo* shared) { |
1356 HeapObject* obj = shared; | 1362 HeapObject* obj = shared; |
1357 String* shared_name = shared->DebugName(); | 1363 String* shared_name = shared->DebugName(); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 void V8HeapExplorer::ExtractCellReferences(int entry, Cell* cell) { | 1505 void V8HeapExplorer::ExtractCellReferences(int entry, Cell* cell) { |
1500 SetInternalReference(cell, entry, "value", cell->value(), Cell::kValueOffset); | 1506 SetInternalReference(cell, entry, "value", cell->value(), Cell::kValueOffset); |
1501 } | 1507 } |
1502 | 1508 |
1503 | 1509 |
1504 void V8HeapExplorer::ExtractPropertyCellReferences(int entry, | 1510 void V8HeapExplorer::ExtractPropertyCellReferences(int entry, |
1505 PropertyCell* cell) { | 1511 PropertyCell* cell) { |
1506 ExtractCellReferences(entry, cell); | 1512 ExtractCellReferences(entry, cell); |
1507 SetInternalReference(cell, entry, "type", cell->type(), | 1513 SetInternalReference(cell, entry, "type", cell->type(), |
1508 PropertyCell::kTypeOffset); | 1514 PropertyCell::kTypeOffset); |
| 1515 MarkAsWeakContainer(cell->dependent_code()); |
1509 SetInternalReference(cell, entry, "dependent_code", cell->dependent_code(), | 1516 SetInternalReference(cell, entry, "dependent_code", cell->dependent_code(), |
1510 PropertyCell::kDependentCodeOffset); | 1517 PropertyCell::kDependentCodeOffset); |
1511 } | 1518 } |
1512 | 1519 |
1513 | 1520 |
1514 void V8HeapExplorer::ExtractAllocationSiteReferences(int entry, | 1521 void V8HeapExplorer::ExtractAllocationSiteReferences(int entry, |
1515 AllocationSite* site) { | 1522 AllocationSite* site) { |
1516 SetInternalReference(site, entry, "transition_info", site->transition_info(), | 1523 SetInternalReference(site, entry, "transition_info", site->transition_info(), |
1517 AllocationSite::kTransitionInfoOffset); | 1524 AllocationSite::kTransitionInfoOffset); |
1518 SetInternalReference(site, entry, "nested_site", site->nested_site(), | 1525 SetInternalReference(site, entry, "nested_site", site->nested_site(), |
1519 AllocationSite::kNestedSiteOffset); | 1526 AllocationSite::kNestedSiteOffset); |
| 1527 MarkAsWeakContainer(site->dependent_code()); |
1520 SetInternalReference(site, entry, "dependent_code", site->dependent_code(), | 1528 SetInternalReference(site, entry, "dependent_code", site->dependent_code(), |
1521 AllocationSite::kDependentCodeOffset); | 1529 AllocationSite::kDependentCodeOffset); |
1522 // Do not visit weak_next as it is not visited by the StaticVisitor, | 1530 // 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. | 1531 // and we're not very interested in weak_next field here. |
1524 STATIC_CHECK(AllocationSite::kWeakNextOffset >= | 1532 STATIC_CHECK(AllocationSite::kWeakNextOffset >= |
1525 AllocationSite::BodyDescriptor::kEndOffset); | 1533 AllocationSite::BodyDescriptor::kEndOffset); |
1526 } | 1534 } |
1527 | 1535 |
1528 | 1536 |
1529 class JSArrayBufferDataEntryAllocator : public HeapEntriesAllocator { | 1537 class JSArrayBufferDataEntryAllocator : public HeapEntriesAllocator { |
(...skipping 25 matching lines...) Expand all Loading... |
1555 return; | 1563 return; |
1556 size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length()); | 1564 size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length()); |
1557 JSArrayBufferDataEntryAllocator allocator(data_size, this); | 1565 JSArrayBufferDataEntryAllocator allocator(data_size, this); |
1558 HeapEntry* data_entry = | 1566 HeapEntry* data_entry = |
1559 filler_->FindOrAddEntry(buffer->backing_store(), &allocator); | 1567 filler_->FindOrAddEntry(buffer->backing_store(), &allocator); |
1560 filler_->SetNamedReference(HeapGraphEdge::kInternal, | 1568 filler_->SetNamedReference(HeapGraphEdge::kInternal, |
1561 entry, "backing_store", data_entry); | 1569 entry, "backing_store", data_entry); |
1562 } | 1570 } |
1563 | 1571 |
1564 | 1572 |
| 1573 void V8HeapExplorer::ExtractFixedArrayReferences(int entry, FixedArray* array) { |
| 1574 bool is_weak = weak_containers_.Contains(array); |
| 1575 for (int i = 0, l = array->length(); i < l; ++i) { |
| 1576 if (is_weak) { |
| 1577 SetWeakReference(array, entry, |
| 1578 i, array->get(i), array->OffsetOfElementAt(i)); |
| 1579 } else { |
| 1580 SetInternalReference(array, entry, |
| 1581 i, array->get(i), array->OffsetOfElementAt(i)); |
| 1582 } |
| 1583 } |
| 1584 } |
| 1585 |
| 1586 |
1565 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) { | 1587 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) { |
1566 if (!js_obj->IsJSFunction()) return; | 1588 if (!js_obj->IsJSFunction()) return; |
1567 | 1589 |
1568 JSFunction* func = JSFunction::cast(js_obj); | 1590 JSFunction* func = JSFunction::cast(js_obj); |
1569 if (func->shared()->bound()) { | 1591 if (func->shared()->bound()) { |
1570 FixedArray* bindings = func->function_bindings(); | 1592 FixedArray* bindings = func->function_bindings(); |
1571 SetNativeBindReference(js_obj, entry, "bound_this", | 1593 SetNativeBindReference(js_obj, entry, "bound_this", |
1572 bindings->get(JSFunction::kBoundThisIndex)); | 1594 bindings->get(JSFunction::kBoundThisIndex)); |
1573 SetNativeBindReference(js_obj, entry, "bound_function", | 1595 SetNativeBindReference(js_obj, entry, "bound_function", |
1574 bindings->get(JSFunction::kBoundFunctionIndex)); | 1596 bindings->get(JSFunction::kBoundFunctionIndex)); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1826 // Make sure builtin code objects get their builtin tags | 1848 // Make sure builtin code objects get their builtin tags |
1827 // first. Otherwise a particular JSFunction object could set | 1849 // first. Otherwise a particular JSFunction object could set |
1828 // its custom name to a generic builtin. | 1850 // its custom name to a generic builtin. |
1829 SetRootGcRootsReference(); | 1851 SetRootGcRootsReference(); |
1830 RootsReferencesExtractor extractor(heap_); | 1852 RootsReferencesExtractor extractor(heap_); |
1831 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); | 1853 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); |
1832 extractor.SetCollectingAllReferences(); | 1854 extractor.SetCollectingAllReferences(); |
1833 heap_->IterateRoots(&extractor, VISIT_ALL); | 1855 heap_->IterateRoots(&extractor, VISIT_ALL); |
1834 extractor.FillReferences(this); | 1856 extractor.FillReferences(this); |
1835 | 1857 |
| 1858 // We have to do two passes as sometimes FixedArrays are used |
| 1859 // to weakly hold their items, and it's impossible to distinguish |
| 1860 // between these cases without processing the array owner first. |
| 1861 bool interrupted = |
| 1862 IterateAndExtractSinglePass<&V8HeapExplorer::ExtractReferencesPass1>() || |
| 1863 IterateAndExtractSinglePass<&V8HeapExplorer::ExtractReferencesPass2>(); |
| 1864 |
| 1865 if (interrupted) { |
| 1866 filler_ = NULL; |
| 1867 return false; |
| 1868 } |
| 1869 |
| 1870 filler_ = NULL; |
| 1871 return progress_->ProgressReport(true); |
| 1872 } |
| 1873 |
| 1874 |
| 1875 template<V8HeapExplorer::ExtractReferencesMethod extractor> |
| 1876 bool V8HeapExplorer::IterateAndExtractSinglePass() { |
1836 // Now iterate the whole heap. | 1877 // Now iterate the whole heap. |
1837 bool interrupted = false; | 1878 bool interrupted = false; |
1838 HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable); | 1879 HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable); |
1839 // Heap iteration with filtering must be finished in any case. | 1880 // Heap iteration with filtering must be finished in any case. |
1840 for (HeapObject* obj = iterator.next(); | 1881 for (HeapObject* obj = iterator.next(); |
1841 obj != NULL; | 1882 obj != NULL; |
1842 obj = iterator.next(), progress_->ProgressStep()) { | 1883 obj = iterator.next(), progress_->ProgressStep()) { |
1843 if (!interrupted) { | 1884 if (interrupted) continue; |
1844 ExtractReferences(obj); | 1885 |
1845 if (!progress_->ProgressReport(false)) interrupted = true; | 1886 HeapEntry* heap_entry = GetEntry(obj); |
| 1887 int entry = heap_entry->index(); |
| 1888 if ((this->*extractor)(entry, obj)) { |
| 1889 SetInternalReference(obj, entry, |
| 1890 "map", obj->map(), HeapObject::kMapOffset); |
| 1891 // Extract unvisited fields as hidden references and restore tags |
| 1892 // of visited fields. |
| 1893 IndexedReferencesExtractor refs_extractor(this, obj, entry); |
| 1894 obj->Iterate(&refs_extractor); |
1846 } | 1895 } |
| 1896 |
| 1897 if (!progress_->ProgressReport(false)) interrupted = true; |
1847 } | 1898 } |
1848 if (interrupted) { | 1899 return interrupted; |
1849 filler_ = NULL; | |
1850 return false; | |
1851 } | |
1852 | |
1853 filler_ = NULL; | |
1854 return progress_->ProgressReport(true); | |
1855 } | 1900 } |
1856 | 1901 |
1857 | 1902 |
1858 bool V8HeapExplorer::IsEssentialObject(Object* object) { | 1903 bool V8HeapExplorer::IsEssentialObject(Object* object) { |
1859 return object->IsHeapObject() | 1904 return object->IsHeapObject() |
1860 && !object->IsOddball() | 1905 && !object->IsOddball() |
1861 && object != heap_->empty_byte_array() | 1906 && object != heap_->empty_byte_array() |
1862 && object != heap_->empty_fixed_array() | 1907 && object != heap_->empty_fixed_array() |
1863 && object != heap_->empty_descriptor_array() | 1908 && object != heap_->empty_descriptor_array() |
1864 && object != heap_->fixed_array_map() | 1909 && object != heap_->fixed_array_map() |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1980 if (IsEssentialObject(child_obj)) { | 2025 if (IsEssentialObject(child_obj)) { |
1981 filler_->SetNamedReference(HeapGraphEdge::kWeak, | 2026 filler_->SetNamedReference(HeapGraphEdge::kWeak, |
1982 parent_entry, | 2027 parent_entry, |
1983 reference_name, | 2028 reference_name, |
1984 child_entry); | 2029 child_entry); |
1985 } | 2030 } |
1986 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); | 2031 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); |
1987 } | 2032 } |
1988 | 2033 |
1989 | 2034 |
| 2035 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj, |
| 2036 int parent_entry, |
| 2037 int index, |
| 2038 Object* child_obj, |
| 2039 int field_offset) { |
| 2040 ASSERT(parent_entry == GetEntry(parent_obj)->index()); |
| 2041 HeapEntry* child_entry = GetEntry(child_obj); |
| 2042 if (child_entry == NULL) return; |
| 2043 if (IsEssentialObject(child_obj)) { |
| 2044 filler_->SetNamedReference(HeapGraphEdge::kWeak, |
| 2045 parent_entry, |
| 2046 names_->GetFormatted("%d", index), |
| 2047 child_entry); |
| 2048 } |
| 2049 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); |
| 2050 } |
| 2051 |
| 2052 |
1990 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, | 2053 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, |
1991 int parent_entry, | 2054 int parent_entry, |
1992 Name* reference_name, | 2055 Name* reference_name, |
1993 Object* child_obj, | 2056 Object* child_obj, |
1994 const char* name_format_string, | 2057 const char* name_format_string, |
1995 int field_offset) { | 2058 int field_offset) { |
1996 ASSERT(parent_entry == GetEntry(parent_obj)->index()); | 2059 ASSERT(parent_entry == GetEntry(parent_obj)->index()); |
1997 HeapEntry* child_entry = GetEntry(child_obj); | 2060 HeapEntry* child_entry = GetEntry(child_obj); |
1998 if (child_entry != NULL) { | 2061 if (child_entry != NULL) { |
1999 HeapGraphEdge::Type type = | 2062 HeapGraphEdge::Type type = |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2107 void V8HeapExplorer::TagObject(Object* obj, const char* tag) { | 2170 void V8HeapExplorer::TagObject(Object* obj, const char* tag) { |
2108 if (IsEssentialObject(obj)) { | 2171 if (IsEssentialObject(obj)) { |
2109 HeapEntry* entry = GetEntry(obj); | 2172 HeapEntry* entry = GetEntry(obj); |
2110 if (entry->name()[0] == '\0') { | 2173 if (entry->name()[0] == '\0') { |
2111 entry->set_name(tag); | 2174 entry->set_name(tag); |
2112 } | 2175 } |
2113 } | 2176 } |
2114 } | 2177 } |
2115 | 2178 |
2116 | 2179 |
| 2180 void V8HeapExplorer::MarkAsWeakContainer(Object* object) { |
| 2181 if (IsEssentialObject(object) && object->IsFixedArray()) { |
| 2182 weak_containers_.Insert(object); |
| 2183 } |
| 2184 } |
| 2185 |
| 2186 |
2117 class GlobalObjectsEnumerator : public ObjectVisitor { | 2187 class GlobalObjectsEnumerator : public ObjectVisitor { |
2118 public: | 2188 public: |
2119 virtual void VisitPointers(Object** start, Object** end) { | 2189 virtual void VisitPointers(Object** start, Object** end) { |
2120 for (Object** p = start; p < end; p++) { | 2190 for (Object** p = start; p < end; p++) { |
2121 if ((*p)->IsNativeContext()) { | 2191 if ((*p)->IsNativeContext()) { |
2122 Context* context = Context::cast(*p); | 2192 Context* context = Context::cast(*p); |
2123 JSObject* proxy = context->global_proxy(); | 2193 JSObject* proxy = context->global_proxy(); |
2124 if (proxy->IsJSGlobalProxy()) { | 2194 if (proxy->IsJSGlobalProxy()) { |
2125 Object* global = proxy->map()->prototype(); | 2195 Object* global = proxy->map()->prototype(); |
2126 if (global->IsJSGlobalObject()) { | 2196 if (global->IsJSGlobalObject()) { |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2497 #endif | 2567 #endif |
2498 | 2568 |
2499 // The following code uses heap iterators, so we want the heap to be | 2569 // The following code uses heap iterators, so we want the heap to be |
2500 // stable. It should follow TagGlobalObjects as that can allocate. | 2570 // stable. It should follow TagGlobalObjects as that can allocate. |
2501 DisallowHeapAllocation no_alloc; | 2571 DisallowHeapAllocation no_alloc; |
2502 | 2572 |
2503 #ifdef VERIFY_HEAP | 2573 #ifdef VERIFY_HEAP |
2504 debug_heap->Verify(); | 2574 debug_heap->Verify(); |
2505 #endif | 2575 #endif |
2506 | 2576 |
2507 SetProgressTotal(1); // 1 pass. | 2577 SetProgressTotal(2); // 2 passes. |
2508 | 2578 |
2509 #ifdef VERIFY_HEAP | 2579 #ifdef VERIFY_HEAP |
2510 debug_heap->Verify(); | 2580 debug_heap->Verify(); |
2511 #endif | 2581 #endif |
2512 | 2582 |
2513 if (!FillReferences()) return false; | 2583 if (!FillReferences()) return false; |
2514 | 2584 |
2515 snapshot_->FillChildren(); | 2585 snapshot_->FillChildren(); |
2516 snapshot_->RememberLastJSObjectId(); | 2586 snapshot_->RememberLastJSObjectId(); |
2517 | 2587 |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3076 writer_->AddString("\"<dummy>\""); | 3146 writer_->AddString("\"<dummy>\""); |
3077 for (int i = 1; i < sorted_strings.length(); ++i) { | 3147 for (int i = 1; i < sorted_strings.length(); ++i) { |
3078 writer_->AddCharacter(','); | 3148 writer_->AddCharacter(','); |
3079 SerializeString(sorted_strings[i]); | 3149 SerializeString(sorted_strings[i]); |
3080 if (writer_->aborted()) return; | 3150 if (writer_->aborted()) return; |
3081 } | 3151 } |
3082 } | 3152 } |
3083 | 3153 |
3084 | 3154 |
3085 } } // namespace v8::internal | 3155 } } // namespace v8::internal |
OLD | NEW |