Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: src/profile-generator.cc

Issue 6776009: Heap profiler: emit more descriptive names for system objects and properties. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments addressed, compilation fixed Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/profile-generator.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 default: return "system";
1745 }
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)
1750 : generator_(generator), 1764 : generator_(generator),
1751 parent_obj_(parent_obj), 1765 parent_obj_(parent_obj),
1752 parent_(parent_entry), 1766 parent_(parent_entry),
1753 process_field_marks_(process_field_marks),
1754 next_index_(1) { 1767 next_index_(1) {
1755 } 1768 }
1756 void VisitPointers(Object** start, Object** end) { 1769 void VisitPointers(Object** start, Object** end) {
1757 for (Object** p = start; p < end; p++) { 1770 for (Object** p = start; p < end; p++) {
1758 if (CheckVisitedAndUnmark(p)) continue; 1771 if (CheckVisitedAndUnmark(p)) continue;
1759 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p); 1772 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p);
1760 } 1773 }
1761 } 1774 }
1762 static void MarkVisitedField(HeapObject* obj, int offset) { 1775 static void MarkVisitedField(HeapObject* obj, int offset) {
1763 if (offset < 0) return; 1776 if (offset < 0) return;
1764 Address field = obj->address() + offset; 1777 Address field = obj->address() + offset;
1765 ASSERT(!Memory::Object_at(field)->IsFailure()); 1778 ASSERT(!Memory::Object_at(field)->IsFailure());
1766 ASSERT(Memory::Object_at(field)->IsHeapObject()); 1779 ASSERT(Memory::Object_at(field)->IsHeapObject());
1767 *field |= kFailureTag; 1780 *field |= kFailureTag;
1768 } 1781 }
1769 private: 1782 private:
1770 bool CheckVisitedAndUnmark(Object** field) { 1783 bool CheckVisitedAndUnmark(Object** field) {
1771 if (process_field_marks_ && (*field)->IsFailure()) { 1784 if ((*field)->IsFailure()) {
1772 intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask; 1785 intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask;
1773 *field = reinterpret_cast<Object*>(untagged | kHeapObjectTag); 1786 *field = reinterpret_cast<Object*>(untagged | kHeapObjectTag);
1774 ASSERT((*field)->IsHeapObject()); 1787 ASSERT((*field)->IsHeapObject());
1775 return true; 1788 return true;
1776 } 1789 }
1777 return false; 1790 return false;
1778 } 1791 }
1779 V8HeapExplorer* generator_; 1792 V8HeapExplorer* generator_;
1780 HeapObject* parent_obj_; 1793 HeapObject* parent_obj_;
1781 HeapEntry* parent_; 1794 HeapEntry* parent_;
1782 bool process_field_marks_;
1783 int next_index_; 1795 int next_index_;
1784 }; 1796 };
1785 1797
1786 1798
1787 void V8HeapExplorer::ExtractReferences(HeapObject* obj) { 1799 void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
1788 HeapEntry* entry = GetEntry(obj); 1800 HeapEntry* entry = GetEntry(obj);
1789 if (entry == NULL) return; // No interest in this object. 1801 if (entry == NULL) return; // No interest in this object.
1790 1802
1791 if (obj->IsJSGlobalProxy()) { 1803 if (obj->IsJSGlobalProxy()) {
1792 // We need to reference JS global objects from snapshot's root. 1804 // We need to reference JS global objects from snapshot's root.
1793 // We use JSGlobalProxy because this is what embedder (e.g. browser) 1805 // We use JSGlobalProxy because this is what embedder (e.g. browser)
1794 // uses for the global object. 1806 // uses for the global object.
1795 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj); 1807 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj);
1796 SetRootShortcutReference(proxy->map()->prototype()); 1808 SetRootShortcutReference(proxy->map()->prototype());
1809 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1797 IndexedReferencesExtractor refs_extractor(this, obj, entry); 1810 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1798 obj->Iterate(&refs_extractor); 1811 obj->Iterate(&refs_extractor);
1799 } else if (obj->IsJSObject()) { 1812 } else if (obj->IsJSObject()) {
1800 JSObject* js_obj = JSObject::cast(obj); 1813 JSObject* js_obj = JSObject::cast(obj);
1801 ExtractClosureReferences(js_obj, entry); 1814 ExtractClosureReferences(js_obj, entry);
1802 ExtractPropertyReferences(js_obj, entry); 1815 ExtractPropertyReferences(js_obj, entry);
1803 ExtractElementReferences(js_obj, entry); 1816 ExtractElementReferences(js_obj, entry);
1804 ExtractInternalReferences(js_obj, entry); 1817 ExtractInternalReferences(js_obj, entry);
1805 SetPropertyReference( 1818 SetPropertyReference(
1806 obj, entry, HEAP->Proto_symbol(), js_obj->GetPrototype()); 1819 obj, entry, HEAP->Proto_symbol(), js_obj->GetPrototype());
1807 if (obj->IsJSFunction()) { 1820 if (obj->IsJSFunction()) {
1808 JSFunction* js_fun = JSFunction::cast(js_obj); 1821 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(); 1822 Object* proto_or_map = js_fun->prototype_or_initial_map();
1814 if (!proto_or_map->IsTheHole()) { 1823 if (!proto_or_map->IsTheHole()) {
1815 if (!proto_or_map->IsMap()) { 1824 if (!proto_or_map->IsMap()) {
1816 SetPropertyReference( 1825 SetPropertyReference(
1817 obj, entry, 1826 obj, entry,
1818 HEAP->prototype_symbol(), proto_or_map, 1827 HEAP->prototype_symbol(), proto_or_map,
1819 JSFunction::kPrototypeOrInitialMapOffset); 1828 JSFunction::kPrototypeOrInitialMapOffset);
1820 } else { 1829 } else {
1821 SetPropertyReference( 1830 SetPropertyReference(
1822 obj, entry, 1831 obj, entry,
1823 HEAP->prototype_symbol(), js_fun->prototype()); 1832 HEAP->prototype_symbol(), js_fun->prototype());
1824 } 1833 }
1825 } 1834 }
1835 SetInternalReference(js_fun, entry,
1836 "shared", js_fun->shared(),
1837 JSFunction::kSharedFunctionInfoOffset);
1838 SetInternalReference(js_fun, entry,
1839 "context", js_fun->unchecked_context(),
1840 JSFunction::kContextOffset);
1841 SetInternalReference(js_fun, entry,
1842 "literals", js_fun->literals(),
1843 JSFunction::kLiteralsOffset);
1826 } 1844 }
1827 IndexedReferencesExtractor refs_extractor(this, obj, entry, true); 1845 SetInternalReference(obj, entry,
1846 "properties", js_obj->properties(),
1847 JSObject::kPropertiesOffset);
1848 SetInternalReference(obj, entry,
1849 "elements", js_obj->elements(),
1850 JSObject::kElementsOffset);
1851 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1852 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1828 obj->Iterate(&refs_extractor); 1853 obj->Iterate(&refs_extractor);
1829 } else if (obj->IsString()) { 1854 } else if (obj->IsString()) {
1830 if (obj->IsConsString()) { 1855 if (obj->IsConsString()) {
1831 ConsString* cs = ConsString::cast(obj); 1856 ConsString* cs = ConsString::cast(obj);
1832 SetInternalReference(obj, entry, 1, cs->first()); 1857 SetInternalReference(obj, entry, 1, cs->first());
1833 SetInternalReference(obj, entry, 2, cs->second()); 1858 SetInternalReference(obj, entry, 2, cs->second());
1834 } 1859 }
1860 } else if (obj->IsMap()) {
1861 Map* map = Map::cast(obj);
1862 SetInternalReference(obj, entry,
1863 "prototype", map->prototype(), Map::kPrototypeOffset);
1864 SetInternalReference(obj, entry,
1865 "constructor", map->constructor(),
1866 Map::kConstructorOffset);
1867 SetInternalReference(obj, entry,
1868 "descriptors", map->instance_descriptors(),
1869 Map::kInstanceDescriptorsOffset);
1870 SetInternalReference(obj, entry,
1871 "code_cache", map->code_cache(),
1872 Map::kCodeCacheOffset);
1873 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1874 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1875 obj->Iterate(&refs_extractor);
1876 } else if (obj->IsSharedFunctionInfo()) {
1877 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
1878 SetInternalReference(obj, entry,
1879 "name", shared->name(),
1880 SharedFunctionInfo::kNameOffset);
1881 SetInternalReference(obj, entry,
1882 "code", shared->unchecked_code(),
1883 SharedFunctionInfo::kCodeOffset);
1884 SetInternalReference(obj, entry,
1885 "instance_class_name", shared->instance_class_name(),
1886 SharedFunctionInfo::kInstanceClassNameOffset);
1887 SetInternalReference(obj, entry,
1888 "script", shared->script(),
1889 SharedFunctionInfo::kScriptOffset);
1890 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1891 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1892 obj->Iterate(&refs_extractor);
1835 } else { 1893 } else {
1894 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1836 IndexedReferencesExtractor refs_extractor(this, obj, entry); 1895 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1837 obj->Iterate(&refs_extractor); 1896 obj->Iterate(&refs_extractor);
1838 } 1897 }
1839 } 1898 }
1840 1899
1841 1900
1842 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, 1901 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
1843 HeapEntry* entry) { 1902 HeapEntry* entry) {
1844 if (js_obj->IsJSFunction()) { 1903 if (js_obj->IsJSFunction()) {
1845 HandleScope hs; 1904 HandleScope hs;
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
2300 2359
2301 2360
2302 void NativeObjectsExplorer::SetWrapperNativeReferences( 2361 void NativeObjectsExplorer::SetWrapperNativeReferences(
2303 HeapObject* wrapper, v8::RetainedObjectInfo* info) { 2362 HeapObject* wrapper, v8::RetainedObjectInfo* info) {
2304 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper); 2363 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper);
2305 ASSERT(wrapper_entry != NULL); 2364 ASSERT(wrapper_entry != NULL);
2306 HeapEntry* info_entry = filler_->FindOrAddEntry(info, this); 2365 HeapEntry* info_entry = filler_->FindOrAddEntry(info, this);
2307 ASSERT(info_entry != NULL); 2366 ASSERT(info_entry != NULL);
2308 filler_->SetNamedReference(HeapGraphEdge::kInternal, 2367 filler_->SetNamedReference(HeapGraphEdge::kInternal,
2309 wrapper, wrapper_entry, 2368 wrapper, wrapper_entry,
2310 "Native", 2369 "native",
2311 info, info_entry); 2370 info, info_entry);
2312 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, 2371 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement,
2313 info, info_entry, 2372 info, info_entry,
2314 wrapper, wrapper_entry); 2373 wrapper, wrapper_entry);
2315 } 2374 }
2316 2375
2317 2376
2318 void NativeObjectsExplorer::SetRootNativesRootReference() { 2377 void NativeObjectsExplorer::SetRootNativesRootReference() {
2319 filler_->SetIndexedAutoIndexReference( 2378 filler_->SetIndexedAutoIndexReference(
2320 HeapGraphEdge::kElement, 2379 HeapGraphEdge::kElement,
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
3027 3086
3028 3087
3029 String* GetConstructorNameForHeapProfile(JSObject* object) { 3088 String* GetConstructorNameForHeapProfile(JSObject* object) {
3030 if (object->IsJSFunction()) return HEAP->closure_symbol(); 3089 if (object->IsJSFunction()) return HEAP->closure_symbol();
3031 return object->constructor_name(); 3090 return object->constructor_name();
3032 } 3091 }
3033 3092
3034 } } // namespace v8::internal 3093 } } // namespace v8::internal
3035 3094
3036 #endif // ENABLE_LOGGING_AND_PROFILING 3095 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698