OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1683 } else if (object->IsScript()) { | 1683 } else if (object->IsScript()) { |
1684 Script* script = Script::cast(object); | 1684 Script* script = Script::cast(object); |
1685 return AddEntry(object, | 1685 return AddEntry(object, |
1686 HeapEntry::kCode, | 1686 HeapEntry::kCode, |
1687 script->name()->IsString() ? | 1687 script->name()->IsString() ? |
1688 collection_->names()->GetName( | 1688 collection_->names()->GetName( |
1689 String::cast(script->name())) | 1689 String::cast(script->name())) |
1690 : "", | 1690 : "", |
1691 children_count, | 1691 children_count, |
1692 retainers_count); | 1692 retainers_count); |
1693 } else if (object->IsFixedArray()) { | 1693 } else if (object->IsFixedArray() || object->IsByteArray()) { |
1694 return AddEntry(object, | 1694 return AddEntry(object, |
1695 HeapEntry::kArray, | 1695 HeapEntry::kArray, |
1696 "", | 1696 "", |
1697 children_count, | 1697 children_count, |
1698 retainers_count); | 1698 retainers_count); |
1699 } else if (object->IsHeapNumber()) { | 1699 } else if (object->IsHeapNumber()) { |
1700 return AddEntry(object, | 1700 return AddEntry(object, |
1701 HeapEntry::kHeapNumber, | 1701 HeapEntry::kHeapNumber, |
1702 "number", | 1702 "number", |
1703 children_count, | 1703 children_count, |
1704 retainers_count); | 1704 retainers_count); |
1705 } | 1705 } |
1706 return AddEntry(object, | 1706 return AddEntry(object, |
1707 HeapEntry::kHidden, | 1707 HeapEntry::kHidden, |
1708 "system", | 1708 GetSystemEntryName(object), |
1709 children_count, | 1709 children_count, |
1710 retainers_count); | 1710 retainers_count); |
1711 } | 1711 } |
1712 | 1712 |
1713 | 1713 |
1714 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, | 1714 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, |
1715 HeapEntry::Type type, | 1715 HeapEntry::Type type, |
1716 const char* name, | 1716 const char* name, |
1717 int children_count, | 1717 int children_count, |
1718 int retainers_count) { | 1718 int retainers_count) { |
1719 return snapshot_->AddEntry(type, | 1719 return snapshot_->AddEntry(type, |
1720 name, | 1720 name, |
1721 collection_->GetObjectId(object->address()), | 1721 collection_->GetObjectId(object->address()), |
1722 object->Size(), | 1722 object->Size(), |
1723 children_count, | 1723 children_count, |
1724 retainers_count); | 1724 retainers_count); |
1725 } | 1725 } |
1726 | 1726 |
1727 | 1727 |
1728 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { | 1728 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { |
1729 filler->AddEntry(kInternalRootObject, this); | 1729 filler->AddEntry(kInternalRootObject, this); |
1730 filler->AddEntry(kGcRootsObject, this); | 1730 filler->AddEntry(kGcRootsObject, this); |
1731 } | 1731 } |
1732 | 1732 |
1733 | 1733 |
1734 const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { | |
1735 switch (object->map()->instance_type()) { | |
1736 case MAP_TYPE: return "system / Map"; | |
1737 case JS_GLOBAL_PROPERTY_CELL_TYPE: return "system / JSGlobalPropertyCell"; | |
1738 case PROXY_TYPE: return "system / Proxy"; | |
1739 case ODDBALL_TYPE: return "system / Oddball"; | |
1740 #define MAKE_STRUCT_CASE(NAME, Name, name) \ | |
1741 case NAME##_TYPE: return "system / "#Name; | |
1742 STRUCT_LIST(MAKE_STRUCT_CASE) | |
1743 #undef MAKE_STRUCT_CASE | |
1744 } | |
1745 return "system"; | |
1746 } | |
1747 | |
1748 | |
1734 int V8HeapExplorer::EstimateObjectsCount() { | 1749 int V8HeapExplorer::EstimateObjectsCount() { |
1735 HeapIterator iterator(HeapIterator::kFilterUnreachable); | 1750 HeapIterator iterator(HeapIterator::kFilterUnreachable); |
1736 int objects_count = 0; | 1751 int objects_count = 0; |
1737 for (HeapObject* obj = iterator.next(); | 1752 for (HeapObject* obj = iterator.next(); |
1738 obj != NULL; | 1753 obj != NULL; |
1739 obj = iterator.next(), ++objects_count) {} | 1754 obj = iterator.next(), ++objects_count) {} |
1740 return objects_count; | 1755 return objects_count; |
1741 } | 1756 } |
1742 | 1757 |
1743 | 1758 |
1744 class IndexedReferencesExtractor : public ObjectVisitor { | 1759 class IndexedReferencesExtractor : public ObjectVisitor { |
1745 public: | 1760 public: |
1746 IndexedReferencesExtractor(V8HeapExplorer* generator, | 1761 IndexedReferencesExtractor(V8HeapExplorer* generator, |
1747 HeapObject* parent_obj, | 1762 HeapObject* parent_obj, |
1748 HeapEntry* parent_entry, | 1763 HeapEntry* parent_entry, |
1749 bool process_field_marks = false) | 1764 bool process_field_marks = true) |
Vitaly Repeshko
2011/03/30 13:26:37
Are there usages left where this parameter is fals
mnaganov (inactive)
2011/03/30 13:45:36
Actually, no. OK, let's remove the conditional.
| |
1750 : generator_(generator), | 1765 : generator_(generator), |
1751 parent_obj_(parent_obj), | 1766 parent_obj_(parent_obj), |
1752 parent_(parent_entry), | 1767 parent_(parent_entry), |
1753 process_field_marks_(process_field_marks), | 1768 process_field_marks_(process_field_marks), |
1754 next_index_(1) { | 1769 next_index_(1) { |
1755 } | 1770 } |
1756 void VisitPointers(Object** start, Object** end) { | 1771 void VisitPointers(Object** start, Object** end) { |
1757 for (Object** p = start; p < end; p++) { | 1772 for (Object** p = start; p < end; p++) { |
1758 if (CheckVisitedAndUnmark(p)) continue; | 1773 if (CheckVisitedAndUnmark(p)) continue; |
1759 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p); | 1774 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p); |
(...skipping 27 matching lines...) Expand all Loading... | |
1787 void V8HeapExplorer::ExtractReferences(HeapObject* obj) { | 1802 void V8HeapExplorer::ExtractReferences(HeapObject* obj) { |
1788 HeapEntry* entry = GetEntry(obj); | 1803 HeapEntry* entry = GetEntry(obj); |
1789 if (entry == NULL) return; // No interest in this object. | 1804 if (entry == NULL) return; // No interest in this object. |
1790 | 1805 |
1791 if (obj->IsJSGlobalProxy()) { | 1806 if (obj->IsJSGlobalProxy()) { |
1792 // We need to reference JS global objects from snapshot's root. | 1807 // We need to reference JS global objects from snapshot's root. |
1793 // We use JSGlobalProxy because this is what embedder (e.g. browser) | 1808 // We use JSGlobalProxy because this is what embedder (e.g. browser) |
1794 // uses for the global object. | 1809 // uses for the global object. |
1795 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj); | 1810 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj); |
1796 SetRootShortcutReference(proxy->map()->prototype()); | 1811 SetRootShortcutReference(proxy->map()->prototype()); |
1812 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | |
1797 IndexedReferencesExtractor refs_extractor(this, obj, entry); | 1813 IndexedReferencesExtractor refs_extractor(this, obj, entry); |
1798 obj->Iterate(&refs_extractor); | 1814 obj->Iterate(&refs_extractor); |
1799 } else if (obj->IsJSObject()) { | 1815 } else if (obj->IsJSObject()) { |
1800 JSObject* js_obj = JSObject::cast(obj); | 1816 JSObject* js_obj = JSObject::cast(obj); |
1801 ExtractClosureReferences(js_obj, entry); | 1817 ExtractClosureReferences(js_obj, entry); |
1802 ExtractPropertyReferences(js_obj, entry); | 1818 ExtractPropertyReferences(js_obj, entry); |
1803 ExtractElementReferences(js_obj, entry); | 1819 ExtractElementReferences(js_obj, entry); |
1804 ExtractInternalReferences(js_obj, entry); | 1820 ExtractInternalReferences(js_obj, entry); |
1805 SetPropertyReference( | 1821 SetPropertyReference( |
1806 obj, entry, HEAP->Proto_symbol(), js_obj->GetPrototype()); | 1822 obj, entry, HEAP->Proto_symbol(), js_obj->GetPrototype()); |
1807 if (obj->IsJSFunction()) { | 1823 if (obj->IsJSFunction()) { |
1808 JSFunction* js_fun = JSFunction::cast(js_obj); | 1824 JSFunction* js_fun = JSFunction::cast(js_obj); |
1809 SetInternalReference( | |
1810 js_fun, entry, | |
1811 "code", js_fun->shared(), | |
1812 JSFunction::kSharedFunctionInfoOffset); | |
1813 Object* proto_or_map = js_fun->prototype_or_initial_map(); | 1825 Object* proto_or_map = js_fun->prototype_or_initial_map(); |
1814 if (!proto_or_map->IsTheHole()) { | 1826 if (!proto_or_map->IsTheHole()) { |
1815 if (!proto_or_map->IsMap()) { | 1827 if (!proto_or_map->IsMap()) { |
1816 SetPropertyReference( | 1828 SetPropertyReference( |
1817 obj, entry, | 1829 obj, entry, |
1818 HEAP->prototype_symbol(), proto_or_map, | 1830 HEAP->prototype_symbol(), proto_or_map, |
1819 JSFunction::kPrototypeOrInitialMapOffset); | 1831 JSFunction::kPrototypeOrInitialMapOffset); |
1820 } else { | 1832 } else { |
1821 SetPropertyReference( | 1833 SetPropertyReference( |
1822 obj, entry, | 1834 obj, entry, |
1823 HEAP->prototype_symbol(), js_fun->prototype()); | 1835 HEAP->prototype_symbol(), js_fun->prototype()); |
1824 } | 1836 } |
1825 } | 1837 } |
1838 SetInternalReference(js_fun, entry, | |
1839 "shared", js_fun->shared(), | |
1840 JSFunction::kSharedFunctionInfoOffset); | |
1841 SetInternalReference(js_fun, entry, | |
1842 "context", js_fun->unchecked_context(), | |
1843 JSFunction::kContextOffset); | |
1844 SetInternalReference(js_fun, entry, | |
1845 "literals", js_fun->literals(), | |
1846 JSFunction::kLiteralsOffset); | |
1826 } | 1847 } |
1827 IndexedReferencesExtractor refs_extractor(this, obj, entry, true); | 1848 SetInternalReference(obj, entry, |
1849 "properties", js_obj->properties(), | |
1850 JSObject::kPropertiesOffset); | |
1851 SetInternalReference(obj, entry, | |
1852 "elements", js_obj->elements(), | |
1853 JSObject::kElementsOffset); | |
1854 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | |
1855 IndexedReferencesExtractor refs_extractor(this, obj, entry); | |
1828 obj->Iterate(&refs_extractor); | 1856 obj->Iterate(&refs_extractor); |
1829 } else if (obj->IsString()) { | 1857 } else if (obj->IsString()) { |
1830 if (obj->IsConsString()) { | 1858 if (obj->IsConsString()) { |
1831 ConsString* cs = ConsString::cast(obj); | 1859 ConsString* cs = ConsString::cast(obj); |
1832 SetInternalReference(obj, entry, 1, cs->first()); | 1860 SetInternalReference(obj, entry, 1, cs->first()); |
1833 SetInternalReference(obj, entry, 2, cs->second()); | 1861 SetInternalReference(obj, entry, 2, cs->second()); |
1834 } | 1862 } |
1863 } else if (obj->IsMap()) { | |
1864 Map* map = Map::cast(obj); | |
1865 SetInternalReference(obj, entry, | |
1866 "prototype", map->prototype(), Map::kPrototypeOffset); | |
1867 SetInternalReference(obj, entry, | |
1868 "constructor", map->constructor(), | |
1869 Map::kConstructorOffset); | |
1870 SetInternalReference(obj, entry, | |
1871 "descriptors", map->instance_descriptors(), | |
1872 Map::kInstanceDescriptorsOffset); | |
1873 SetInternalReference(obj, entry, | |
1874 "code_cache", map->code_cache(), | |
1875 Map::kCodeCacheOffset); | |
1876 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | |
1877 IndexedReferencesExtractor refs_extractor(this, obj, entry); | |
1878 obj->Iterate(&refs_extractor); | |
1879 } else if (obj->IsSharedFunctionInfo()) { | |
1880 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | |
1881 SetInternalReference(obj, entry, | |
1882 "name", shared->name(), | |
1883 SharedFunctionInfo::kNameOffset); | |
1884 SetInternalReference(obj, entry, | |
1885 "code", shared->unchecked_code(), | |
1886 SharedFunctionInfo::kCodeOffset); | |
1887 SetInternalReference(obj, entry, | |
1888 "instance_class_name", shared->instance_class_name(), | |
1889 SharedFunctionInfo::kInstanceClassNameOffset); | |
1890 SetInternalReference(obj, entry, | |
1891 "script", shared->script(), | |
1892 SharedFunctionInfo::kScriptOffset); | |
1893 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | |
1894 IndexedReferencesExtractor refs_extractor(this, obj, entry); | |
1895 obj->Iterate(&refs_extractor); | |
1835 } else { | 1896 } else { |
1897 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | |
1836 IndexedReferencesExtractor refs_extractor(this, obj, entry); | 1898 IndexedReferencesExtractor refs_extractor(this, obj, entry); |
1837 obj->Iterate(&refs_extractor); | 1899 obj->Iterate(&refs_extractor); |
1838 } | 1900 } |
1839 } | 1901 } |
1840 | 1902 |
1841 | 1903 |
1842 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, | 1904 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, |
1843 HeapEntry* entry) { | 1905 HeapEntry* entry) { |
1844 if (js_obj->IsJSFunction()) { | 1906 if (js_obj->IsJSFunction()) { |
1845 HandleScope hs; | 1907 HandleScope hs; |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2300 | 2362 |
2301 | 2363 |
2302 void NativeObjectsExplorer::SetWrapperNativeReferences( | 2364 void NativeObjectsExplorer::SetWrapperNativeReferences( |
2303 HeapObject* wrapper, v8::RetainedObjectInfo* info) { | 2365 HeapObject* wrapper, v8::RetainedObjectInfo* info) { |
2304 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper); | 2366 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper); |
2305 ASSERT(wrapper_entry != NULL); | 2367 ASSERT(wrapper_entry != NULL); |
2306 HeapEntry* info_entry = filler_->FindOrAddEntry(info, this); | 2368 HeapEntry* info_entry = filler_->FindOrAddEntry(info, this); |
2307 ASSERT(info_entry != NULL); | 2369 ASSERT(info_entry != NULL); |
2308 filler_->SetNamedReference(HeapGraphEdge::kInternal, | 2370 filler_->SetNamedReference(HeapGraphEdge::kInternal, |
2309 wrapper, wrapper_entry, | 2371 wrapper, wrapper_entry, |
2310 "Native", | 2372 "native", |
2311 info, info_entry); | 2373 info, info_entry); |
2312 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, | 2374 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, |
2313 info, info_entry, | 2375 info, info_entry, |
2314 wrapper, wrapper_entry); | 2376 wrapper, wrapper_entry); |
2315 } | 2377 } |
2316 | 2378 |
2317 | 2379 |
2318 void NativeObjectsExplorer::SetRootNativesRootReference() { | 2380 void NativeObjectsExplorer::SetRootNativesRootReference() { |
2319 filler_->SetIndexedAutoIndexReference( | 2381 filler_->SetIndexedAutoIndexReference( |
2320 HeapGraphEdge::kElement, | 2382 HeapGraphEdge::kElement, |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3027 | 3089 |
3028 | 3090 |
3029 String* GetConstructorNameForHeapProfile(JSObject* object) { | 3091 String* GetConstructorNameForHeapProfile(JSObject* object) { |
3030 if (object->IsJSFunction()) return HEAP->closure_symbol(); | 3092 if (object->IsJSFunction()) return HEAP->closure_symbol(); |
3031 return object->constructor_name(); | 3093 return object->constructor_name(); |
3032 } | 3094 } |
3033 | 3095 |
3034 } } // namespace v8::internal | 3096 } } // namespace v8::internal |
3035 | 3097 |
3036 #endif // ENABLE_LOGGING_AND_PROFILING | 3098 #endif // ENABLE_LOGGING_AND_PROFILING |
OLD | NEW |