| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/heap-snapshot-generator-inl.h" | 7 #include "src/heap-snapshot-generator-inl.h" |
| 8 | 8 |
| 9 #include "src/allocation-tracker.h" | 9 #include "src/allocation-tracker.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 } | 1619 } |
| 1620 } | 1620 } |
| 1621 } | 1621 } |
| 1622 | 1622 |
| 1623 | 1623 |
| 1624 void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) { | 1624 void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) { |
| 1625 if (js_obj->HasFastProperties()) { | 1625 if (js_obj->HasFastProperties()) { |
| 1626 DescriptorArray* descs = js_obj->map()->instance_descriptors(); | 1626 DescriptorArray* descs = js_obj->map()->instance_descriptors(); |
| 1627 int real_size = js_obj->map()->NumberOfOwnDescriptors(); | 1627 int real_size = js_obj->map()->NumberOfOwnDescriptors(); |
| 1628 for (int i = 0; i < real_size; i++) { | 1628 for (int i = 0; i < real_size; i++) { |
| 1629 switch (descs->GetType(i)) { | 1629 PropertyDetails details = descs->GetDetails(i); |
| 1630 case FIELD: { | 1630 switch (details.location()) { |
| 1631 Representation r = descs->GetDetails(i).representation(); | 1631 case IN_OBJECT: { |
| 1632 Representation r = details.representation(); |
| 1632 if (r.IsSmi() || r.IsDouble()) break; | 1633 if (r.IsSmi() || r.IsDouble()) break; |
| 1633 int index = descs->GetFieldIndex(i); | |
| 1634 | 1634 |
| 1635 Name* k = descs->GetKey(i); | 1635 Name* k = descs->GetKey(i); |
| 1636 if (index < js_obj->map()->inobject_properties()) { | 1636 FieldIndex field_index = FieldIndex::ForDescriptor(js_obj->map(), i); |
| 1637 Object* value = js_obj->InObjectPropertyAt(index); | 1637 Object* value = js_obj->RawFastPropertyAt(field_index); |
| 1638 if (k != heap_->hidden_string()) { | 1638 int field_offset = |
| 1639 SetPropertyReference( | 1639 field_index.is_inobject() ? field_index.offset() : -1; |
| 1640 js_obj, entry, | 1640 |
| 1641 k, value, | 1641 if (k != heap_->hidden_string()) { |
| 1642 NULL, | 1642 SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry, k, |
| 1643 js_obj->GetInObjectPropertyOffset(index)); | 1643 value, NULL, field_offset); |
| 1644 } else { | |
| 1645 TagObject(value, "(hidden properties)"); | |
| 1646 SetInternalReference( | |
| 1647 js_obj, entry, | |
| 1648 "hidden_properties", value, | |
| 1649 js_obj->GetInObjectPropertyOffset(index)); | |
| 1650 } | |
| 1651 } else { | 1644 } else { |
| 1652 FieldIndex field_index = | 1645 TagObject(value, "(hidden properties)"); |
| 1653 FieldIndex::ForDescriptor(js_obj->map(), i); | 1646 SetInternalReference(js_obj, entry, "hidden_properties", value, |
| 1654 Object* value = js_obj->RawFastPropertyAt(field_index); | 1647 field_offset); |
| 1655 if (k != heap_->hidden_string()) { | |
| 1656 SetPropertyReference(js_obj, entry, k, value); | |
| 1657 } else { | |
| 1658 TagObject(value, "(hidden properties)"); | |
| 1659 SetInternalReference(js_obj, entry, "hidden_properties", value); | |
| 1660 } | |
| 1661 } | 1648 } |
| 1662 break; | 1649 break; |
| 1663 } | 1650 } |
| 1664 case CONSTANT: | 1651 case IN_DESCRIPTOR: |
| 1665 SetPropertyReference( | 1652 SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry, |
| 1666 js_obj, entry, | 1653 descs->GetKey(i), |
| 1667 descs->GetKey(i), descs->GetConstant(i)); | 1654 descs->GetValue(i)); |
| 1668 break; | |
| 1669 case CALLBACKS: | |
| 1670 ExtractAccessorPairProperty( | |
| 1671 js_obj, entry, | |
| 1672 descs->GetKey(i), descs->GetValue(i)); | |
| 1673 break; | 1655 break; |
| 1674 } | 1656 } |
| 1675 } | 1657 } |
| 1676 } else { | 1658 } else { |
| 1677 NameDictionary* dictionary = js_obj->property_dictionary(); | 1659 NameDictionary* dictionary = js_obj->property_dictionary(); |
| 1678 int length = dictionary->Capacity(); | 1660 int length = dictionary->Capacity(); |
| 1679 for (int i = 0; i < length; ++i) { | 1661 for (int i = 0; i < length; ++i) { |
| 1680 Object* k = dictionary->KeyAt(i); | 1662 Object* k = dictionary->KeyAt(i); |
| 1681 if (dictionary->IsKey(k)) { | 1663 if (dictionary->IsKey(k)) { |
| 1682 Object* target = dictionary->ValueAt(i); | 1664 Object* target = dictionary->ValueAt(i); |
| 1683 // We assume that global objects can only have slow properties. | 1665 // We assume that global objects can only have slow properties. |
| 1684 Object* value = target->IsPropertyCell() | 1666 Object* value = target->IsPropertyCell() |
| 1685 ? PropertyCell::cast(target)->value() | 1667 ? PropertyCell::cast(target)->value() |
| 1686 : target; | 1668 : target; |
| 1687 if (k == heap_->hidden_string()) { | 1669 if (k == heap_->hidden_string()) { |
| 1688 TagObject(value, "(hidden properties)"); | 1670 TagObject(value, "(hidden properties)"); |
| 1689 SetInternalReference(js_obj, entry, "hidden_properties", value); | 1671 SetInternalReference(js_obj, entry, "hidden_properties", value); |
| 1690 continue; | 1672 continue; |
| 1691 } | 1673 } |
| 1692 if (ExtractAccessorPairProperty(js_obj, entry, k, value)) continue; | 1674 PropertyDetails details = dictionary->DetailsAt(i); |
| 1693 SetPropertyReference(js_obj, entry, Name::cast(k), value); | 1675 SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry, |
| 1676 Name::cast(k), value); |
| 1694 } | 1677 } |
| 1695 } | 1678 } |
| 1696 } | 1679 } |
| 1697 } | 1680 } |
| 1698 | 1681 |
| 1699 | 1682 |
| 1700 bool V8HeapExplorer::ExtractAccessorPairProperty( | 1683 void V8HeapExplorer::ExtractAccessorPairProperty(JSObject* js_obj, int entry, |
| 1701 JSObject* js_obj, int entry, Object* key, Object* callback_obj) { | 1684 Name* key, |
| 1702 if (!callback_obj->IsAccessorPair()) return false; | 1685 Object* callback_obj, |
| 1686 int field_offset) { |
| 1687 if (!callback_obj->IsAccessorPair()) return; |
| 1703 AccessorPair* accessors = AccessorPair::cast(callback_obj); | 1688 AccessorPair* accessors = AccessorPair::cast(callback_obj); |
| 1689 SetPropertyReference(js_obj, entry, key, accessors, NULL, field_offset); |
| 1704 Object* getter = accessors->getter(); | 1690 Object* getter = accessors->getter(); |
| 1705 if (!getter->IsOddball()) { | 1691 if (!getter->IsOddball()) { |
| 1706 SetPropertyReference(js_obj, entry, Name::cast(key), getter, "get %s"); | 1692 SetPropertyReference(js_obj, entry, key, getter, "get %s"); |
| 1707 } | 1693 } |
| 1708 Object* setter = accessors->setter(); | 1694 Object* setter = accessors->setter(); |
| 1709 if (!setter->IsOddball()) { | 1695 if (!setter->IsOddball()) { |
| 1710 SetPropertyReference(js_obj, entry, Name::cast(key), setter, "set %s"); | 1696 SetPropertyReference(js_obj, entry, key, setter, "set %s"); |
| 1711 } | 1697 } |
| 1712 return true; | |
| 1713 } | 1698 } |
| 1714 | 1699 |
| 1715 | 1700 |
| 1716 void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) { | 1701 void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) { |
| 1717 if (js_obj->HasFastObjectElements()) { | 1702 if (js_obj->HasFastObjectElements()) { |
| 1718 FixedArray* elements = FixedArray::cast(js_obj->elements()); | 1703 FixedArray* elements = FixedArray::cast(js_obj->elements()); |
| 1719 int length = js_obj->IsJSArray() ? | 1704 int length = js_obj->IsJSArray() ? |
| 1720 Smi::cast(JSArray::cast(js_obj)->length())->value() : | 1705 Smi::cast(JSArray::cast(js_obj)->length())->value() : |
| 1721 elements->length(); | 1706 elements->length(); |
| 1722 for (int i = 0; i < length; ++i) { | 1707 for (int i = 0; i < length; ++i) { |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2041 if (IsEssentialObject(child_obj)) { | 2026 if (IsEssentialObject(child_obj)) { |
| 2042 filler_->SetNamedReference(HeapGraphEdge::kWeak, | 2027 filler_->SetNamedReference(HeapGraphEdge::kWeak, |
| 2043 parent_entry, | 2028 parent_entry, |
| 2044 names_->GetFormatted("%d", index), | 2029 names_->GetFormatted("%d", index), |
| 2045 child_entry); | 2030 child_entry); |
| 2046 } | 2031 } |
| 2047 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); | 2032 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); |
| 2048 } | 2033 } |
| 2049 | 2034 |
| 2050 | 2035 |
| 2036 void V8HeapExplorer::SetDataOrAccessorPropertyReference( |
| 2037 PropertyKind kind, JSObject* parent_obj, int parent_entry, |
| 2038 Name* reference_name, Object* child_obj, const char* name_format_string, |
| 2039 int field_offset) { |
| 2040 if (kind == ACCESSOR) { |
| 2041 ExtractAccessorPairProperty(parent_obj, parent_entry, reference_name, |
| 2042 child_obj, field_offset); |
| 2043 } else { |
| 2044 SetPropertyReference(parent_obj, parent_entry, reference_name, child_obj, |
| 2045 name_format_string, field_offset); |
| 2046 } |
| 2047 } |
| 2048 |
| 2049 |
| 2051 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, | 2050 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, |
| 2052 int parent_entry, | 2051 int parent_entry, |
| 2053 Name* reference_name, | 2052 Name* reference_name, |
| 2054 Object* child_obj, | 2053 Object* child_obj, |
| 2055 const char* name_format_string, | 2054 const char* name_format_string, |
| 2056 int field_offset) { | 2055 int field_offset) { |
| 2057 DCHECK(parent_entry == GetEntry(parent_obj)->index()); | 2056 DCHECK(parent_entry == GetEntry(parent_obj)->index()); |
| 2058 HeapEntry* child_entry = GetEntry(child_obj); | 2057 HeapEntry* child_entry = GetEntry(child_obj); |
| 2059 if (child_entry != NULL) { | 2058 if (child_entry != NULL) { |
| 2060 HeapGraphEdge::Type type = | 2059 HeapGraphEdge::Type type = |
| (...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3134 writer_->AddString("\"<dummy>\""); | 3133 writer_->AddString("\"<dummy>\""); |
| 3135 for (int i = 1; i < sorted_strings.length(); ++i) { | 3134 for (int i = 1; i < sorted_strings.length(); ++i) { |
| 3136 writer_->AddCharacter(','); | 3135 writer_->AddCharacter(','); |
| 3137 SerializeString(sorted_strings[i]); | 3136 SerializeString(sorted_strings[i]); |
| 3138 if (writer_->aborted()) return; | 3137 if (writer_->aborted()) return; |
| 3139 } | 3138 } |
| 3140 } | 3139 } |
| 3141 | 3140 |
| 3142 | 3141 |
| 3143 } } // namespace v8::internal | 3142 } } // namespace v8::internal |
| OLD | NEW |