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...) 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 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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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 |
OLD | NEW |