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 |