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

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

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 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') | src/proxy.js » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 + sizeof(HeapGraphEdge*) * retainers_count; // NOLINT 1089 + sizeof(HeapGraphEdge*) * retainers_count; // NOLINT
1090 } 1090 }
1091 1091
1092 1092
1093 class RetainedSizeCalculator { 1093 class RetainedSizeCalculator {
1094 public: 1094 public:
1095 RetainedSizeCalculator() 1095 RetainedSizeCalculator()
1096 : retained_size_(0) { 1096 : retained_size_(0) {
1097 } 1097 }
1098 1098
1099 int reained_size() const { return retained_size_; } 1099 int retained_size() const { return retained_size_; }
1100 1100
1101 void Apply(HeapEntry** entry_ptr) { 1101 void Apply(HeapEntry** entry_ptr) {
1102 if ((*entry_ptr)->painted_reachable()) { 1102 if ((*entry_ptr)->painted_reachable()) {
1103 retained_size_ += (*entry_ptr)->self_size(); 1103 retained_size_ += (*entry_ptr)->self_size();
1104 } 1104 }
1105 } 1105 }
1106 1106
1107 private: 1107 private:
1108 int retained_size_; 1108 int retained_size_;
1109 }; 1109 };
(...skipping 20 matching lines...) Expand all
1130 HeapEntry* child = children[i].to(); 1130 HeapEntry* child = children[i].to();
1131 if (child != this && child->not_painted_reachable_from_others()) { 1131 if (child != this && child->not_painted_reachable_from_others()) {
1132 list.Add(child); 1132 list.Add(child);
1133 child->paint_reachable_from_others(); 1133 child->paint_reachable_from_others();
1134 } 1134 }
1135 } 1135 }
1136 } 1136 }
1137 1137
1138 RetainedSizeCalculator ret_size_calc; 1138 RetainedSizeCalculator ret_size_calc;
1139 snapshot()->IterateEntries(&ret_size_calc); 1139 snapshot()->IterateEntries(&ret_size_calc);
1140 retained_size_ = ret_size_calc.reained_size(); 1140 retained_size_ = ret_size_calc.retained_size();
1141 ASSERT((retained_size_ & kExactRetainedSizeTag) == 0); 1141 ASSERT((retained_size_ & kExactRetainedSizeTag) == 0);
1142 retained_size_ |= kExactRetainedSizeTag; 1142 retained_size_ |= kExactRetainedSizeTag;
1143 } 1143 }
1144 1144
1145 1145
1146 // It is very important to keep objects that form a heap snapshot 1146 // It is very important to keep objects that form a heap snapshot
1147 // as small as possible. 1147 // as small as possible.
1148 namespace { // Avoid littering the global namespace. 1148 namespace { // Avoid littering the global namespace.
1149 1149
1150 template <size_t ptr_size> struct SnapshotSizeConstants; 1150 template <size_t ptr_size> struct SnapshotSizeConstants;
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 if (!obj->IsHeapObject()) return; 1595 if (!obj->IsHeapObject()) return;
1596 HeapObject* object = HeapObject::cast(obj); 1596 HeapObject* object = HeapObject::cast(obj);
1597 HashMap::Entry* cache_entry = 1597 HashMap::Entry* cache_entry =
1598 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); 1598 entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
1599 if (cache_entry->value == NULL) { 1599 if (cache_entry->value == NULL) {
1600 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder; 1600 cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder;
1601 } 1601 }
1602 } 1602 }
1603 1603
1604 1604
1605 const char* HeapObjectsSet::GetTag(Object* obj) {
1606 HeapObject* object = HeapObject::cast(obj);
1607 HashMap::Entry* cache_entry =
1608 entries_.Lookup(object, HeapEntriesMap::Hash(object), false);
1609 if (cache_entry != NULL
1610 && cache_entry->value != HeapEntriesMap::kHeapEntryPlaceholder) {
1611 return reinterpret_cast<const char*>(cache_entry->value);
1612 } else {
1613 return NULL;
1614 }
1615 }
1616
1617
1618 void HeapObjectsSet::SetTag(Object* obj, const char* tag) {
1619 if (!obj->IsHeapObject()) return;
1620 HeapObject* object = HeapObject::cast(obj);
1621 HashMap::Entry* cache_entry =
1622 entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
1623 cache_entry->value = const_cast<char*>(tag);
1624 }
1625
1626
1605 HeapObject *const V8HeapExplorer::kInternalRootObject = 1627 HeapObject *const V8HeapExplorer::kInternalRootObject =
1606 reinterpret_cast<HeapObject*>( 1628 reinterpret_cast<HeapObject*>(
1607 static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId)); 1629 static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId));
1608 HeapObject *const V8HeapExplorer::kGcRootsObject = 1630 HeapObject *const V8HeapExplorer::kGcRootsObject =
1609 reinterpret_cast<HeapObject*>( 1631 reinterpret_cast<HeapObject*>(
1610 static_cast<intptr_t>(HeapObjectsMap::kGcRootsObjectId)); 1632 static_cast<intptr_t>(HeapObjectsMap::kGcRootsObjectId));
1611 1633
1612 1634
1613 V8HeapExplorer::V8HeapExplorer( 1635 V8HeapExplorer::V8HeapExplorer(
1614 HeapSnapshot* snapshot, 1636 HeapSnapshot* snapshot,
1615 SnapshottingProgressReportingInterface* progress) 1637 SnapshottingProgressReportingInterface* progress)
1616 : snapshot_(snapshot), 1638 : heap_(Isolate::Current()->heap()),
1639 snapshot_(snapshot),
1617 collection_(snapshot_->collection()), 1640 collection_(snapshot_->collection()),
1618 progress_(progress), 1641 progress_(progress),
1619 filler_(NULL) { 1642 filler_(NULL) {
1620 } 1643 }
1621 1644
1622 1645
1623 V8HeapExplorer::~V8HeapExplorer() { 1646 V8HeapExplorer::~V8HeapExplorer() {
1624 } 1647 }
1625 1648
1626 1649
1627 HeapEntry* V8HeapExplorer::AllocateEntry( 1650 HeapEntry* V8HeapExplorer::AllocateEntry(
1628 HeapThing ptr, int children_count, int retainers_count) { 1651 HeapThing ptr, int children_count, int retainers_count) {
1629 return AddEntry( 1652 return AddEntry(
1630 reinterpret_cast<HeapObject*>(ptr), children_count, retainers_count); 1653 reinterpret_cast<HeapObject*>(ptr), children_count, retainers_count);
1631 } 1654 }
1632 1655
1633 1656
1634 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, 1657 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
1635 int children_count, 1658 int children_count,
1636 int retainers_count) { 1659 int retainers_count) {
1637 if (object == kInternalRootObject) { 1660 if (object == kInternalRootObject) {
1638 ASSERT(retainers_count == 0); 1661 ASSERT(retainers_count == 0);
1639 return snapshot_->AddRootEntry(children_count); 1662 return snapshot_->AddRootEntry(children_count);
1640 } else if (object == kGcRootsObject) { 1663 } else if (object == kGcRootsObject) {
1641 return snapshot_->AddGcRootsEntry(children_count, retainers_count); 1664 return snapshot_->AddGcRootsEntry(children_count, retainers_count);
1665 } else if (object->IsJSGlobalObject()) {
1666 const char* tag = objects_tags_.GetTag(object);
1667 const char* name = collection_->names()->GetName(
1668 GetConstructorNameForHeapProfile(JSObject::cast(object)));
1669 if (tag != NULL) {
1670 name = collection_->names()->GetFormatted("%s / %s", name, tag);
1671 }
1672 return AddEntry(object,
1673 HeapEntry::kObject,
1674 name,
1675 children_count,
1676 retainers_count);
1642 } else if (object->IsJSFunction()) { 1677 } else if (object->IsJSFunction()) {
1643 JSFunction* func = JSFunction::cast(object); 1678 JSFunction* func = JSFunction::cast(object);
1644 SharedFunctionInfo* shared = func->shared(); 1679 SharedFunctionInfo* shared = func->shared();
1645 return AddEntry(object, 1680 return AddEntry(object,
1646 HeapEntry::kClosure, 1681 HeapEntry::kClosure,
1647 collection_->names()->GetName(String::cast(shared->name())), 1682 collection_->names()->GetName(String::cast(shared->name())),
1648 children_count, 1683 children_count,
1649 retainers_count); 1684 retainers_count);
1650 } else if (object->IsJSRegExp()) { 1685 } else if (object->IsJSRegExp()) {
1651 JSRegExp* re = JSRegExp::cast(object); 1686 JSRegExp* re = JSRegExp::cast(object);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 } else if (object->IsScript()) { 1719 } else if (object->IsScript()) {
1685 Script* script = Script::cast(object); 1720 Script* script = Script::cast(object);
1686 return AddEntry(object, 1721 return AddEntry(object,
1687 HeapEntry::kCode, 1722 HeapEntry::kCode,
1688 script->name()->IsString() ? 1723 script->name()->IsString() ?
1689 collection_->names()->GetName( 1724 collection_->names()->GetName(
1690 String::cast(script->name())) 1725 String::cast(script->name()))
1691 : "", 1726 : "",
1692 children_count, 1727 children_count,
1693 retainers_count); 1728 retainers_count);
1694 } else if (object->IsFixedArray() || object->IsByteArray()) { 1729 } else if (object->IsFixedArray() ||
1730 object->IsFixedDoubleArray() ||
1731 object->IsByteArray() ||
1732 object->IsExternalArray()) {
1733 const char* tag = objects_tags_.GetTag(object);
1695 return AddEntry(object, 1734 return AddEntry(object,
1696 HeapEntry::kArray, 1735 HeapEntry::kArray,
1697 "", 1736 tag != NULL ? tag : "",
1698 children_count, 1737 children_count,
1699 retainers_count); 1738 retainers_count);
1700 } else if (object->IsHeapNumber()) { 1739 } else if (object->IsHeapNumber()) {
1701 return AddEntry(object, 1740 return AddEntry(object,
1702 HeapEntry::kHeapNumber, 1741 HeapEntry::kHeapNumber,
1703 "number", 1742 "number",
1704 children_count, 1743 children_count,
1705 retainers_count); 1744 retainers_count);
1706 } 1745 }
1707 return AddEntry(object, 1746 return AddEntry(object,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p); 1811 generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p);
1773 } 1812 }
1774 } 1813 }
1775 static void MarkVisitedField(HeapObject* obj, int offset) { 1814 static void MarkVisitedField(HeapObject* obj, int offset) {
1776 if (offset < 0) return; 1815 if (offset < 0) return;
1777 Address field = obj->address() + offset; 1816 Address field = obj->address() + offset;
1778 ASSERT(!Memory::Object_at(field)->IsFailure()); 1817 ASSERT(!Memory::Object_at(field)->IsFailure());
1779 ASSERT(Memory::Object_at(field)->IsHeapObject()); 1818 ASSERT(Memory::Object_at(field)->IsHeapObject());
1780 *field |= kFailureTag; 1819 *field |= kFailureTag;
1781 } 1820 }
1821
1782 private: 1822 private:
1783 bool CheckVisitedAndUnmark(Object** field) { 1823 bool CheckVisitedAndUnmark(Object** field) {
1784 if ((*field)->IsFailure()) { 1824 if ((*field)->IsFailure()) {
1785 intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask; 1825 intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask;
1786 *field = reinterpret_cast<Object*>(untagged | kHeapObjectTag); 1826 *field = reinterpret_cast<Object*>(untagged | kHeapObjectTag);
1787 ASSERT((*field)->IsHeapObject()); 1827 ASSERT((*field)->IsHeapObject());
1788 return true; 1828 return true;
1789 } 1829 }
1790 return false; 1830 return false;
1791 } 1831 }
1792 V8HeapExplorer* generator_; 1832 V8HeapExplorer* generator_;
1793 HeapObject* parent_obj_; 1833 HeapObject* parent_obj_;
1794 HeapEntry* parent_; 1834 HeapEntry* parent_;
1795 int next_index_; 1835 int next_index_;
1796 }; 1836 };
1797 1837
1798 1838
1799 void V8HeapExplorer::ExtractReferences(HeapObject* obj) { 1839 void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
1800 HeapEntry* entry = GetEntry(obj); 1840 HeapEntry* entry = GetEntry(obj);
1801 if (entry == NULL) return; // No interest in this object. 1841 if (entry == NULL) return; // No interest in this object.
1802 1842
1843 bool extract_indexed_refs = true;
1803 if (obj->IsJSGlobalProxy()) { 1844 if (obj->IsJSGlobalProxy()) {
1804 // We need to reference JS global objects from snapshot's root. 1845 // We need to reference JS global objects from snapshot's root.
1805 // We use JSGlobalProxy because this is what embedder (e.g. browser) 1846 // We use JSGlobalProxy because this is what embedder (e.g. browser)
1806 // uses for the global object. 1847 // uses for the global object.
1807 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj); 1848 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj);
1808 SetRootShortcutReference(proxy->map()->prototype()); 1849 SetRootShortcutReference(proxy->map()->prototype());
1809 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1810 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1811 obj->Iterate(&refs_extractor);
1812 } else if (obj->IsJSObject()) { 1850 } else if (obj->IsJSObject()) {
1813 JSObject* js_obj = JSObject::cast(obj); 1851 JSObject* js_obj = JSObject::cast(obj);
1814 ExtractClosureReferences(js_obj, entry); 1852 ExtractClosureReferences(js_obj, entry);
1815 ExtractPropertyReferences(js_obj, entry); 1853 ExtractPropertyReferences(js_obj, entry);
1816 ExtractElementReferences(js_obj, entry); 1854 ExtractElementReferences(js_obj, entry);
1817 ExtractInternalReferences(js_obj, entry); 1855 ExtractInternalReferences(js_obj, entry);
1818 SetPropertyReference( 1856 SetPropertyReference(
1819 obj, entry, HEAP->Proto_symbol(), js_obj->GetPrototype()); 1857 obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype());
1820 if (obj->IsJSFunction()) { 1858 if (obj->IsJSFunction()) {
1821 JSFunction* js_fun = JSFunction::cast(js_obj); 1859 JSFunction* js_fun = JSFunction::cast(js_obj);
1822 Object* proto_or_map = js_fun->prototype_or_initial_map(); 1860 Object* proto_or_map = js_fun->prototype_or_initial_map();
1823 if (!proto_or_map->IsTheHole()) { 1861 if (!proto_or_map->IsTheHole()) {
1824 if (!proto_or_map->IsMap()) { 1862 if (!proto_or_map->IsMap()) {
1825 SetPropertyReference( 1863 SetPropertyReference(
1826 obj, entry, 1864 obj, entry,
1827 HEAP->prototype_symbol(), proto_or_map, 1865 heap_->prototype_symbol(), proto_or_map,
1828 JSFunction::kPrototypeOrInitialMapOffset); 1866 JSFunction::kPrototypeOrInitialMapOffset);
1829 } else { 1867 } else {
1830 SetPropertyReference( 1868 SetPropertyReference(
1831 obj, entry, 1869 obj, entry,
1832 HEAP->prototype_symbol(), js_fun->prototype()); 1870 heap_->prototype_symbol(), js_fun->prototype());
1833 } 1871 }
1834 } 1872 }
1835 SetInternalReference(js_fun, entry, 1873 SetInternalReference(js_fun, entry,
1836 "shared", js_fun->shared(), 1874 "shared", js_fun->shared(),
1837 JSFunction::kSharedFunctionInfoOffset); 1875 JSFunction::kSharedFunctionInfoOffset);
1876 TagObject(js_fun->unchecked_context(), "(context)");
1838 SetInternalReference(js_fun, entry, 1877 SetInternalReference(js_fun, entry,
1839 "context", js_fun->unchecked_context(), 1878 "context", js_fun->unchecked_context(),
1840 JSFunction::kContextOffset); 1879 JSFunction::kContextOffset);
1880 TagObject(js_fun->literals(), "(function literals)");
1841 SetInternalReference(js_fun, entry, 1881 SetInternalReference(js_fun, entry,
1842 "literals", js_fun->literals(), 1882 "literals", js_fun->literals(),
1843 JSFunction::kLiteralsOffset); 1883 JSFunction::kLiteralsOffset);
1844 } 1884 }
1885 TagObject(js_obj->properties(), "(object properties)");
1845 SetInternalReference(obj, entry, 1886 SetInternalReference(obj, entry,
1846 "properties", js_obj->properties(), 1887 "properties", js_obj->properties(),
1847 JSObject::kPropertiesOffset); 1888 JSObject::kPropertiesOffset);
1889 TagObject(js_obj->elements(), "(object elements)");
1848 SetInternalReference(obj, entry, 1890 SetInternalReference(obj, entry,
1849 "elements", js_obj->elements(), 1891 "elements", js_obj->elements(),
1850 JSObject::kElementsOffset); 1892 JSObject::kElementsOffset);
1851 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1852 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1853 obj->Iterate(&refs_extractor);
1854 } else if (obj->IsString()) { 1893 } else if (obj->IsString()) {
1855 if (obj->IsConsString()) { 1894 if (obj->IsConsString()) {
1856 ConsString* cs = ConsString::cast(obj); 1895 ConsString* cs = ConsString::cast(obj);
1857 SetInternalReference(obj, entry, 1, cs->first()); 1896 SetInternalReference(obj, entry, 1, cs->first());
1858 SetInternalReference(obj, entry, 2, cs->second()); 1897 SetInternalReference(obj, entry, 2, cs->second());
1859 } 1898 }
1899 extract_indexed_refs = false;
1900 } else if (obj->IsGlobalContext()) {
1901 Context* context = Context::cast(obj);
1902 TagObject(context->jsfunction_result_caches(),
1903 "(context func. result caches)");
1904 TagObject(context->normalized_map_cache(), "(context norm. map cache)");
1905 TagObject(context->runtime_context(), "(runtime context)");
1906 TagObject(context->map_cache(), "(context map cache)");
1907 TagObject(context->data(), "(context data)");
1860 } else if (obj->IsMap()) { 1908 } else if (obj->IsMap()) {
1861 Map* map = Map::cast(obj); 1909 Map* map = Map::cast(obj);
1862 SetInternalReference(obj, entry, 1910 SetInternalReference(obj, entry,
1863 "prototype", map->prototype(), Map::kPrototypeOffset); 1911 "prototype", map->prototype(), Map::kPrototypeOffset);
1864 SetInternalReference(obj, entry, 1912 SetInternalReference(obj, entry,
1865 "constructor", map->constructor(), 1913 "constructor", map->constructor(),
1866 Map::kConstructorOffset); 1914 Map::kConstructorOffset);
1867 if (!map->instance_descriptors()->IsEmpty()) { 1915 if (!map->instance_descriptors()->IsEmpty()) {
1916 TagObject(map->instance_descriptors(), "(map descriptors)");
1868 SetInternalReference(obj, entry, 1917 SetInternalReference(obj, entry,
1869 "descriptors", map->instance_descriptors(), 1918 "descriptors", map->instance_descriptors(),
1870 Map::kInstanceDescriptorsOrBitField3Offset); 1919 Map::kInstanceDescriptorsOrBitField3Offset);
1871 } 1920 }
1921 if (map->prototype_transitions() != heap_->empty_fixed_array()) {
1922 TagObject(map->prototype_transitions(), "(prototype transitions)");
1923 SetInternalReference(obj,
1924 entry,
1925 "prototype_transitions",
1926 map->prototype_transitions(),
1927 Map::kPrototypeTransitionsOffset);
1928 }
1872 SetInternalReference(obj, entry, 1929 SetInternalReference(obj, entry,
1873 "code_cache", map->code_cache(), 1930 "code_cache", map->code_cache(),
1874 Map::kCodeCacheOffset); 1931 Map::kCodeCacheOffset);
1875 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1876 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1877 obj->Iterate(&refs_extractor);
1878 } else if (obj->IsSharedFunctionInfo()) { 1932 } else if (obj->IsSharedFunctionInfo()) {
1879 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); 1933 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
1880 SetInternalReference(obj, entry, 1934 SetInternalReference(obj, entry,
1881 "name", shared->name(), 1935 "name", shared->name(),
1882 SharedFunctionInfo::kNameOffset); 1936 SharedFunctionInfo::kNameOffset);
1883 SetInternalReference(obj, entry, 1937 SetInternalReference(obj, entry,
1884 "code", shared->unchecked_code(), 1938 "code", shared->unchecked_code(),
1885 SharedFunctionInfo::kCodeOffset); 1939 SharedFunctionInfo::kCodeOffset);
1940 TagObject(shared->scope_info(), "(function scope info)");
1941 SetInternalReference(obj, entry,
1942 "scope_info", shared->scope_info(),
1943 SharedFunctionInfo::kScopeInfoOffset);
1886 SetInternalReference(obj, entry, 1944 SetInternalReference(obj, entry,
1887 "instance_class_name", shared->instance_class_name(), 1945 "instance_class_name", shared->instance_class_name(),
1888 SharedFunctionInfo::kInstanceClassNameOffset); 1946 SharedFunctionInfo::kInstanceClassNameOffset);
1889 SetInternalReference(obj, entry, 1947 SetInternalReference(obj, entry,
1890 "script", shared->script(), 1948 "script", shared->script(),
1891 SharedFunctionInfo::kScriptOffset); 1949 SharedFunctionInfo::kScriptOffset);
1892 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); 1950 } else if (obj->IsScript()) {
1893 IndexedReferencesExtractor refs_extractor(this, obj, entry); 1951 Script* script = Script::cast(obj);
1894 obj->Iterate(&refs_extractor); 1952 SetInternalReference(obj, entry,
1895 } else { 1953 "source", script->source(),
1954 Script::kSourceOffset);
1955 SetInternalReference(obj, entry,
1956 "name", script->name(),
1957 Script::kNameOffset);
1958 SetInternalReference(obj, entry,
1959 "data", script->data(),
1960 Script::kDataOffset);
1961 SetInternalReference(obj, entry,
1962 "context_data", script->context_data(),
1963 Script::kContextOffset);
1964 TagObject(script->line_ends(), "(script line ends)");
1965 SetInternalReference(obj, entry,
1966 "line_ends", script->line_ends(),
1967 Script::kLineEndsOffset);
1968 } else if (obj->IsDescriptorArray()) {
1969 DescriptorArray* desc_array = DescriptorArray::cast(obj);
1970 if (desc_array->length() > DescriptorArray::kContentArrayIndex) {
1971 Object* content_array =
1972 desc_array->get(DescriptorArray::kContentArrayIndex);
1973 TagObject(content_array, "(map descriptor content)");
1974 SetInternalReference(obj, entry,
1975 "content", content_array,
1976 FixedArray::OffsetOfElementAt(
1977 DescriptorArray::kContentArrayIndex));
1978 }
1979 } else if (obj->IsCodeCache()) {
1980 CodeCache* code_cache = CodeCache::cast(obj);
1981 TagObject(code_cache->default_cache(), "(default code cache)");
1982 SetInternalReference(obj, entry,
1983 "default_cache", code_cache->default_cache(),
1984 CodeCache::kDefaultCacheOffset);
1985 TagObject(code_cache->normal_type_cache(), "(code type cache)");
1986 SetInternalReference(obj, entry,
1987 "type_cache", code_cache->normal_type_cache(),
1988 CodeCache::kNormalTypeCacheOffset);
1989 } else if (obj->IsCode()) {
1990 Code* code = Code::cast(obj);
1991 TagObject(code->unchecked_relocation_info(), "(code relocation info)");
1992 TagObject(code->unchecked_deoptimization_data(), "(code deopt data)");
1993 }
1994 if (extract_indexed_refs) {
1896 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); 1995 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
1897 IndexedReferencesExtractor refs_extractor(this, obj, entry); 1996 IndexedReferencesExtractor refs_extractor(this, obj, entry);
1898 obj->Iterate(&refs_extractor); 1997 obj->Iterate(&refs_extractor);
1899 } 1998 }
1900 } 1999 }
1901 2000
1902 2001
1903 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, 2002 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
1904 HeapEntry* entry) { 2003 HeapEntry* entry) {
1905 if (js_obj->IsJSFunction()) { 2004 if (js_obj->IsJSFunction()) {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 private: 2127 private:
2029 V8HeapExplorer* explorer_; 2128 V8HeapExplorer* explorer_;
2030 }; 2129 };
2031 2130
2032 2131
2033 bool V8HeapExplorer::IterateAndExtractReferences( 2132 bool V8HeapExplorer::IterateAndExtractReferences(
2034 HeapIterator* iterator, 2133 HeapIterator* iterator,
2035 SnapshotFillerInterface* filler) { 2134 SnapshotFillerInterface* filler) {
2036 filler_ = filler; 2135 filler_ = filler;
2037 bool interrupted = false; 2136 bool interrupted = false;
2137
2038 // Heap iteration with filtering must be finished in any case. 2138 // Heap iteration with filtering must be finished in any case.
2039 for (HeapObject* obj = iterator->Next(); 2139 for (HeapObject* obj = iterator->Next();
2040 obj != NULL; 2140 obj != NULL;
2041 obj = iterator->Next(), progress_->ProgressStep()) { 2141 obj = iterator->Next(), progress_->ProgressStep()) {
2042 if (!interrupted) { 2142 if (!interrupted) {
2043 ExtractReferences(obj); 2143 ExtractReferences(obj);
2044 if (!progress_->ProgressReport(false)) interrupted = true; 2144 if (!progress_->ProgressReport(false)) interrupted = true;
2045 } 2145 }
2046 } 2146 }
2047 if (interrupted) { 2147 if (interrupted) {
2048 filler_ = NULL; 2148 filler_ = NULL;
2049 return false; 2149 return false;
2050 } 2150 }
2051 SetRootGcRootsReference(); 2151 SetRootGcRootsReference();
2052 RootsReferencesExtractor extractor(this); 2152 RootsReferencesExtractor extractor(this);
2053 HEAP->IterateRoots(&extractor, VISIT_ALL); 2153 heap_->IterateRoots(&extractor, VISIT_ALL);
2054 filler_ = NULL; 2154 filler_ = NULL;
2055 return progress_->ProgressReport(false); 2155 return progress_->ProgressReport(false);
2056 } 2156 }
2057 2157
2058 2158
2059 void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj, 2159 void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
2060 HeapEntry* parent_entry, 2160 HeapEntry* parent_entry,
2061 String* reference_name, 2161 String* reference_name,
2062 Object* child_obj) { 2162 Object* child_obj) {
2063 HeapEntry* child_entry = GetEntry(child_obj); 2163 HeapEntry* child_entry = GetEntry(child_obj);
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
2198 HeapEntry* child_entry = GetEntry(child_obj); 2298 HeapEntry* child_entry = GetEntry(child_obj);
2199 if (child_entry != NULL) { 2299 if (child_entry != NULL) {
2200 filler_->SetIndexedAutoIndexReference( 2300 filler_->SetIndexedAutoIndexReference(
2201 HeapGraphEdge::kElement, 2301 HeapGraphEdge::kElement,
2202 kGcRootsObject, snapshot_->gc_roots(), 2302 kGcRootsObject, snapshot_->gc_roots(),
2203 child_obj, child_entry); 2303 child_obj, child_entry);
2204 } 2304 }
2205 } 2305 }
2206 2306
2207 2307
2308 void V8HeapExplorer::TagObject(Object* obj, const char* tag) {
2309 if (obj->IsHeapObject() &&
2310 !obj->IsOddball() &&
2311 obj != heap_->raw_unchecked_empty_byte_array() &&
2312 obj != heap_->raw_unchecked_empty_fixed_array() &&
2313 obj != heap_->raw_unchecked_empty_fixed_double_array() &&
2314 obj != heap_->raw_unchecked_empty_descriptor_array()) {
2315 objects_tags_.SetTag(obj, tag);
2316 }
2317 }
2318
2319
2320 class GlobalObjectsEnumerator : public ObjectVisitor {
2321 public:
2322 virtual void VisitPointers(Object** start, Object** end) {
2323 for (Object** p = start; p < end; p++) {
2324 if ((*p)->IsGlobalContext()) {
2325 Context* context = Context::cast(*p);
2326 JSObject* proxy = context->global_proxy();
2327 if (proxy->IsJSGlobalProxy()) {
2328 Object* global = proxy->map()->prototype();
2329 if (global->IsJSGlobalObject()) {
2330 objects_.Add(Handle<JSGlobalObject>(JSGlobalObject::cast(global)));
2331 }
2332 }
2333 }
2334 }
2335 }
2336 int count() { return objects_.length(); }
2337 Handle<JSGlobalObject>& at(int i) { return objects_[i]; }
2338
2339 private:
2340 List<Handle<JSGlobalObject> > objects_;
2341 };
2342
2343
2344 // Modifies heap. Must not be run during heap traversal.
2345 void V8HeapExplorer::TagGlobalObjects() {
2346 Isolate* isolate = Isolate::Current();
2347 GlobalObjectsEnumerator enumerator;
2348 isolate->global_handles()->IterateAllRoots(&enumerator);
2349 Handle<String> document_string =
2350 isolate->factory()->NewStringFromAscii(CStrVector("document"));
2351 Handle<String> url_string =
2352 isolate->factory()->NewStringFromAscii(CStrVector("URL"));
2353 const char** urls = NewArray<const char*>(enumerator.count());
2354 for (int i = 0, l = enumerator.count(); i < l; ++i) {
2355 urls[i] = NULL;
2356 Handle<JSGlobalObject> global_obj = enumerator.at(i);
2357 Object* obj_document;
2358 if (global_obj->GetProperty(*document_string)->ToObject(&obj_document) &&
2359 obj_document->IsJSObject()) {
2360 JSObject* document = JSObject::cast(obj_document);
2361 Object* obj_url;
2362 if (document->GetProperty(*url_string)->ToObject(&obj_url) &&
2363 obj_url->IsString()) {
2364 urls[i] = collection_->names()->GetName(String::cast(obj_url));
2365 }
2366 }
2367 }
2368
2369 AssertNoAllocation no_allocation;
2370 for (int i = 0, l = enumerator.count(); i < l; ++i) {
2371 objects_tags_.SetTag(*enumerator.at(i), urls[i]);
2372 }
2373
2374 DeleteArray(urls);
2375 }
2376
2377
2208 class GlobalHandlesExtractor : public ObjectVisitor { 2378 class GlobalHandlesExtractor : public ObjectVisitor {
2209 public: 2379 public:
2210 explicit GlobalHandlesExtractor(NativeObjectsExplorer* explorer) 2380 explicit GlobalHandlesExtractor(NativeObjectsExplorer* explorer)
2211 : explorer_(explorer) {} 2381 : explorer_(explorer) {}
2212 virtual ~GlobalHandlesExtractor() {} 2382 virtual ~GlobalHandlesExtractor() {}
2213 virtual void VisitPointers(Object** start, Object** end) { 2383 virtual void VisitPointers(Object** start, Object** end) {
2214 UNREACHABLE(); 2384 UNREACHABLE();
2215 } 2385 }
2216 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) { 2386 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {
2217 explorer_->VisitSubtreeWrapper(p, class_id); 2387 explorer_->VisitSubtreeWrapper(p, class_id);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2440 HeapEntry*) { 2610 HeapEntry*) {
2441 entries_->CountReference(parent_ptr, child_ptr); 2611 entries_->CountReference(parent_ptr, child_ptr);
2442 } 2612 }
2443 void SetNamedAutoIndexReference(HeapGraphEdge::Type, 2613 void SetNamedAutoIndexReference(HeapGraphEdge::Type,
2444 HeapThing parent_ptr, 2614 HeapThing parent_ptr,
2445 HeapEntry*, 2615 HeapEntry*,
2446 HeapThing child_ptr, 2616 HeapThing child_ptr,
2447 HeapEntry*) { 2617 HeapEntry*) {
2448 entries_->CountReference(parent_ptr, child_ptr); 2618 entries_->CountReference(parent_ptr, child_ptr);
2449 } 2619 }
2620
2450 private: 2621 private:
2451 HeapEntriesMap* entries_; 2622 HeapEntriesMap* entries_;
2452 }; 2623 };
2453 2624
2454 2625
2455 class SnapshotFiller : public SnapshotFillerInterface { 2626 class SnapshotFiller : public SnapshotFillerInterface {
2456 public: 2627 public:
2457 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) 2628 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
2458 : snapshot_(snapshot), 2629 : snapshot_(snapshot),
2459 collection_(snapshot->collection()), 2630 collection_(snapshot->collection()),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 HeapEntry* child_entry) { 2682 HeapEntry* child_entry) {
2512 int child_index, retainer_index; 2683 int child_index, retainer_index;
2513 entries_->CountReference( 2684 entries_->CountReference(
2514 parent_ptr, child_ptr, &child_index, &retainer_index); 2685 parent_ptr, child_ptr, &child_index, &retainer_index);
2515 parent_entry->SetNamedReference(type, 2686 parent_entry->SetNamedReference(type,
2516 child_index, 2687 child_index,
2517 collection_->names()->GetName(child_index + 1), 2688 collection_->names()->GetName(child_index + 1),
2518 child_entry, 2689 child_entry,
2519 retainer_index); 2690 retainer_index);
2520 } 2691 }
2692
2521 private: 2693 private:
2522 HeapSnapshot* snapshot_; 2694 HeapSnapshot* snapshot_;
2523 HeapSnapshotsCollection* collection_; 2695 HeapSnapshotsCollection* collection_;
2524 HeapEntriesMap* entries_; 2696 HeapEntriesMap* entries_;
2525 }; 2697 };
2526 2698
2527 2699
2528 bool HeapSnapshotGenerator::GenerateSnapshot() { 2700 bool HeapSnapshotGenerator::GenerateSnapshot() {
2701 v8_heap_explorer_.TagGlobalObjects();
2702
2703 // TODO(gc) Profiler assumes that any object that is in the heap after
2704 // full GC is reachable from the root when computing dominators.
2705 // This is not true for weakly reachable objects.
2706 // As a temporary solution we call GC twice.
2707 Isolate::Current()->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
2708 Isolate::Current()->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
2709
2710 // Iterator creation should follow TagGlobalObjects as it can allocate.
2529 HeapIterator set_progress_heap_iterator; 2711 HeapIterator set_progress_heap_iterator;
2530 HeapIterator count_entries_heap_iterator; 2712 HeapIterator count_entries_heap_iterator;
2531 HeapIterator fill_references_heap_iterator; 2713 HeapIterator fill_references_heap_iterator;
2714
2532 AssertNoAllocation no_alloc; 2715 AssertNoAllocation no_alloc;
2533 2716
2534 SetProgressTotal(&set_progress_heap_iterator, 2717 SetProgressTotal(&set_progress_heap_iterator,
2535 4); // 2 passes + dominators + sizes. 2718 4); // 2 passes + dominators + sizes.
2536 2719
2537 // Pass 1. Iterate heap contents to count entries and references. 2720 // Pass 1. Iterate heap contents to count entries and references.
2538 if (!CountEntriesAndReferences(&count_entries_heap_iterator)) return false; 2721 if (!CountEntriesAndReferences(&count_entries_heap_iterator)) return false;
2539 2722
2540 // Allocate and fill entries in the snapshot, allocate references. 2723 // Allocate and fill entries in the snapshot, allocate references.
2541 snapshot_->AllocateEntries(entries_.entries_count(), 2724 snapshot_->AllocateEntries(entries_.entries_count(),
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
3093 3276
3094 3277
3095 String* GetConstructorNameForHeapProfile(JSObject* object) { 3278 String* GetConstructorNameForHeapProfile(JSObject* object) {
3096 if (object->IsJSFunction()) return HEAP->closure_symbol(); 3279 if (object->IsJSFunction()) return HEAP->closure_symbol();
3097 return object->constructor_name(); 3280 return object->constructor_name();
3098 } 3281 }
3099 3282
3100 } } // namespace v8::internal 3283 } } // namespace v8::internal
3101 3284
3102 #endif // ENABLE_LOGGING_AND_PROFILING 3285 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | src/proxy.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698