 Chromium Code Reviews
 Chromium Code Reviews Issue 6776009:
  Heap profiler: emit more descriptive names for system objects and properties.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 6776009:
  Heap profiler: emit more descriptive names for system objects and properties.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| 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 |