| 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 <sstream> | 5 #include <sstream> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 map()->constructor_name()->PrintOn(file); | 1262 map()->constructor_name()->PrintOn(file); |
| 1263 PrintF(file, "] "); | 1263 PrintF(file, "] "); |
| 1264 DescriptorArray* o = original_map->instance_descriptors(); | 1264 DescriptorArray* o = original_map->instance_descriptors(); |
| 1265 DescriptorArray* n = new_map->instance_descriptors(); | 1265 DescriptorArray* n = new_map->instance_descriptors(); |
| 1266 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { | 1266 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { |
| 1267 Representation o_r = o->GetDetails(i).representation(); | 1267 Representation o_r = o->GetDetails(i).representation(); |
| 1268 Representation n_r = n->GetDetails(i).representation(); | 1268 Representation n_r = n->GetDetails(i).representation(); |
| 1269 if (!o_r.Equals(n_r)) { | 1269 if (!o_r.Equals(n_r)) { |
| 1270 String::cast(o->GetKey(i))->PrintOn(file); | 1270 String::cast(o->GetKey(i))->PrintOn(file); |
| 1271 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); | 1271 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); |
| 1272 } else if (o->GetDetails(i).type() == CONSTANT && | 1272 } else if (o->GetDetails(i).type() == DATA_CONSTANT && |
| 1273 n->GetDetails(i).type() == FIELD) { | 1273 n->GetDetails(i).type() == DATA_FIELD) { |
| 1274 Name* name = o->GetKey(i); | 1274 Name* name = o->GetKey(i); |
| 1275 if (name->IsString()) { | 1275 if (name->IsString()) { |
| 1276 String::cast(name)->PrintOn(file); | 1276 String::cast(name)->PrintOn(file); |
| 1277 } else { | 1277 } else { |
| 1278 PrintF(file, "{symbol %p}", static_cast<void*>(name)); | 1278 PrintF(file, "{symbol %p}", static_cast<void*>(name)); |
| 1279 } | 1279 } |
| 1280 PrintF(file, " "); | 1280 PrintF(file, " "); |
| 1281 } | 1281 } |
| 1282 } | 1282 } |
| 1283 PrintF(file, "\n"); | 1283 PrintF(file, "\n"); |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1641 Isolate* isolate = map->GetIsolate(); | 1641 Isolate* isolate = map->GetIsolate(); |
| 1642 | 1642 |
| 1643 // Compute the new index for new field. | 1643 // Compute the new index for new field. |
| 1644 int index = map->NextFreePropertyIndex(); | 1644 int index = map->NextFreePropertyIndex(); |
| 1645 | 1645 |
| 1646 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { | 1646 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { |
| 1647 representation = Representation::Tagged(); | 1647 representation = Representation::Tagged(); |
| 1648 type = HeapType::Any(isolate); | 1648 type = HeapType::Any(isolate); |
| 1649 } | 1649 } |
| 1650 | 1650 |
| 1651 FieldDescriptor new_field_desc(name, index, type, attributes, representation); | 1651 DataFieldDescriptor new_field_desc(name, index, type, attributes, |
| 1652 representation); |
| 1652 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); | 1653 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); |
| 1653 int unused_property_fields = new_map->unused_property_fields() - 1; | 1654 int unused_property_fields = new_map->unused_property_fields() - 1; |
| 1654 if (unused_property_fields < 0) { | 1655 if (unused_property_fields < 0) { |
| 1655 unused_property_fields += JSObject::kFieldsAdded; | 1656 unused_property_fields += JSObject::kFieldsAdded; |
| 1656 } | 1657 } |
| 1657 new_map->set_unused_property_fields(unused_property_fields); | 1658 new_map->set_unused_property_fields(unused_property_fields); |
| 1658 return new_map; | 1659 return new_map; |
| 1659 } | 1660 } |
| 1660 | 1661 |
| 1661 | 1662 |
| 1662 MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map, | 1663 MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map, |
| 1663 Handle<Name> name, | 1664 Handle<Name> name, |
| 1664 Handle<Object> constant, | 1665 Handle<Object> constant, |
| 1665 PropertyAttributes attributes, | 1666 PropertyAttributes attributes, |
| 1666 TransitionFlag flag) { | 1667 TransitionFlag flag) { |
| 1667 // Ensure the descriptor array does not get too big. | 1668 // Ensure the descriptor array does not get too big. |
| 1668 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | 1669 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
| 1669 return MaybeHandle<Map>(); | 1670 return MaybeHandle<Map>(); |
| 1670 } | 1671 } |
| 1671 | 1672 |
| 1672 // Allocate new instance descriptors with (name, constant) added. | 1673 // Allocate new instance descriptors with (name, constant) added. |
| 1673 ConstantDescriptor new_constant_desc(name, constant, attributes); | 1674 DataConstantDescriptor new_constant_desc(name, constant, attributes); |
| 1674 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); | 1675 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); |
| 1675 } | 1676 } |
| 1676 | 1677 |
| 1677 | 1678 |
| 1678 void JSObject::AddSlowProperty(Handle<JSObject> object, | 1679 void JSObject::AddSlowProperty(Handle<JSObject> object, |
| 1679 Handle<Name> name, | 1680 Handle<Name> name, |
| 1680 Handle<Object> value, | 1681 Handle<Object> value, |
| 1681 PropertyAttributes attributes) { | 1682 PropertyAttributes attributes) { |
| 1682 DCHECK(!object->HasFastProperties()); | 1683 DCHECK(!object->HasFastProperties()); |
| 1683 Isolate* isolate = object->GetIsolate(); | 1684 Isolate* isolate = object->GetIsolate(); |
| 1684 Handle<NameDictionary> dict(object->property_dictionary()); | 1685 Handle<NameDictionary> dict(object->property_dictionary()); |
| 1685 if (object->IsGlobalObject()) { | 1686 if (object->IsGlobalObject()) { |
| 1686 // In case name is an orphaned property reuse the cell. | 1687 // In case name is an orphaned property reuse the cell. |
| 1687 int entry = dict->FindEntry(name); | 1688 int entry = dict->FindEntry(name); |
| 1688 if (entry != NameDictionary::kNotFound) { | 1689 if (entry != NameDictionary::kNotFound) { |
| 1689 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); | 1690 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); |
| 1690 PropertyCell::SetValueInferType(cell, value); | 1691 PropertyCell::SetValueInferType(cell, value); |
| 1691 // Assign an enumeration index to the property and update | 1692 // Assign an enumeration index to the property and update |
| 1692 // SetNextEnumerationIndex. | 1693 // SetNextEnumerationIndex. |
| 1693 int index = dict->NextEnumerationIndex(); | 1694 int index = dict->NextEnumerationIndex(); |
| 1694 PropertyDetails details(attributes, FIELD, index); | 1695 PropertyDetails details(attributes, DATA_FIELD, index); |
| 1695 dict->SetNextEnumerationIndex(index + 1); | 1696 dict->SetNextEnumerationIndex(index + 1); |
| 1696 dict->SetEntry(entry, name, cell, details); | 1697 dict->SetEntry(entry, name, cell, details); |
| 1697 return; | 1698 return; |
| 1698 } | 1699 } |
| 1699 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value); | 1700 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value); |
| 1700 PropertyCell::SetValueInferType(cell, value); | 1701 PropertyCell::SetValueInferType(cell, value); |
| 1701 value = cell; | 1702 value = cell; |
| 1702 } | 1703 } |
| 1703 PropertyDetails details(attributes, FIELD, 0); | 1704 PropertyDetails details(attributes, DATA_FIELD, 0); |
| 1704 Handle<NameDictionary> result = | 1705 Handle<NameDictionary> result = |
| 1705 NameDictionary::Add(dict, name, value, details); | 1706 NameDictionary::Add(dict, name, value, details); |
| 1706 if (*dict != *result) object->set_properties(*result); | 1707 if (*dict != *result) object->set_properties(*result); |
| 1707 } | 1708 } |
| 1708 | 1709 |
| 1709 | 1710 |
| 1710 Context* JSObject::GetCreationContext() { | 1711 Context* JSObject::GetCreationContext() { |
| 1711 Object* constructor = this->map()->constructor(); | 1712 Object* constructor = this->map()->constructor(); |
| 1712 JSFunction* function; | 1713 JSFunction* function; |
| 1713 if (!constructor->IsJSFunction()) { | 1714 if (!constructor->IsJSFunction()) { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 Handle<FixedArray> new_storage = | 1889 Handle<FixedArray> new_storage = |
| 1889 FixedArray::CopySize(old_storage, external); | 1890 FixedArray::CopySize(old_storage, external); |
| 1890 | 1891 |
| 1891 // Properly initialize newly added property. | 1892 // Properly initialize newly added property. |
| 1892 Handle<Object> value; | 1893 Handle<Object> value; |
| 1893 if (details.representation().IsDouble()) { | 1894 if (details.representation().IsDouble()) { |
| 1894 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 1895 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
| 1895 } else { | 1896 } else { |
| 1896 value = isolate->factory()->uninitialized_value(); | 1897 value = isolate->factory()->uninitialized_value(); |
| 1897 } | 1898 } |
| 1898 DCHECK(details.type() == FIELD); | 1899 DCHECK(details.type() == DATA_FIELD); |
| 1899 int target_index = details.field_index() - inobject; | 1900 int target_index = details.field_index() - inobject; |
| 1900 DCHECK(target_index >= 0); // Must be a backing store index. | 1901 DCHECK(target_index >= 0); // Must be a backing store index. |
| 1901 new_storage->set(target_index, *value); | 1902 new_storage->set(target_index, *value); |
| 1902 | 1903 |
| 1903 // From here on we cannot fail and we shouldn't GC anymore. | 1904 // From here on we cannot fail and we shouldn't GC anymore. |
| 1904 DisallowHeapAllocation no_allocation; | 1905 DisallowHeapAllocation no_allocation; |
| 1905 | 1906 |
| 1906 // Set the new property value and do the map transition. | 1907 // Set the new property value and do the map transition. |
| 1907 object->set_properties(*new_storage); | 1908 object->set_properties(*new_storage); |
| 1908 object->synchronized_set_map(*new_map); | 1909 object->synchronized_set_map(*new_map); |
| 1909 return; | 1910 return; |
| 1910 } | 1911 } |
| 1911 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size); | 1912 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size); |
| 1912 | 1913 |
| 1913 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); | 1914 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); |
| 1914 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); | 1915 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); |
| 1915 int old_nof = old_map->NumberOfOwnDescriptors(); | 1916 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 1916 int new_nof = new_map->NumberOfOwnDescriptors(); | 1917 int new_nof = new_map->NumberOfOwnDescriptors(); |
| 1917 | 1918 |
| 1918 // This method only supports generalizing instances to at least the same | 1919 // This method only supports generalizing instances to at least the same |
| 1919 // number of properties. | 1920 // number of properties. |
| 1920 DCHECK(old_nof <= new_nof); | 1921 DCHECK(old_nof <= new_nof); |
| 1921 | 1922 |
| 1922 for (int i = 0; i < old_nof; i++) { | 1923 for (int i = 0; i < old_nof; i++) { |
| 1923 PropertyDetails details = new_descriptors->GetDetails(i); | 1924 PropertyDetails details = new_descriptors->GetDetails(i); |
| 1924 if (details.type() != FIELD) continue; | 1925 if (details.type() != DATA_FIELD) continue; |
| 1925 PropertyDetails old_details = old_descriptors->GetDetails(i); | 1926 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 1926 if (old_details.type() == CALLBACKS) { | 1927 if (old_details.type() == ACCESSOR_CONSTANT) { |
| 1927 DCHECK(details.representation().IsTagged()); | 1928 DCHECK(details.representation().IsTagged()); |
| 1928 continue; | 1929 continue; |
| 1929 } | 1930 } |
| 1930 Representation old_representation = old_details.representation(); | 1931 Representation old_representation = old_details.representation(); |
| 1931 Representation representation = details.representation(); | 1932 Representation representation = details.representation(); |
| 1932 DCHECK(old_details.type() == CONSTANT || | 1933 DCHECK(old_details.type() == DATA_CONSTANT || |
| 1933 old_details.type() == FIELD); | 1934 old_details.type() == DATA_FIELD); |
| 1934 Handle<Object> value; | 1935 Handle<Object> value; |
| 1935 if (old_details.type() == CONSTANT) { | 1936 if (old_details.type() == DATA_CONSTANT) { |
| 1936 value = handle(old_descriptors->GetValue(i), isolate); | 1937 value = handle(old_descriptors->GetValue(i), isolate); |
| 1937 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); | 1938 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); |
| 1938 } else { | 1939 } else { |
| 1939 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); | 1940 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); |
| 1940 if (object->IsUnboxedDoubleField(index)) { | 1941 if (object->IsUnboxedDoubleField(index)) { |
| 1941 double old = object->RawFastDoublePropertyAt(index); | 1942 double old = object->RawFastDoublePropertyAt(index); |
| 1942 value = isolate->factory()->NewHeapNumber( | 1943 value = isolate->factory()->NewHeapNumber( |
| 1943 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); | 1944 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); |
| 1944 | 1945 |
| 1945 } else { | 1946 } else { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1956 } | 1957 } |
| 1957 } | 1958 } |
| 1958 DCHECK(!(representation.IsDouble() && value->IsSmi())); | 1959 DCHECK(!(representation.IsDouble() && value->IsSmi())); |
| 1959 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 1960 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
| 1960 if (target_index < 0) target_index += total_size; | 1961 if (target_index < 0) target_index += total_size; |
| 1961 array->set(target_index, *value); | 1962 array->set(target_index, *value); |
| 1962 } | 1963 } |
| 1963 | 1964 |
| 1964 for (int i = old_nof; i < new_nof; i++) { | 1965 for (int i = old_nof; i < new_nof; i++) { |
| 1965 PropertyDetails details = new_descriptors->GetDetails(i); | 1966 PropertyDetails details = new_descriptors->GetDetails(i); |
| 1966 if (details.type() != FIELD) continue; | 1967 if (details.type() != DATA_FIELD) continue; |
| 1967 Handle<Object> value; | 1968 Handle<Object> value; |
| 1968 if (details.representation().IsDouble()) { | 1969 if (details.representation().IsDouble()) { |
| 1969 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 1970 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
| 1970 } else { | 1971 } else { |
| 1971 value = isolate->factory()->uninitialized_value(); | 1972 value = isolate->factory()->uninitialized_value(); |
| 1972 } | 1973 } |
| 1973 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 1974 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
| 1974 if (target_index < 0) target_index += total_size; | 1975 if (target_index < 0) target_index += total_size; |
| 1975 array->set(target_index, *value); | 1976 array->set(target_index, *value); |
| 1976 } | 1977 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2019 // We are storing the new map using release store after creating a filler for | 2020 // We are storing the new map using release store after creating a filler for |
| 2020 // the left-over space to avoid races with the sweeper thread. | 2021 // the left-over space to avoid races with the sweeper thread. |
| 2021 object->synchronized_set_map(*new_map); | 2022 object->synchronized_set_map(*new_map); |
| 2022 } | 2023 } |
| 2023 | 2024 |
| 2024 | 2025 |
| 2025 int Map::NumberOfFields() { | 2026 int Map::NumberOfFields() { |
| 2026 DescriptorArray* descriptors = instance_descriptors(); | 2027 DescriptorArray* descriptors = instance_descriptors(); |
| 2027 int result = 0; | 2028 int result = 0; |
| 2028 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 2029 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
| 2029 if (descriptors->GetDetails(i).type() == FIELD) result++; | 2030 if (descriptors->GetDetails(i).type() == DATA_FIELD) result++; |
| 2030 } | 2031 } |
| 2031 return result; | 2032 return result; |
| 2032 } | 2033 } |
| 2033 | 2034 |
| 2034 | 2035 |
| 2035 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | 2036 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
| 2036 int modify_index, | 2037 int modify_index, |
| 2037 StoreMode store_mode, | 2038 StoreMode store_mode, |
| 2038 PropertyAttributes attributes, | 2039 PropertyAttributes attributes, |
| 2039 const char* reason) { | 2040 const char* reason) { |
| 2040 Isolate* isolate = map->GetIsolate(); | 2041 Isolate* isolate = map->GetIsolate(); |
| 2041 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 2042 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
| 2042 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 2043 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 2043 Handle<DescriptorArray> descriptors = | 2044 Handle<DescriptorArray> descriptors = |
| 2044 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); | 2045 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); |
| 2045 | 2046 |
| 2046 for (int i = 0; i < number_of_own_descriptors; i++) { | 2047 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 2047 descriptors->SetRepresentation(i, Representation::Tagged()); | 2048 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 2048 if (descriptors->GetDetails(i).type() == FIELD) { | 2049 if (descriptors->GetDetails(i).type() == DATA_FIELD) { |
| 2049 descriptors->SetValue(i, HeapType::Any()); | 2050 descriptors->SetValue(i, HeapType::Any()); |
| 2050 } | 2051 } |
| 2051 } | 2052 } |
| 2052 | 2053 |
| 2053 Handle<LayoutDescriptor> new_layout_descriptor( | 2054 Handle<LayoutDescriptor> new_layout_descriptor( |
| 2054 LayoutDescriptor::FastPointerLayout(), isolate); | 2055 LayoutDescriptor::FastPointerLayout(), isolate); |
| 2055 Handle<Map> new_map = CopyReplaceDescriptors( | 2056 Handle<Map> new_map = CopyReplaceDescriptors( |
| 2056 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, | 2057 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, |
| 2057 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); | 2058 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); |
| 2058 | 2059 |
| 2059 // Unless the instance is being migrated, ensure that modify_index is a field. | 2060 // Unless the instance is being migrated, ensure that modify_index is a field. |
| 2060 PropertyDetails details = descriptors->GetDetails(modify_index); | 2061 PropertyDetails details = descriptors->GetDetails(modify_index); |
| 2061 if (store_mode == FORCE_IN_OBJECT && | 2062 if (store_mode == FORCE_FIELD && |
| 2062 (details.type() != FIELD || details.attributes() != attributes)) { | 2063 (details.type() != DATA_FIELD || details.attributes() != attributes)) { |
| 2063 int field_index = details.type() == FIELD ? details.field_index() | 2064 int field_index = details.type() == DATA_FIELD ? details.field_index() |
| 2064 : new_map->NumberOfFields(); | 2065 : new_map->NumberOfFields(); |
| 2065 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), | 2066 DataFieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), |
| 2066 field_index, attributes, Representation::Tagged()); | 2067 field_index, attributes, Representation::Tagged()); |
| 2067 descriptors->Replace(modify_index, &d); | 2068 descriptors->Replace(modify_index, &d); |
| 2068 if (details.type() != FIELD) { | 2069 if (details.type() != DATA_FIELD) { |
| 2069 int unused_property_fields = new_map->unused_property_fields() - 1; | 2070 int unused_property_fields = new_map->unused_property_fields() - 1; |
| 2070 if (unused_property_fields < 0) { | 2071 if (unused_property_fields < 0) { |
| 2071 unused_property_fields += JSObject::kFieldsAdded; | 2072 unused_property_fields += JSObject::kFieldsAdded; |
| 2072 } | 2073 } |
| 2073 new_map->set_unused_property_fields(unused_property_fields); | 2074 new_map->set_unused_property_fields(unused_property_fields); |
| 2074 } | 2075 } |
| 2075 } else { | 2076 } else { |
| 2076 DCHECK(details.attributes() == attributes); | 2077 DCHECK(details.attributes() == attributes); |
| 2077 } | 2078 } |
| 2078 | 2079 |
| 2079 if (FLAG_trace_generalization) { | 2080 if (FLAG_trace_generalization) { |
| 2080 HeapType* field_type = (details.type() == FIELD) | 2081 HeapType* field_type = |
| 2081 ? map->instance_descriptors()->GetFieldType(modify_index) | 2082 (details.type() == DATA_FIELD) |
| 2082 : NULL; | 2083 ? map->instance_descriptors()->GetFieldType(modify_index) |
| 2084 : NULL; |
| 2083 map->PrintGeneralization( | 2085 map->PrintGeneralization( |
| 2084 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), | 2086 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), |
| 2085 new_map->NumberOfOwnDescriptors(), | 2087 new_map->NumberOfOwnDescriptors(), |
| 2086 details.type() == CONSTANT && store_mode == FORCE_IN_OBJECT, | 2088 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, |
| 2087 details.representation(), Representation::Tagged(), field_type, | 2089 details.representation(), Representation::Tagged(), field_type, |
| 2088 HeapType::Any()); | 2090 HeapType::Any()); |
| 2089 } | 2091 } |
| 2090 return new_map; | 2092 return new_map; |
| 2091 } | 2093 } |
| 2092 | 2094 |
| 2093 | 2095 |
| 2094 // static | 2096 // static |
| 2095 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | 2097 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
| 2096 int modify_index, | 2098 int modify_index, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2184 transitions->Search(details.kind(), name, details.attributes()); | 2186 transitions->Search(details.kind(), name, details.attributes()); |
| 2185 if (transition == TransitionArray::kNotFound) break; | 2187 if (transition == TransitionArray::kNotFound) break; |
| 2186 | 2188 |
| 2187 Map* next = transitions->GetTarget(transition); | 2189 Map* next = transitions->GetTarget(transition); |
| 2188 DescriptorArray* next_descriptors = next->instance_descriptors(); | 2190 DescriptorArray* next_descriptors = next->instance_descriptors(); |
| 2189 | 2191 |
| 2190 PropertyDetails next_details = next_descriptors->GetDetails(i); | 2192 PropertyDetails next_details = next_descriptors->GetDetails(i); |
| 2191 if (details.type() != next_details.type()) break; | 2193 if (details.type() != next_details.type()) break; |
| 2192 if (details.attributes() != next_details.attributes()) break; | 2194 if (details.attributes() != next_details.attributes()) break; |
| 2193 if (!details.representation().Equals(next_details.representation())) break; | 2195 if (!details.representation().Equals(next_details.representation())) break; |
| 2194 if (next_details.type() == FIELD) { | 2196 if (next_details.type() == DATA_FIELD) { |
| 2195 if (!descriptors->GetFieldType(i)->NowIs( | 2197 if (!descriptors->GetFieldType(i)->NowIs( |
| 2196 next_descriptors->GetFieldType(i))) break; | 2198 next_descriptors->GetFieldType(i))) break; |
| 2197 } else { | 2199 } else { |
| 2198 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; | 2200 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; |
| 2199 } | 2201 } |
| 2200 | 2202 |
| 2201 current = next; | 2203 current = next; |
| 2202 } | 2204 } |
| 2203 return current; | 2205 return current; |
| 2204 } | 2206 } |
| 2205 | 2207 |
| 2206 | 2208 |
| 2207 Map* Map::FindFieldOwner(int descriptor) { | 2209 Map* Map::FindFieldOwner(int descriptor) { |
| 2208 DisallowHeapAllocation no_allocation; | 2210 DisallowHeapAllocation no_allocation; |
| 2209 DCHECK_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type()); | 2211 DCHECK_EQ(DATA_FIELD, instance_descriptors()->GetDetails(descriptor).type()); |
| 2210 Map* result = this; | 2212 Map* result = this; |
| 2211 while (true) { | 2213 while (true) { |
| 2212 Object* back = result->GetBackPointer(); | 2214 Object* back = result->GetBackPointer(); |
| 2213 if (back->IsUndefined()) break; | 2215 if (back->IsUndefined()) break; |
| 2214 Map* parent = Map::cast(back); | 2216 Map* parent = Map::cast(back); |
| 2215 if (parent->NumberOfOwnDescriptors() <= descriptor) break; | 2217 if (parent->NumberOfOwnDescriptors() <= descriptor) break; |
| 2216 result = parent; | 2218 result = parent; |
| 2217 } | 2219 } |
| 2218 return result; | 2220 return result; |
| 2219 } | 2221 } |
| 2220 | 2222 |
| 2221 | 2223 |
| 2222 void Map::UpdateFieldType(int descriptor, Handle<Name> name, | 2224 void Map::UpdateFieldType(int descriptor, Handle<Name> name, |
| 2223 Representation new_representation, | 2225 Representation new_representation, |
| 2224 Handle<HeapType> new_type) { | 2226 Handle<HeapType> new_type) { |
| 2225 DisallowHeapAllocation no_allocation; | 2227 DisallowHeapAllocation no_allocation; |
| 2226 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); | 2228 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); |
| 2227 if (details.type() != FIELD) return; | 2229 if (details.type() != DATA_FIELD) return; |
| 2228 if (HasTransitionArray()) { | 2230 if (HasTransitionArray()) { |
| 2229 TransitionArray* transitions = this->transitions(); | 2231 TransitionArray* transitions = this->transitions(); |
| 2230 for (int i = 0; i < transitions->number_of_transitions(); ++i) { | 2232 for (int i = 0; i < transitions->number_of_transitions(); ++i) { |
| 2231 transitions->GetTarget(i) | 2233 transitions->GetTarget(i) |
| 2232 ->UpdateFieldType(descriptor, name, new_representation, new_type); | 2234 ->UpdateFieldType(descriptor, name, new_representation, new_type); |
| 2233 } | 2235 } |
| 2234 } | 2236 } |
| 2235 // It is allowed to change representation here only from None to something. | 2237 // It is allowed to change representation here only from None to something. |
| 2236 DCHECK(details.representation().Equals(new_representation) || | 2238 DCHECK(details.representation().Equals(new_representation) || |
| 2237 details.representation().IsNone()); | 2239 details.representation().IsNone()); |
| 2238 | 2240 |
| 2239 // Skip if already updated the shared descriptor. | 2241 // Skip if already updated the shared descriptor. |
| 2240 if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return; | 2242 if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return; |
| 2241 FieldDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), | 2243 DataFieldDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), |
| 2242 new_type, details.attributes(), new_representation); | 2244 new_type, details.attributes(), new_representation); |
| 2243 instance_descriptors()->Replace(descriptor, &d); | 2245 instance_descriptors()->Replace(descriptor, &d); |
| 2244 } | 2246 } |
| 2245 | 2247 |
| 2246 | 2248 |
| 2247 // static | 2249 // static |
| 2248 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, | 2250 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, |
| 2249 Handle<HeapType> type2, | 2251 Handle<HeapType> type2, |
| 2250 Isolate* isolate) { | 2252 Isolate* isolate) { |
| 2251 static const int kMaxClassesPerFieldType = 5; | 2253 static const int kMaxClassesPerFieldType = 5; |
| 2252 if (type1->NowIs(type2)) return type2; | 2254 if (type1->NowIs(type2)) return type2; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2344 int old_nof = old_map->NumberOfOwnDescriptors(); | 2346 int old_nof = old_map->NumberOfOwnDescriptors(); |
| 2345 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2347 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 2346 Representation old_representation = old_details.representation(); | 2348 Representation old_representation = old_details.representation(); |
| 2347 | 2349 |
| 2348 // It's fine to transition from None to anything but double without any | 2350 // It's fine to transition from None to anything but double without any |
| 2349 // modification to the object, because the default uninitialized value for | 2351 // modification to the object, because the default uninitialized value for |
| 2350 // representation None can be overwritten by both smi and tagged values. | 2352 // representation None can be overwritten by both smi and tagged values. |
| 2351 // Doubles, however, would require a box allocation. | 2353 // Doubles, however, would require a box allocation. |
| 2352 if (old_representation.IsNone() && !new_representation.IsNone() && | 2354 if (old_representation.IsNone() && !new_representation.IsNone() && |
| 2353 !new_representation.IsDouble()) { | 2355 !new_representation.IsDouble()) { |
| 2354 DCHECK(old_details.type() == FIELD); | 2356 DCHECK(old_details.type() == DATA_FIELD); |
| 2355 if (FLAG_trace_generalization) { | 2357 if (FLAG_trace_generalization) { |
| 2356 old_map->PrintGeneralization( | 2358 old_map->PrintGeneralization( |
| 2357 stdout, "uninitialized field", | 2359 stdout, "uninitialized field", |
| 2358 modify_index, old_map->NumberOfOwnDescriptors(), | 2360 modify_index, old_map->NumberOfOwnDescriptors(), |
| 2359 old_map->NumberOfOwnDescriptors(), false, | 2361 old_map->NumberOfOwnDescriptors(), false, |
| 2360 old_representation, new_representation, | 2362 old_representation, new_representation, |
| 2361 old_descriptors->GetFieldType(modify_index), *new_field_type); | 2363 old_descriptors->GetFieldType(modify_index), *new_field_type); |
| 2362 } | 2364 } |
| 2363 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); | 2365 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); |
| 2364 | 2366 |
| 2365 GeneralizeFieldType(field_owner, modify_index, new_representation, | 2367 GeneralizeFieldType(field_owner, modify_index, new_representation, |
| 2366 new_field_type); | 2368 new_field_type); |
| 2367 DCHECK(old_descriptors->GetDetails(modify_index).representation().Equals( | 2369 DCHECK(old_descriptors->GetDetails(modify_index).representation().Equals( |
| 2368 new_representation)); | 2370 new_representation)); |
| 2369 DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | 2371 DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); |
| 2370 return old_map; | 2372 return old_map; |
| 2371 } | 2373 } |
| 2372 | 2374 |
| 2373 // Check the state of the root map. | 2375 // Check the state of the root map. |
| 2374 Handle<Map> root_map(old_map->FindRootMap(), isolate); | 2376 Handle<Map> root_map(old_map->FindRootMap(), isolate); |
| 2375 if (!old_map->EquivalentToForTransition(*root_map)) { | 2377 if (!old_map->EquivalentToForTransition(*root_map)) { |
| 2376 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2378 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2377 "GenAll_NotEquivalent"); | 2379 "GenAll_NotEquivalent"); |
| 2378 } | 2380 } |
| 2379 int root_nof = root_map->NumberOfOwnDescriptors(); | 2381 int root_nof = root_map->NumberOfOwnDescriptors(); |
| 2380 if (modify_index < root_nof) { | 2382 if (modify_index < root_nof) { |
| 2381 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2383 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 2382 if ((old_details.type() != FIELD && store_mode == FORCE_IN_OBJECT) || | 2384 if ((old_details.type() != DATA_FIELD && store_mode == FORCE_FIELD) || |
| 2383 (old_details.type() == FIELD && | 2385 (old_details.type() == DATA_FIELD && |
| 2384 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | 2386 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || |
| 2385 !new_representation.fits_into(old_details.representation())))) { | 2387 !new_representation.fits_into(old_details.representation())))) { |
| 2386 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2388 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2387 "GenAll_RootModification"); | 2389 "GenAll_RootModification"); |
| 2388 } | 2390 } |
| 2389 } | 2391 } |
| 2390 | 2392 |
| 2391 Handle<Map> target_map = root_map; | 2393 Handle<Map> target_map = root_map; |
| 2392 for (int i = root_nof; i < old_nof; ++i) { | 2394 for (int i = root_nof; i < old_nof; ++i) { |
| 2393 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2395 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2394 int j = target_map->SearchTransition(old_details.kind(), | 2396 int j = target_map->SearchTransition(old_details.kind(), |
| 2395 old_descriptors->GetKey(i), | 2397 old_descriptors->GetKey(i), |
| 2396 old_details.attributes()); | 2398 old_details.attributes()); |
| 2397 if (j == TransitionArray::kNotFound) break; | 2399 if (j == TransitionArray::kNotFound) break; |
| 2398 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2400 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
| 2399 Handle<DescriptorArray> tmp_descriptors = handle( | 2401 Handle<DescriptorArray> tmp_descriptors = handle( |
| 2400 tmp_map->instance_descriptors(), isolate); | 2402 tmp_map->instance_descriptors(), isolate); |
| 2401 | 2403 |
| 2402 // Check if target map is incompatible. | 2404 // Check if target map is incompatible. |
| 2403 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2405 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
| 2404 PropertyType old_type = old_details.type(); | 2406 PropertyType old_type = old_details.type(); |
| 2405 PropertyType tmp_type = tmp_details.type(); | 2407 PropertyType tmp_type = tmp_details.type(); |
| 2406 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 2408 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
| 2407 if ((tmp_type == CALLBACKS || old_type == CALLBACKS) && | 2409 if ((tmp_type == ACCESSOR_CONSTANT || old_type == ACCESSOR_CONSTANT) && |
| 2408 (tmp_type != old_type || | 2410 (tmp_type != old_type || |
| 2409 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2411 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
| 2410 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2412 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2411 "GenAll_Incompatible"); | 2413 "GenAll_Incompatible"); |
| 2412 } | 2414 } |
| 2413 Representation old_representation = old_details.representation(); | 2415 Representation old_representation = old_details.representation(); |
| 2414 Representation tmp_representation = tmp_details.representation(); | 2416 Representation tmp_representation = tmp_details.representation(); |
| 2415 if (!old_representation.fits_into(tmp_representation) || | 2417 if (!old_representation.fits_into(tmp_representation) || |
| 2416 (!new_representation.fits_into(tmp_representation) && | 2418 (!new_representation.fits_into(tmp_representation) && |
| 2417 modify_index == i)) { | 2419 modify_index == i)) { |
| 2418 break; | 2420 break; |
| 2419 } | 2421 } |
| 2420 if (tmp_type == FIELD) { | 2422 if (tmp_type == DATA_FIELD) { |
| 2421 // Generalize the field type as necessary. | 2423 // Generalize the field type as necessary. |
| 2422 Handle<HeapType> old_field_type = (old_type == FIELD) | 2424 Handle<HeapType> old_field_type = |
| 2423 ? handle(old_descriptors->GetFieldType(i), isolate) | 2425 (old_type == DATA_FIELD) |
| 2424 : old_descriptors->GetValue(i)->OptimalType( | 2426 ? handle(old_descriptors->GetFieldType(i), isolate) |
| 2425 isolate, tmp_representation); | 2427 : old_descriptors->GetValue(i) |
| 2428 ->OptimalType(isolate, tmp_representation); |
| 2426 if (modify_index == i) { | 2429 if (modify_index == i) { |
| 2427 old_field_type = GeneralizeFieldType( | 2430 old_field_type = GeneralizeFieldType( |
| 2428 new_field_type, old_field_type, isolate); | 2431 new_field_type, old_field_type, isolate); |
| 2429 } | 2432 } |
| 2430 GeneralizeFieldType(tmp_map, i, tmp_representation, old_field_type); | 2433 GeneralizeFieldType(tmp_map, i, tmp_representation, old_field_type); |
| 2431 } else if (tmp_type == CONSTANT) { | 2434 } else if (tmp_type == DATA_CONSTANT) { |
| 2432 if (old_type != CONSTANT || | 2435 if (old_type != DATA_CONSTANT || |
| 2433 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) { | 2436 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) { |
| 2434 break; | 2437 break; |
| 2435 } | 2438 } |
| 2436 } else { | 2439 } else { |
| 2437 DCHECK_EQ(tmp_type, old_type); | 2440 DCHECK_EQ(tmp_type, old_type); |
| 2438 DCHECK_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i)); | 2441 DCHECK_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i)); |
| 2439 } | 2442 } |
| 2440 target_map = tmp_map; | 2443 target_map = tmp_map; |
| 2441 } | 2444 } |
| 2442 | 2445 |
| 2443 // Directly change the map if the target map is more general. | 2446 // Directly change the map if the target map is more general. |
| 2444 Handle<DescriptorArray> target_descriptors( | 2447 Handle<DescriptorArray> target_descriptors( |
| 2445 target_map->instance_descriptors(), isolate); | 2448 target_map->instance_descriptors(), isolate); |
| 2446 int target_nof = target_map->NumberOfOwnDescriptors(); | 2449 int target_nof = target_map->NumberOfOwnDescriptors(); |
| 2447 if (target_nof == old_nof && | 2450 if (target_nof == old_nof && |
| 2448 (store_mode != FORCE_IN_OBJECT || | 2451 (store_mode != FORCE_FIELD || |
| 2449 target_descriptors->GetDetails(modify_index).type() == FIELD)) { | 2452 target_descriptors->GetDetails(modify_index).type() == DATA_FIELD)) { |
| 2450 DCHECK(modify_index < target_nof); | 2453 DCHECK(modify_index < target_nof); |
| 2451 DCHECK(new_representation.fits_into( | 2454 DCHECK(new_representation.fits_into( |
| 2452 target_descriptors->GetDetails(modify_index).representation())); | 2455 target_descriptors->GetDetails(modify_index).representation())); |
| 2453 DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD || | 2456 DCHECK( |
| 2454 new_field_type->NowIs( | 2457 target_descriptors->GetDetails(modify_index).type() != DATA_FIELD || |
| 2455 target_descriptors->GetFieldType(modify_index))); | 2458 new_field_type->NowIs(target_descriptors->GetFieldType(modify_index))); |
| 2456 return target_map; | 2459 return target_map; |
| 2457 } | 2460 } |
| 2458 | 2461 |
| 2459 // Find the last compatible target map in the transition tree. | 2462 // Find the last compatible target map in the transition tree. |
| 2460 for (int i = target_nof; i < old_nof; ++i) { | 2463 for (int i = target_nof; i < old_nof; ++i) { |
| 2461 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2464 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2462 int j = target_map->SearchTransition(old_details.kind(), | 2465 int j = target_map->SearchTransition(old_details.kind(), |
| 2463 old_descriptors->GetKey(i), | 2466 old_descriptors->GetKey(i), |
| 2464 old_details.attributes()); | 2467 old_details.attributes()); |
| 2465 if (j == TransitionArray::kNotFound) break; | 2468 if (j == TransitionArray::kNotFound) break; |
| 2466 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2469 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
| 2467 Handle<DescriptorArray> tmp_descriptors( | 2470 Handle<DescriptorArray> tmp_descriptors( |
| 2468 tmp_map->instance_descriptors(), isolate); | 2471 tmp_map->instance_descriptors(), isolate); |
| 2469 | 2472 |
| 2470 // Check if target map is compatible. | 2473 // Check if target map is compatible. |
| 2471 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2474 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
| 2472 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 2475 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
| 2473 if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && | 2476 if ((tmp_details.type() == ACCESSOR_CONSTANT || |
| 2477 old_details.type() == ACCESSOR_CONSTANT) && |
| 2474 (tmp_details.type() != old_details.type() || | 2478 (tmp_details.type() != old_details.type() || |
| 2475 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2479 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
| 2476 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2480 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2477 "GenAll_Incompatible"); | 2481 "GenAll_Incompatible"); |
| 2478 } | 2482 } |
| 2479 target_map = tmp_map; | 2483 target_map = tmp_map; |
| 2480 } | 2484 } |
| 2481 target_nof = target_map->NumberOfOwnDescriptors(); | 2485 target_nof = target_map->NumberOfOwnDescriptors(); |
| 2482 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 2486 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
| 2483 | 2487 |
| 2484 // Allocate a new descriptor array large enough to hold the required | 2488 // Allocate a new descriptor array large enough to hold the required |
| 2485 // descriptors, with minimally the exact same size as the old descriptor | 2489 // descriptors, with minimally the exact same size as the old descriptor |
| 2486 // array. | 2490 // array. |
| 2487 int new_slack = Max( | 2491 int new_slack = Max( |
| 2488 old_nof, old_descriptors->number_of_descriptors()) - old_nof; | 2492 old_nof, old_descriptors->number_of_descriptors()) - old_nof; |
| 2489 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( | 2493 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( |
| 2490 isolate, old_nof, new_slack); | 2494 isolate, old_nof, new_slack); |
| 2491 DCHECK(new_descriptors->length() > target_descriptors->length() || | 2495 DCHECK(new_descriptors->length() > target_descriptors->length() || |
| 2492 new_descriptors->NumberOfSlackDescriptors() > 0 || | 2496 new_descriptors->NumberOfSlackDescriptors() > 0 || |
| 2493 new_descriptors->number_of_descriptors() == | 2497 new_descriptors->number_of_descriptors() == |
| 2494 old_descriptors->number_of_descriptors()); | 2498 old_descriptors->number_of_descriptors()); |
| 2495 DCHECK(new_descriptors->number_of_descriptors() == old_nof); | 2499 DCHECK(new_descriptors->number_of_descriptors() == old_nof); |
| 2496 | 2500 |
| 2497 // 0 -> |root_nof| | 2501 // 0 -> |root_nof| |
| 2498 int current_offset = 0; | 2502 int current_offset = 0; |
| 2499 for (int i = 0; i < root_nof; ++i) { | 2503 for (int i = 0; i < root_nof; ++i) { |
| 2500 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2504 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2501 if (old_details.type() == FIELD) { | 2505 if (old_details.type() == DATA_FIELD) { |
| 2502 current_offset += old_details.field_width_in_words(); | 2506 current_offset += old_details.field_width_in_words(); |
| 2503 } | 2507 } |
| 2504 Descriptor d(handle(old_descriptors->GetKey(i), isolate), | 2508 Descriptor d(handle(old_descriptors->GetKey(i), isolate), |
| 2505 handle(old_descriptors->GetValue(i), isolate), | 2509 handle(old_descriptors->GetValue(i), isolate), |
| 2506 old_details); | 2510 old_details); |
| 2507 new_descriptors->Set(i, &d); | 2511 new_descriptors->Set(i, &d); |
| 2508 } | 2512 } |
| 2509 | 2513 |
| 2510 // |root_nof| -> |target_nof| | 2514 // |root_nof| -> |target_nof| |
| 2511 for (int i = root_nof; i < target_nof; ++i) { | 2515 for (int i = root_nof; i < target_nof; ++i) { |
| 2512 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); | 2516 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); |
| 2513 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2517 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2514 PropertyDetails target_details = target_descriptors->GetDetails(i); | 2518 PropertyDetails target_details = target_descriptors->GetDetails(i); |
| 2515 target_details = target_details.CopyWithRepresentation( | 2519 target_details = target_details.CopyWithRepresentation( |
| 2516 old_details.representation().generalize( | 2520 old_details.representation().generalize( |
| 2517 target_details.representation())); | 2521 target_details.representation())); |
| 2518 if (modify_index == i) { | 2522 if (modify_index == i) { |
| 2519 target_details = target_details.CopyWithRepresentation( | 2523 target_details = target_details.CopyWithRepresentation( |
| 2520 new_representation.generalize(target_details.representation())); | 2524 new_representation.generalize(target_details.representation())); |
| 2521 } | 2525 } |
| 2522 DCHECK_EQ(old_details.attributes(), target_details.attributes()); | 2526 DCHECK_EQ(old_details.attributes(), target_details.attributes()); |
| 2523 if (old_details.type() == FIELD || target_details.type() == FIELD || | 2527 if (old_details.type() == DATA_FIELD || |
| 2524 (modify_index == i && store_mode == FORCE_IN_OBJECT) || | 2528 target_details.type() == DATA_FIELD || |
| 2529 (modify_index == i && store_mode == FORCE_FIELD) || |
| 2525 (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2530 (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
| 2526 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | 2531 Handle<HeapType> old_field_type = |
| 2527 ? handle(old_descriptors->GetFieldType(i), isolate) | 2532 (old_details.type() == DATA_FIELD) |
| 2528 : old_descriptors->GetValue(i)->OptimalType( | 2533 ? handle(old_descriptors->GetFieldType(i), isolate) |
| 2529 isolate, target_details.representation()); | 2534 : old_descriptors->GetValue(i) |
| 2530 Handle<HeapType> target_field_type = (target_details.type() == FIELD) | 2535 ->OptimalType(isolate, target_details.representation()); |
| 2531 ? handle(target_descriptors->GetFieldType(i), isolate) | 2536 Handle<HeapType> target_field_type = |
| 2532 : target_descriptors->GetValue(i)->OptimalType( | 2537 (target_details.type() == DATA_FIELD) |
| 2533 isolate, target_details.representation()); | 2538 ? handle(target_descriptors->GetFieldType(i), isolate) |
| 2539 : target_descriptors->GetValue(i) |
| 2540 ->OptimalType(isolate, target_details.representation()); |
| 2534 target_field_type = GeneralizeFieldType( | 2541 target_field_type = GeneralizeFieldType( |
| 2535 target_field_type, old_field_type, isolate); | 2542 target_field_type, old_field_type, isolate); |
| 2536 if (modify_index == i) { | 2543 if (modify_index == i) { |
| 2537 target_field_type = GeneralizeFieldType( | 2544 target_field_type = GeneralizeFieldType( |
| 2538 target_field_type, new_field_type, isolate); | 2545 target_field_type, new_field_type, isolate); |
| 2539 } | 2546 } |
| 2540 FieldDescriptor d(target_key, current_offset, target_field_type, | 2547 DataFieldDescriptor d(target_key, current_offset, target_field_type, |
| 2541 target_details.attributes(), | 2548 target_details.attributes(), |
| 2542 target_details.representation()); | 2549 target_details.representation()); |
| 2543 current_offset += d.GetDetails().field_width_in_words(); | 2550 current_offset += d.GetDetails().field_width_in_words(); |
| 2544 new_descriptors->Set(i, &d); | 2551 new_descriptors->Set(i, &d); |
| 2545 } else { | 2552 } else { |
| 2546 DCHECK_NE(FIELD, target_details.type()); | 2553 DCHECK_NE(DATA_FIELD, target_details.type()); |
| 2547 Descriptor d(target_key, | 2554 Descriptor d(target_key, |
| 2548 handle(target_descriptors->GetValue(i), isolate), | 2555 handle(target_descriptors->GetValue(i), isolate), |
| 2549 target_details); | 2556 target_details); |
| 2550 new_descriptors->Set(i, &d); | 2557 new_descriptors->Set(i, &d); |
| 2551 } | 2558 } |
| 2552 } | 2559 } |
| 2553 | 2560 |
| 2554 // |target_nof| -> |old_nof| | 2561 // |target_nof| -> |old_nof| |
| 2555 for (int i = target_nof; i < old_nof; ++i) { | 2562 for (int i = target_nof; i < old_nof; ++i) { |
| 2556 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2563 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2557 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); | 2564 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); |
| 2558 if (modify_index == i) { | 2565 if (modify_index == i) { |
| 2559 old_details = old_details.CopyWithRepresentation( | 2566 old_details = old_details.CopyWithRepresentation( |
| 2560 new_representation.generalize(old_details.representation())); | 2567 new_representation.generalize(old_details.representation())); |
| 2561 } | 2568 } |
| 2562 if (old_details.type() == FIELD) { | 2569 if (old_details.type() == DATA_FIELD) { |
| 2563 Handle<HeapType> old_field_type( | 2570 Handle<HeapType> old_field_type( |
| 2564 old_descriptors->GetFieldType(i), isolate); | 2571 old_descriptors->GetFieldType(i), isolate); |
| 2565 if (modify_index == i) { | 2572 if (modify_index == i) { |
| 2566 old_field_type = GeneralizeFieldType( | 2573 old_field_type = GeneralizeFieldType( |
| 2567 old_field_type, new_field_type, isolate); | 2574 old_field_type, new_field_type, isolate); |
| 2568 } | 2575 } |
| 2569 FieldDescriptor d(old_key, current_offset, old_field_type, | 2576 DataFieldDescriptor d(old_key, current_offset, old_field_type, |
| 2570 old_details.attributes(), old_details.representation()); | 2577 old_details.attributes(), |
| 2578 old_details.representation()); |
| 2571 current_offset += d.GetDetails().field_width_in_words(); | 2579 current_offset += d.GetDetails().field_width_in_words(); |
| 2572 new_descriptors->Set(i, &d); | 2580 new_descriptors->Set(i, &d); |
| 2573 } else { | 2581 } else { |
| 2574 DCHECK(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); | 2582 DCHECK(old_details.type() == DATA_CONSTANT || |
| 2575 if (modify_index == i && store_mode == FORCE_IN_OBJECT) { | 2583 old_details.type() == ACCESSOR_CONSTANT); |
| 2576 FieldDescriptor d( | 2584 if (modify_index == i && store_mode == FORCE_FIELD) { |
| 2585 DataFieldDescriptor d( |
| 2577 old_key, current_offset, | 2586 old_key, current_offset, |
| 2578 GeneralizeFieldType(old_descriptors->GetValue(i)->OptimalType( | 2587 GeneralizeFieldType(old_descriptors->GetValue(i)->OptimalType( |
| 2579 isolate, old_details.representation()), | 2588 isolate, old_details.representation()), |
| 2580 new_field_type, isolate), | 2589 new_field_type, isolate), |
| 2581 old_details.attributes(), old_details.representation()); | 2590 old_details.attributes(), old_details.representation()); |
| 2582 current_offset += d.GetDetails().field_width_in_words(); | 2591 current_offset += d.GetDetails().field_width_in_words(); |
| 2583 new_descriptors->Set(i, &d); | 2592 new_descriptors->Set(i, &d); |
| 2584 } else { | 2593 } else { |
| 2585 DCHECK_NE(FIELD, old_details.type()); | 2594 DCHECK_NE(DATA_FIELD, old_details.type()); |
| 2586 Descriptor d(old_key, | 2595 Descriptor d(old_key, |
| 2587 handle(old_descriptors->GetValue(i), isolate), | 2596 handle(old_descriptors->GetValue(i), isolate), |
| 2588 old_details); | 2597 old_details); |
| 2589 new_descriptors->Set(i, &d); | 2598 new_descriptors->Set(i, &d); |
| 2590 } | 2599 } |
| 2591 } | 2600 } |
| 2592 } | 2601 } |
| 2593 | 2602 |
| 2594 new_descriptors->Sort(); | 2603 new_descriptors->Sort(); |
| 2595 | 2604 |
| 2596 DCHECK(store_mode != FORCE_IN_OBJECT || | 2605 DCHECK(store_mode != FORCE_FIELD || |
| 2597 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2606 new_descriptors->GetDetails(modify_index).type() == DATA_FIELD); |
| 2598 | 2607 |
| 2599 Handle<Map> split_map(root_map->FindLastMatchMap( | 2608 Handle<Map> split_map(root_map->FindLastMatchMap( |
| 2600 root_nof, old_nof, *new_descriptors), isolate); | 2609 root_nof, old_nof, *new_descriptors), isolate); |
| 2601 int split_nof = split_map->NumberOfOwnDescriptors(); | 2610 int split_nof = split_map->NumberOfOwnDescriptors(); |
| 2602 DCHECK_NE(old_nof, split_nof); | 2611 DCHECK_NE(old_nof, split_nof); |
| 2603 | 2612 |
| 2604 Handle<LayoutDescriptor> new_layout_descriptor = | 2613 Handle<LayoutDescriptor> new_layout_descriptor = |
| 2605 LayoutDescriptor::New(split_map, new_descriptors, old_nof); | 2614 LayoutDescriptor::New(split_map, new_descriptors, old_nof); |
| 2606 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); | 2615 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); |
| 2607 bool transition_target_deprecated = split_map->DeprecateTarget( | 2616 bool transition_target_deprecated = split_map->DeprecateTarget( |
| 2608 split_prop_details.kind(), old_descriptors->GetKey(split_nof), | 2617 split_prop_details.kind(), old_descriptors->GetKey(split_nof), |
| 2609 split_prop_details.attributes(), *new_descriptors, | 2618 split_prop_details.attributes(), *new_descriptors, |
| 2610 *new_layout_descriptor); | 2619 *new_layout_descriptor); |
| 2611 | 2620 |
| 2612 // If |transition_target_deprecated| is true then the transition array | 2621 // If |transition_target_deprecated| is true then the transition array |
| 2613 // already contains entry for given descriptor. This means that the transition | 2622 // already contains entry for given descriptor. This means that the transition |
| 2614 // could be inserted regardless of whether transitions array is full or not. | 2623 // could be inserted regardless of whether transitions array is full or not. |
| 2615 if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) { | 2624 if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) { |
| 2616 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2625 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2617 "GenAll_CantHaveMoreTransitions"); | 2626 "GenAll_CantHaveMoreTransitions"); |
| 2618 } | 2627 } |
| 2619 | 2628 |
| 2620 if (FLAG_trace_generalization) { | 2629 if (FLAG_trace_generalization) { |
| 2621 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2630 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 2622 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 2631 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
| 2623 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | 2632 Handle<HeapType> old_field_type = |
| 2624 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 2633 (old_details.type() == DATA_FIELD) |
| 2625 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), | 2634 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
| 2626 isolate), isolate); | 2635 : HeapType::Constant( |
| 2627 Handle<HeapType> new_field_type = (new_details.type() == FIELD) | 2636 handle(old_descriptors->GetValue(modify_index), isolate), |
| 2628 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | 2637 isolate); |
| 2629 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), | 2638 Handle<HeapType> new_field_type = |
| 2630 isolate), isolate); | 2639 (new_details.type() == DATA_FIELD) |
| 2640 ? handle(new_descriptors->GetFieldType(modify_index), isolate) |
| 2641 : HeapType::Constant( |
| 2642 handle(new_descriptors->GetValue(modify_index), isolate), |
| 2643 isolate); |
| 2631 old_map->PrintGeneralization( | 2644 old_map->PrintGeneralization( |
| 2632 stdout, "", modify_index, split_nof, old_nof, | 2645 stdout, "", modify_index, split_nof, old_nof, |
| 2633 old_details.type() == CONSTANT && store_mode == FORCE_IN_OBJECT, | 2646 old_details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, |
| 2634 old_details.representation(), new_details.representation(), | 2647 old_details.representation(), new_details.representation(), |
| 2635 *old_field_type, *new_field_type); | 2648 *old_field_type, *new_field_type); |
| 2636 } | 2649 } |
| 2637 | 2650 |
| 2638 // Add missing transitions. | 2651 // Add missing transitions. |
| 2639 Handle<Map> new_map = split_map; | 2652 Handle<Map> new_map = split_map; |
| 2640 for (int i = split_nof; i < old_nof; ++i) { | 2653 for (int i = split_nof; i < old_nof; ++i) { |
| 2641 new_map = CopyInstallDescriptors(new_map, i, new_descriptors, | 2654 new_map = CopyInstallDescriptors(new_map, i, new_descriptors, |
| 2642 new_layout_descriptor); | 2655 new_layout_descriptor); |
| 2643 } | 2656 } |
| 2644 new_map->set_owns_descriptors(true); | 2657 new_map->set_owns_descriptors(true); |
| 2645 return new_map; | 2658 return new_map; |
| 2646 } | 2659 } |
| 2647 | 2660 |
| 2648 | 2661 |
| 2649 // Generalize the representation of all FIELD descriptors. | 2662 // Generalize the representation of all DATA_FIELD descriptors. |
| 2650 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2663 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
| 2651 Handle<Map> map) { | 2664 Handle<Map> map) { |
| 2652 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2665 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 2653 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { | 2666 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
| 2654 if (descriptors->GetDetails(i).type() == FIELD) { | 2667 if (descriptors->GetDetails(i).type() == DATA_FIELD) { |
| 2655 map = GeneralizeRepresentation(map, i, Representation::Tagged(), | 2668 map = GeneralizeRepresentation(map, i, Representation::Tagged(), |
| 2656 HeapType::Any(map->GetIsolate()), | 2669 HeapType::Any(map->GetIsolate()), |
| 2657 FORCE_IN_OBJECT); | 2670 FORCE_FIELD); |
| 2658 } | 2671 } |
| 2659 } | 2672 } |
| 2660 return map; | 2673 return map; |
| 2661 } | 2674 } |
| 2662 | 2675 |
| 2663 | 2676 |
| 2664 // static | 2677 // static |
| 2665 MaybeHandle<Map> Map::TryUpdate(Handle<Map> map) { | 2678 MaybeHandle<Map> Map::TryUpdate(Handle<Map> map) { |
| 2666 Handle<Map> proto_map(map); | 2679 Handle<Map> proto_map(map); |
| 2667 while (proto_map->prototype()->IsJSObject()) { | 2680 while (proto_map->prototype()->IsJSObject()) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2711 | 2724 |
| 2712 PropertyDetails new_details = new_descriptors->GetDetails(i); | 2725 PropertyDetails new_details = new_descriptors->GetDetails(i); |
| 2713 DCHECK_EQ(old_details.kind(), new_details.kind()); | 2726 DCHECK_EQ(old_details.kind(), new_details.kind()); |
| 2714 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 2727 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
| 2715 if (!old_details.representation().fits_into(new_details.representation())) { | 2728 if (!old_details.representation().fits_into(new_details.representation())) { |
| 2716 return MaybeHandle<Map>(); | 2729 return MaybeHandle<Map>(); |
| 2717 } | 2730 } |
| 2718 Object* new_value = new_descriptors->GetValue(i); | 2731 Object* new_value = new_descriptors->GetValue(i); |
| 2719 Object* old_value = old_descriptors->GetValue(i); | 2732 Object* old_value = old_descriptors->GetValue(i); |
| 2720 switch (new_details.type()) { | 2733 switch (new_details.type()) { |
| 2721 case FIELD: { | 2734 case DATA_FIELD: { |
| 2722 PropertyType old_type = old_details.type(); | 2735 PropertyType old_type = old_details.type(); |
| 2723 if (old_type == FIELD) { | 2736 if (old_type == DATA_FIELD) { |
| 2724 if (!HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) { | 2737 if (!HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) { |
| 2725 return MaybeHandle<Map>(); | 2738 return MaybeHandle<Map>(); |
| 2726 } | 2739 } |
| 2727 } else { | 2740 } else { |
| 2728 DCHECK(old_type == CONSTANT); | 2741 DCHECK(old_type == DATA_CONSTANT); |
| 2729 if (!HeapType::cast(new_value)->NowContains(old_value)) { | 2742 if (!HeapType::cast(new_value)->NowContains(old_value)) { |
| 2730 return MaybeHandle<Map>(); | 2743 return MaybeHandle<Map>(); |
| 2731 } | 2744 } |
| 2732 } | 2745 } |
| 2733 break; | 2746 break; |
| 2734 } | 2747 } |
| 2735 case ACCESSOR_FIELD: | 2748 case ACCESSOR_FIELD: |
| 2736 DCHECK(HeapType::Any()->Is(HeapType::cast(new_value))); | 2749 DCHECK(HeapType::Any()->Is(HeapType::cast(new_value))); |
| 2737 break; | 2750 break; |
| 2738 | 2751 |
| 2739 case CONSTANT: | 2752 case DATA_CONSTANT: |
| 2740 case CALLBACKS: | 2753 case ACCESSOR_CONSTANT: |
| 2741 if (old_details.location() == IN_OBJECT || old_value != new_value) { | 2754 if (old_details.location() == FIELD || old_value != new_value) { |
| 2742 return MaybeHandle<Map>(); | 2755 return MaybeHandle<Map>(); |
| 2743 } | 2756 } |
| 2744 break; | 2757 break; |
| 2745 } | 2758 } |
| 2746 } | 2759 } |
| 2747 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); | 2760 if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>(); |
| 2748 return handle(new_map); | 2761 return handle(new_map); |
| 2749 } | 2762 } |
| 2750 | 2763 |
| 2751 | 2764 |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3029 } | 3042 } |
| 3030 Handle<JSObject> js_proto = | 3043 Handle<JSObject> js_proto = |
| 3031 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 3044 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 3032 if (!js_proto->HasDictionaryElements()) { | 3045 if (!js_proto->HasDictionaryElements()) { |
| 3033 continue; | 3046 continue; |
| 3034 } | 3047 } |
| 3035 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); | 3048 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); |
| 3036 int entry = dictionary->FindEntry(index); | 3049 int entry = dictionary->FindEntry(index); |
| 3037 if (entry != SeededNumberDictionary::kNotFound) { | 3050 if (entry != SeededNumberDictionary::kNotFound) { |
| 3038 PropertyDetails details = dictionary->DetailsAt(entry); | 3051 PropertyDetails details = dictionary->DetailsAt(entry); |
| 3039 if (details.type() == CALLBACKS) { | 3052 if (details.type() == ACCESSOR_CONSTANT) { |
| 3040 *found = true; | 3053 *found = true; |
| 3041 Handle<Object> structure(dictionary->ValueAt(entry), isolate); | 3054 Handle<Object> structure(dictionary->ValueAt(entry), isolate); |
| 3042 return SetElementWithCallback(object, structure, index, value, js_proto, | 3055 return SetElementWithCallback(object, structure, index, value, js_proto, |
| 3043 strict_mode); | 3056 strict_mode); |
| 3044 } | 3057 } |
| 3045 } | 3058 } |
| 3046 } | 3059 } |
| 3047 *found = false; | 3060 *found = false; |
| 3048 return isolate->factory()->the_hole_value(); | 3061 return isolate->factory()->the_hole_value(); |
| 3049 } | 3062 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3136 int valid_descriptors, | 3149 int valid_descriptors, |
| 3137 Handle<DescriptorArray> array) { | 3150 Handle<DescriptorArray> array) { |
| 3138 DisallowHeapAllocation no_gc; | 3151 DisallowHeapAllocation no_gc; |
| 3139 return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound; | 3152 return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound; |
| 3140 } | 3153 } |
| 3141 static void Insert(Handle<Name> key, | 3154 static void Insert(Handle<Name> key, |
| 3142 Handle<AccessorInfo> entry, | 3155 Handle<AccessorInfo> entry, |
| 3143 int valid_descriptors, | 3156 int valid_descriptors, |
| 3144 Handle<DescriptorArray> array) { | 3157 Handle<DescriptorArray> array) { |
| 3145 DisallowHeapAllocation no_gc; | 3158 DisallowHeapAllocation no_gc; |
| 3146 CallbacksDescriptor desc(key, entry, entry->property_attributes()); | 3159 AccessorConstantDescriptor desc(key, entry, entry->property_attributes()); |
| 3147 array->Append(&desc); | 3160 array->Append(&desc); |
| 3148 } | 3161 } |
| 3149 }; | 3162 }; |
| 3150 | 3163 |
| 3151 | 3164 |
| 3152 struct FixedArrayAppender { | 3165 struct FixedArrayAppender { |
| 3153 typedef FixedArray Array; | 3166 typedef FixedArray Array; |
| 3154 static bool Contains(Handle<Name> key, | 3167 static bool Contains(Handle<Name> key, |
| 3155 Handle<AccessorInfo> entry, | 3168 Handle<AccessorInfo> entry, |
| 3156 int valid_descriptors, | 3169 int valid_descriptors, |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3766 return true; | 3779 return true; |
| 3767 } | 3780 } |
| 3768 | 3781 |
| 3769 | 3782 |
| 3770 void JSObject::WriteToField(int descriptor, Object* value) { | 3783 void JSObject::WriteToField(int descriptor, Object* value) { |
| 3771 DisallowHeapAllocation no_gc; | 3784 DisallowHeapAllocation no_gc; |
| 3772 | 3785 |
| 3773 DescriptorArray* desc = map()->instance_descriptors(); | 3786 DescriptorArray* desc = map()->instance_descriptors(); |
| 3774 PropertyDetails details = desc->GetDetails(descriptor); | 3787 PropertyDetails details = desc->GetDetails(descriptor); |
| 3775 | 3788 |
| 3776 DCHECK(details.type() == FIELD); | 3789 DCHECK(details.type() == DATA_FIELD); |
| 3777 | 3790 |
| 3778 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); | 3791 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); |
| 3779 if (details.representation().IsDouble()) { | 3792 if (details.representation().IsDouble()) { |
| 3780 // Nothing more to be done. | 3793 // Nothing more to be done. |
| 3781 if (value->IsUninitialized()) return; | 3794 if (value->IsUninitialized()) return; |
| 3782 if (IsUnboxedDoubleField(index)) { | 3795 if (IsUnboxedDoubleField(index)) { |
| 3783 RawFastDoublePropertyAtPut(index, value->Number()); | 3796 RawFastDoublePropertyAtPut(index, value->Number()); |
| 3784 } else { | 3797 } else { |
| 3785 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | 3798 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); |
| 3786 DCHECK(box->IsMutableHeapNumber()); | 3799 DCHECK(box->IsMutableHeapNumber()); |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4204 property_count += 2; // Make space for two more properties. | 4217 property_count += 2; // Make space for two more properties. |
| 4205 } | 4218 } |
| 4206 Handle<NameDictionary> dictionary = | 4219 Handle<NameDictionary> dictionary = |
| 4207 NameDictionary::New(isolate, property_count); | 4220 NameDictionary::New(isolate, property_count); |
| 4208 | 4221 |
| 4209 Handle<DescriptorArray> descs(map->instance_descriptors()); | 4222 Handle<DescriptorArray> descs(map->instance_descriptors()); |
| 4210 for (int i = 0; i < real_size; i++) { | 4223 for (int i = 0; i < real_size; i++) { |
| 4211 PropertyDetails details = descs->GetDetails(i); | 4224 PropertyDetails details = descs->GetDetails(i); |
| 4212 Handle<Name> key(descs->GetKey(i)); | 4225 Handle<Name> key(descs->GetKey(i)); |
| 4213 switch (details.type()) { | 4226 switch (details.type()) { |
| 4214 case CONSTANT: { | 4227 case DATA_CONSTANT: { |
| 4215 Handle<Object> value(descs->GetConstant(i), isolate); | 4228 Handle<Object> value(descs->GetConstant(i), isolate); |
| 4216 PropertyDetails d(details.attributes(), FIELD, i + 1); | 4229 PropertyDetails d(details.attributes(), DATA_FIELD, i + 1); |
| 4217 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4230 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 4218 break; | 4231 break; |
| 4219 } | 4232 } |
| 4220 case FIELD: { | 4233 case DATA_FIELD: { |
| 4221 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 4234 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
| 4222 Handle<Object> value; | 4235 Handle<Object> value; |
| 4223 if (object->IsUnboxedDoubleField(index)) { | 4236 if (object->IsUnboxedDoubleField(index)) { |
| 4224 double old_value = object->RawFastDoublePropertyAt(index); | 4237 double old_value = object->RawFastDoublePropertyAt(index); |
| 4225 value = isolate->factory()->NewHeapNumber(old_value); | 4238 value = isolate->factory()->NewHeapNumber(old_value); |
| 4226 } else { | 4239 } else { |
| 4227 value = handle(object->RawFastPropertyAt(index), isolate); | 4240 value = handle(object->RawFastPropertyAt(index), isolate); |
| 4228 if (details.representation().IsDouble()) { | 4241 if (details.representation().IsDouble()) { |
| 4229 DCHECK(value->IsMutableHeapNumber()); | 4242 DCHECK(value->IsMutableHeapNumber()); |
| 4230 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); | 4243 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); |
| 4231 value = isolate->factory()->NewHeapNumber(old->value()); | 4244 value = isolate->factory()->NewHeapNumber(old->value()); |
| 4232 } | 4245 } |
| 4233 } | 4246 } |
| 4234 PropertyDetails d(details.attributes(), FIELD, i + 1); | 4247 PropertyDetails d(details.attributes(), DATA_FIELD, i + 1); |
| 4235 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4248 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 4236 break; | 4249 break; |
| 4237 } | 4250 } |
| 4238 case ACCESSOR_FIELD: { | 4251 case ACCESSOR_FIELD: { |
| 4239 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 4252 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
| 4240 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 4253 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
| 4241 PropertyDetails d(details.attributes(), CALLBACKS, i + 1); | 4254 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1); |
| 4242 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4255 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 4243 break; | 4256 break; |
| 4244 } | 4257 } |
| 4245 case CALLBACKS: { | 4258 case ACCESSOR_CONSTANT: { |
| 4246 Handle<Object> value(descs->GetCallbacksObject(i), isolate); | 4259 Handle<Object> value(descs->GetCallbacksObject(i), isolate); |
| 4247 PropertyDetails d(details.attributes(), CALLBACKS, i + 1); | 4260 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1); |
| 4248 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4261 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 4249 break; | 4262 break; |
| 4250 } | 4263 } |
| 4251 } | 4264 } |
| 4252 } | 4265 } |
| 4253 | 4266 |
| 4254 // Copy the next enumeration index from instance descriptor. | 4267 // Copy the next enumeration index from instance descriptor. |
| 4255 dictionary->SetNextEnumerationIndex(real_size + 1); | 4268 dictionary->SetNextEnumerationIndex(real_size + 1); |
| 4256 | 4269 |
| 4257 // From here on we cannot fail and we shouldn't GC anymore. | 4270 // From here on we cannot fail and we shouldn't GC anymore. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4321 int instance_descriptor_length = iteration_order->length(); | 4334 int instance_descriptor_length = iteration_order->length(); |
| 4322 int number_of_fields = 0; | 4335 int number_of_fields = 0; |
| 4323 | 4336 |
| 4324 // Compute the length of the instance descriptor. | 4337 // Compute the length of the instance descriptor. |
| 4325 for (int i = 0; i < instance_descriptor_length; i++) { | 4338 for (int i = 0; i < instance_descriptor_length; i++) { |
| 4326 int index = Smi::cast(iteration_order->get(i))->value(); | 4339 int index = Smi::cast(iteration_order->get(i))->value(); |
| 4327 DCHECK(dictionary->IsKey(dictionary->KeyAt(index))); | 4340 DCHECK(dictionary->IsKey(dictionary->KeyAt(index))); |
| 4328 | 4341 |
| 4329 Object* value = dictionary->ValueAt(index); | 4342 Object* value = dictionary->ValueAt(index); |
| 4330 PropertyType type = dictionary->DetailsAt(index).type(); | 4343 PropertyType type = dictionary->DetailsAt(index).type(); |
| 4331 if (type == FIELD && !value->IsJSFunction()) { | 4344 if (type == DATA_FIELD && !value->IsJSFunction()) { |
| 4332 number_of_fields += 1; | 4345 number_of_fields += 1; |
| 4333 } | 4346 } |
| 4334 } | 4347 } |
| 4335 | 4348 |
| 4336 int inobject_props = object->map()->inobject_properties(); | 4349 int inobject_props = object->map()->inobject_properties(); |
| 4337 | 4350 |
| 4338 // Allocate new map. | 4351 // Allocate new map. |
| 4339 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 4352 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
| 4340 new_map->set_dictionary_map(false); | 4353 new_map->set_dictionary_map(false); |
| 4341 | 4354 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4390 // Ensure the key is a unique name before writing into the | 4403 // Ensure the key is a unique name before writing into the |
| 4391 // instance descriptor. | 4404 // instance descriptor. |
| 4392 key = factory->InternalizeString(handle(String::cast(k))); | 4405 key = factory->InternalizeString(handle(String::cast(k))); |
| 4393 } | 4406 } |
| 4394 | 4407 |
| 4395 PropertyDetails details = dictionary->DetailsAt(index); | 4408 PropertyDetails details = dictionary->DetailsAt(index); |
| 4396 int enumeration_index = details.dictionary_index(); | 4409 int enumeration_index = details.dictionary_index(); |
| 4397 PropertyType type = details.type(); | 4410 PropertyType type = details.type(); |
| 4398 | 4411 |
| 4399 if (value->IsJSFunction()) { | 4412 if (value->IsJSFunction()) { |
| 4400 ConstantDescriptor d(key, handle(value, isolate), details.attributes()); | 4413 DataConstantDescriptor d(key, handle(value, isolate), |
| 4414 details.attributes()); |
| 4401 descriptors->Set(enumeration_index - 1, &d); | 4415 descriptors->Set(enumeration_index - 1, &d); |
| 4402 } else if (type == FIELD) { | 4416 } else if (type == DATA_FIELD) { |
| 4403 if (current_offset < inobject_props) { | 4417 if (current_offset < inobject_props) { |
| 4404 object->InObjectPropertyAtPut(current_offset, value, | 4418 object->InObjectPropertyAtPut(current_offset, value, |
| 4405 UPDATE_WRITE_BARRIER); | 4419 UPDATE_WRITE_BARRIER); |
| 4406 } else { | 4420 } else { |
| 4407 int offset = current_offset - inobject_props; | 4421 int offset = current_offset - inobject_props; |
| 4408 fields->set(offset, value); | 4422 fields->set(offset, value); |
| 4409 } | 4423 } |
| 4410 FieldDescriptor d(key, current_offset, details.attributes(), | 4424 DataFieldDescriptor d(key, current_offset, details.attributes(), |
| 4411 // TODO(verwaest): value->OptimalRepresentation(); | 4425 // TODO(verwaest): value->OptimalRepresentation(); |
| 4412 Representation::Tagged()); | 4426 Representation::Tagged()); |
| 4413 current_offset += d.GetDetails().field_width_in_words(); | 4427 current_offset += d.GetDetails().field_width_in_words(); |
| 4414 descriptors->Set(enumeration_index - 1, &d); | 4428 descriptors->Set(enumeration_index - 1, &d); |
| 4415 } else if (type == CALLBACKS) { | 4429 } else if (type == ACCESSOR_CONSTANT) { |
| 4416 CallbacksDescriptor d(key, handle(value, isolate), details.attributes()); | 4430 AccessorConstantDescriptor d(key, handle(value, isolate), |
| 4431 details.attributes()); |
| 4417 descriptors->Set(enumeration_index - 1, &d); | 4432 descriptors->Set(enumeration_index - 1, &d); |
| 4418 } else { | 4433 } else { |
| 4419 UNREACHABLE(); | 4434 UNREACHABLE(); |
| 4420 } | 4435 } |
| 4421 } | 4436 } |
| 4422 DCHECK(current_offset == number_of_fields); | 4437 DCHECK(current_offset == number_of_fields); |
| 4423 | 4438 |
| 4424 descriptors->Sort(); | 4439 descriptors->Sort(); |
| 4425 | 4440 |
| 4426 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New( | 4441 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4468 Handle<FixedDoubleArray>::cast(array); | 4483 Handle<FixedDoubleArray>::cast(array); |
| 4469 if (double_array->is_the_hole(i)) { | 4484 if (double_array->is_the_hole(i)) { |
| 4470 value = factory->the_hole_value(); | 4485 value = factory->the_hole_value(); |
| 4471 } else { | 4486 } else { |
| 4472 value = factory->NewHeapNumber(double_array->get_scalar(i)); | 4487 value = factory->NewHeapNumber(double_array->get_scalar(i)); |
| 4473 } | 4488 } |
| 4474 } else { | 4489 } else { |
| 4475 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate); | 4490 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate); |
| 4476 } | 4491 } |
| 4477 if (!value->IsTheHole()) { | 4492 if (!value->IsTheHole()) { |
| 4478 PropertyDetails details(NONE, FIELD, 0); | 4493 PropertyDetails details(NONE, DATA_FIELD, 0); |
| 4479 dictionary = | 4494 dictionary = |
| 4480 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); | 4495 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); |
| 4481 } | 4496 } |
| 4482 } | 4497 } |
| 4483 return dictionary; | 4498 return dictionary; |
| 4484 } | 4499 } |
| 4485 | 4500 |
| 4486 | 4501 |
| 4487 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4502 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
| 4488 Handle<JSObject> object) { | 4503 Handle<JSObject> object) { |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4737 if (HasFastProperties()) { | 4752 if (HasFastProperties()) { |
| 4738 // If the object has fast properties, check whether the first slot | 4753 // If the object has fast properties, check whether the first slot |
| 4739 // in the descriptor array matches the hidden string. Since the | 4754 // in the descriptor array matches the hidden string. Since the |
| 4740 // hidden strings hash code is zero (and no other name has hash | 4755 // hidden strings hash code is zero (and no other name has hash |
| 4741 // code zero) it will always occupy the first entry if present. | 4756 // code zero) it will always occupy the first entry if present. |
| 4742 DescriptorArray* descriptors = this->map()->instance_descriptors(); | 4757 DescriptorArray* descriptors = this->map()->instance_descriptors(); |
| 4743 if (descriptors->number_of_descriptors() > 0) { | 4758 if (descriptors->number_of_descriptors() > 0) { |
| 4744 int sorted_index = descriptors->GetSortedKeyIndex(0); | 4759 int sorted_index = descriptors->GetSortedKeyIndex(0); |
| 4745 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && | 4760 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
| 4746 sorted_index < map()->NumberOfOwnDescriptors()) { | 4761 sorted_index < map()->NumberOfOwnDescriptors()) { |
| 4747 DCHECK(descriptors->GetType(sorted_index) == FIELD); | 4762 DCHECK(descriptors->GetType(sorted_index) == DATA_FIELD); |
| 4748 DCHECK(descriptors->GetDetails(sorted_index).representation(). | 4763 DCHECK(descriptors->GetDetails(sorted_index).representation(). |
| 4749 IsCompatibleForLoad(Representation::Tagged())); | 4764 IsCompatibleForLoad(Representation::Tagged())); |
| 4750 FieldIndex index = FieldIndex::ForDescriptor(this->map(), | 4765 FieldIndex index = FieldIndex::ForDescriptor(this->map(), |
| 4751 sorted_index); | 4766 sorted_index); |
| 4752 return this->RawFastPropertyAt(index); | 4767 return this->RawFastPropertyAt(index); |
| 4753 } else { | 4768 } else { |
| 4754 return GetHeap()->undefined_value(); | 4769 return GetHeap()->undefined_value(); |
| 4755 } | 4770 } |
| 4756 } else { | 4771 } else { |
| 4757 return GetHeap()->undefined_value(); | 4772 return GetHeap()->undefined_value(); |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5278 static void ApplyAttributesToDictionary(Dictionary* dictionary, | 5293 static void ApplyAttributesToDictionary(Dictionary* dictionary, |
| 5279 const PropertyAttributes attributes) { | 5294 const PropertyAttributes attributes) { |
| 5280 int capacity = dictionary->Capacity(); | 5295 int capacity = dictionary->Capacity(); |
| 5281 for (int i = 0; i < capacity; i++) { | 5296 for (int i = 0; i < capacity; i++) { |
| 5282 Object* k = dictionary->KeyAt(i); | 5297 Object* k = dictionary->KeyAt(i); |
| 5283 if (dictionary->IsKey(k) && | 5298 if (dictionary->IsKey(k) && |
| 5284 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { | 5299 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { |
| 5285 PropertyDetails details = dictionary->DetailsAt(i); | 5300 PropertyDetails details = dictionary->DetailsAt(i); |
| 5286 int attrs = attributes; | 5301 int attrs = attributes; |
| 5287 // READ_ONLY is an invalid attribute for JS setters/getters. | 5302 // READ_ONLY is an invalid attribute for JS setters/getters. |
| 5288 if ((attributes & READ_ONLY) && details.type() == CALLBACKS) { | 5303 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) { |
| 5289 Object* v = dictionary->ValueAt(i); | 5304 Object* v = dictionary->ValueAt(i); |
| 5290 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); | 5305 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); |
| 5291 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; | 5306 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; |
| 5292 } | 5307 } |
| 5293 details = details.CopyAddAttributes( | 5308 details = details.CopyAddAttributes( |
| 5294 static_cast<PropertyAttributes>(attrs)); | 5309 static_cast<PropertyAttributes>(attrs)); |
| 5295 dictionary->DetailsAtPut(i, details); | 5310 dictionary->DetailsAtPut(i, details); |
| 5296 } | 5311 } |
| 5297 } | 5312 } |
| 5298 } | 5313 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5518 | 5533 |
| 5519 if (!shallow) { | 5534 if (!shallow) { |
| 5520 HandleScope scope(isolate); | 5535 HandleScope scope(isolate); |
| 5521 | 5536 |
| 5522 // Deep copy own properties. | 5537 // Deep copy own properties. |
| 5523 if (copy->HasFastProperties()) { | 5538 if (copy->HasFastProperties()) { |
| 5524 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | 5539 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
| 5525 int limit = copy->map()->NumberOfOwnDescriptors(); | 5540 int limit = copy->map()->NumberOfOwnDescriptors(); |
| 5526 for (int i = 0; i < limit; i++) { | 5541 for (int i = 0; i < limit; i++) { |
| 5527 PropertyDetails details = descriptors->GetDetails(i); | 5542 PropertyDetails details = descriptors->GetDetails(i); |
| 5528 if (details.type() != FIELD) continue; | 5543 if (details.type() != DATA_FIELD) continue; |
| 5529 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); | 5544 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); |
| 5530 if (object->IsUnboxedDoubleField(index)) { | 5545 if (object->IsUnboxedDoubleField(index)) { |
| 5531 if (copying) { | 5546 if (copying) { |
| 5532 double value = object->RawFastDoublePropertyAt(index); | 5547 double value = object->RawFastDoublePropertyAt(index); |
| 5533 copy->RawFastDoublePropertyAtPut(index, value); | 5548 copy->RawFastDoublePropertyAtPut(index, value); |
| 5534 } | 5549 } |
| 5535 } else { | 5550 } else { |
| 5536 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 5551 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
| 5537 if (value->IsJSObject()) { | 5552 if (value->IsJSObject()) { |
| 5538 ASSIGN_RETURN_ON_EXCEPTION( | 5553 ASSIGN_RETURN_ON_EXCEPTION( |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5743 return result; | 5758 return result; |
| 5744 } | 5759 } |
| 5745 | 5760 |
| 5746 | 5761 |
| 5747 int Map::NextFreePropertyIndex() { | 5762 int Map::NextFreePropertyIndex() { |
| 5748 int free_index = 0; | 5763 int free_index = 0; |
| 5749 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 5764 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| 5750 DescriptorArray* descs = instance_descriptors(); | 5765 DescriptorArray* descs = instance_descriptors(); |
| 5751 for (int i = 0; i < number_of_own_descriptors; i++) { | 5766 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 5752 PropertyDetails details = descs->GetDetails(i); | 5767 PropertyDetails details = descs->GetDetails(i); |
| 5753 if (details.type() == FIELD) { | 5768 if (details.type() == DATA_FIELD) { |
| 5754 int candidate = details.field_index() + details.field_width_in_words(); | 5769 int candidate = details.field_index() + details.field_width_in_words(); |
| 5755 if (candidate > free_index) free_index = candidate; | 5770 if (candidate > free_index) free_index = candidate; |
| 5756 } | 5771 } |
| 5757 } | 5772 } |
| 5758 return free_index; | 5773 return free_index; |
| 5759 } | 5774 } |
| 5760 | 5775 |
| 5761 | 5776 |
| 5762 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 5777 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 5763 int len = array->length(); | 5778 int len = array->length(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5834 | 5849 |
| 5835 int size = map->NumberOfOwnDescriptors(); | 5850 int size = map->NumberOfOwnDescriptors(); |
| 5836 int index = 0; | 5851 int index = 0; |
| 5837 | 5852 |
| 5838 for (int i = 0; i < size; i++) { | 5853 for (int i = 0; i < size; i++) { |
| 5839 PropertyDetails details = descs->GetDetails(i); | 5854 PropertyDetails details = descs->GetDetails(i); |
| 5840 Object* key = descs->GetKey(i); | 5855 Object* key = descs->GetKey(i); |
| 5841 if (!(details.IsDontEnum() || key->IsSymbol())) { | 5856 if (!(details.IsDontEnum() || key->IsSymbol())) { |
| 5842 storage->set(index, key); | 5857 storage->set(index, key); |
| 5843 if (!indices.is_null()) { | 5858 if (!indices.is_null()) { |
| 5844 if (details.type() != FIELD) { | 5859 if (details.type() != DATA_FIELD) { |
| 5845 indices = Handle<FixedArray>(); | 5860 indices = Handle<FixedArray>(); |
| 5846 } else { | 5861 } else { |
| 5847 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i); | 5862 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i); |
| 5848 int load_by_field_index = field_index.GetLoadByFieldIndex(); | 5863 int load_by_field_index = field_index.GetLoadByFieldIndex(); |
| 5849 indices->set(index, Smi::FromInt(load_by_field_index)); | 5864 indices->set(index, Smi::FromInt(load_by_field_index)); |
| 5850 } | 5865 } |
| 5851 } | 5866 } |
| 5852 index++; | 5867 index++; |
| 5853 } | 5868 } |
| 5854 } | 5869 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5997 static bool UpdateGetterSetterInDictionary( | 6012 static bool UpdateGetterSetterInDictionary( |
| 5998 SeededNumberDictionary* dictionary, | 6013 SeededNumberDictionary* dictionary, |
| 5999 uint32_t index, | 6014 uint32_t index, |
| 6000 Object* getter, | 6015 Object* getter, |
| 6001 Object* setter, | 6016 Object* setter, |
| 6002 PropertyAttributes attributes) { | 6017 PropertyAttributes attributes) { |
| 6003 int entry = dictionary->FindEntry(index); | 6018 int entry = dictionary->FindEntry(index); |
| 6004 if (entry != SeededNumberDictionary::kNotFound) { | 6019 if (entry != SeededNumberDictionary::kNotFound) { |
| 6005 Object* result = dictionary->ValueAt(entry); | 6020 Object* result = dictionary->ValueAt(entry); |
| 6006 PropertyDetails details = dictionary->DetailsAt(entry); | 6021 PropertyDetails details = dictionary->DetailsAt(entry); |
| 6007 if (details.type() == CALLBACKS && result->IsAccessorPair()) { | 6022 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) { |
| 6008 DCHECK(details.IsConfigurable()); | 6023 DCHECK(details.IsConfigurable()); |
| 6009 if (details.attributes() != attributes) { | 6024 if (details.attributes() != attributes) { |
| 6010 dictionary->DetailsAtPut( | 6025 dictionary->DetailsAtPut( |
| 6011 entry, | 6026 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index)); |
| 6012 PropertyDetails(attributes, CALLBACKS, index)); | |
| 6013 } | 6027 } |
| 6014 AccessorPair::cast(result)->SetComponents(getter, setter); | 6028 AccessorPair::cast(result)->SetComponents(getter, setter); |
| 6015 return true; | 6029 return true; |
| 6016 } | 6030 } |
| 6017 } | 6031 } |
| 6018 return false; | 6032 return false; |
| 6019 } | 6033 } |
| 6020 | 6034 |
| 6021 | 6035 |
| 6022 void JSObject::DefineElementAccessor(Handle<JSObject> object, | 6036 void JSObject::DefineElementAccessor(Handle<JSObject> object, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6104 | 6118 |
| 6105 return false; | 6119 return false; |
| 6106 } | 6120 } |
| 6107 | 6121 |
| 6108 | 6122 |
| 6109 void JSObject::SetElementCallback(Handle<JSObject> object, | 6123 void JSObject::SetElementCallback(Handle<JSObject> object, |
| 6110 uint32_t index, | 6124 uint32_t index, |
| 6111 Handle<Object> structure, | 6125 Handle<Object> structure, |
| 6112 PropertyAttributes attributes) { | 6126 PropertyAttributes attributes) { |
| 6113 Heap* heap = object->GetHeap(); | 6127 Heap* heap = object->GetHeap(); |
| 6114 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6128 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0); |
| 6115 | 6129 |
| 6116 // Normalize elements to make this operation simple. | 6130 // Normalize elements to make this operation simple. |
| 6117 bool had_dictionary_elements = object->HasDictionaryElements(); | 6131 bool had_dictionary_elements = object->HasDictionaryElements(); |
| 6118 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6132 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
| 6119 DCHECK(object->HasDictionaryElements() || | 6133 DCHECK(object->HasDictionaryElements() || |
| 6120 object->HasDictionaryArgumentsElements()); | 6134 object->HasDictionaryArgumentsElements()); |
| 6121 // Update the dictionary with the new CALLBACKS property. | 6135 // Update the dictionary with the new ACCESSOR_CONSTANT property. |
| 6122 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6136 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
| 6123 details); | 6137 details); |
| 6124 dictionary->set_requires_slow_elements(); | 6138 dictionary->set_requires_slow_elements(); |
| 6125 | 6139 |
| 6126 // Update the dictionary backing store on the object. | 6140 // Update the dictionary backing store on the object. |
| 6127 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) { | 6141 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) { |
| 6128 // Also delete any parameter alias. | 6142 // Also delete any parameter alias. |
| 6129 // | 6143 // |
| 6130 // TODO(kmillikin): when deleting the last parameter alias we could | 6144 // TODO(kmillikin): when deleting the last parameter alias we could |
| 6131 // switch to a direct backing store without the parameter map. This | 6145 // switch to a direct backing store without the parameter map. This |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6169 } | 6183 } |
| 6170 #endif | 6184 #endif |
| 6171 JSObject::MigrateToMap(object, new_map); | 6185 JSObject::MigrateToMap(object, new_map); |
| 6172 | 6186 |
| 6173 // When running crankshaft, changing the map is not enough. We | 6187 // When running crankshaft, changing the map is not enough. We |
| 6174 // need to deoptimize all functions that rely on this global | 6188 // need to deoptimize all functions that rely on this global |
| 6175 // object. | 6189 // object. |
| 6176 Deoptimizer::DeoptimizeGlobalObject(*object); | 6190 Deoptimizer::DeoptimizeGlobalObject(*object); |
| 6177 } | 6191 } |
| 6178 | 6192 |
| 6179 // Update the dictionary with the new CALLBACKS property. | 6193 // Update the dictionary with the new ACCESSOR_CONSTANT property. |
| 6180 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6194 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0); |
| 6181 SetNormalizedProperty(object, name, structure, details); | 6195 SetNormalizedProperty(object, name, structure, details); |
| 6182 | 6196 |
| 6183 ReoptimizeIfPrototype(object); | 6197 ReoptimizeIfPrototype(object); |
| 6184 } | 6198 } |
| 6185 | 6199 |
| 6186 | 6200 |
| 6187 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, | 6201 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, |
| 6188 Handle<Name> name, | 6202 Handle<Name> name, |
| 6189 Handle<Object> getter, | 6203 Handle<Object> getter, |
| 6190 Handle<Object> setter, | 6204 Handle<Object> setter, |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6384 return isolate->factory()->undefined_value(); | 6398 return isolate->factory()->undefined_value(); |
| 6385 } | 6399 } |
| 6386 | 6400 |
| 6387 if (current->IsJSObject() && | 6401 if (current->IsJSObject() && |
| 6388 Handle<JSObject>::cast(current)->HasDictionaryElements()) { | 6402 Handle<JSObject>::cast(current)->HasDictionaryElements()) { |
| 6389 JSObject* js_object = JSObject::cast(*current); | 6403 JSObject* js_object = JSObject::cast(*current); |
| 6390 SeededNumberDictionary* dictionary = js_object->element_dictionary(); | 6404 SeededNumberDictionary* dictionary = js_object->element_dictionary(); |
| 6391 int entry = dictionary->FindEntry(index); | 6405 int entry = dictionary->FindEntry(index); |
| 6392 if (entry != SeededNumberDictionary::kNotFound) { | 6406 if (entry != SeededNumberDictionary::kNotFound) { |
| 6393 Object* element = dictionary->ValueAt(entry); | 6407 Object* element = dictionary->ValueAt(entry); |
| 6394 if (dictionary->DetailsAt(entry).type() == CALLBACKS && | 6408 if (dictionary->DetailsAt(entry).type() == ACCESSOR_CONSTANT && |
| 6395 element->IsAccessorPair()) { | 6409 element->IsAccessorPair()) { |
| 6396 return handle(AccessorPair::cast(element)->GetComponent(component), | 6410 return handle(AccessorPair::cast(element)->GetComponent(component), |
| 6397 isolate); | 6411 isolate); |
| 6398 } | 6412 } |
| 6399 } | 6413 } |
| 6400 } | 6414 } |
| 6401 } | 6415 } |
| 6402 } else { | 6416 } else { |
| 6403 LookupIterator it(object, name, | 6417 LookupIterator it(object, name, |
| 6404 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); | 6418 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 6435 return isolate->factory()->undefined_value(); | 6449 return isolate->factory()->undefined_value(); |
| 6436 } | 6450 } |
| 6437 | 6451 |
| 6438 | 6452 |
| 6439 Object* JSObject::SlowReverseLookup(Object* value) { | 6453 Object* JSObject::SlowReverseLookup(Object* value) { |
| 6440 if (HasFastProperties()) { | 6454 if (HasFastProperties()) { |
| 6441 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 6455 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
| 6442 DescriptorArray* descs = map()->instance_descriptors(); | 6456 DescriptorArray* descs = map()->instance_descriptors(); |
| 6443 bool value_is_number = value->IsNumber(); | 6457 bool value_is_number = value->IsNumber(); |
| 6444 for (int i = 0; i < number_of_own_descriptors; i++) { | 6458 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 6445 if (descs->GetType(i) == FIELD) { | 6459 if (descs->GetType(i) == DATA_FIELD) { |
| 6446 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); | 6460 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); |
| 6447 if (IsUnboxedDoubleField(field_index)) { | 6461 if (IsUnboxedDoubleField(field_index)) { |
| 6448 if (value_is_number) { | 6462 if (value_is_number) { |
| 6449 double property = RawFastDoublePropertyAt(field_index); | 6463 double property = RawFastDoublePropertyAt(field_index); |
| 6450 if (property == value->Number()) { | 6464 if (property == value->Number()) { |
| 6451 return descs->GetKey(i); | 6465 return descs->GetKey(i); |
| 6452 } | 6466 } |
| 6453 } | 6467 } |
| 6454 } else { | 6468 } else { |
| 6455 Object* property = RawFastPropertyAt(field_index); | 6469 Object* property = RawFastPropertyAt(field_index); |
| 6456 if (field_index.is_double()) { | 6470 if (field_index.is_double()) { |
| 6457 DCHECK(property->IsMutableHeapNumber()); | 6471 DCHECK(property->IsMutableHeapNumber()); |
| 6458 if (value_is_number && property->Number() == value->Number()) { | 6472 if (value_is_number && property->Number() == value->Number()) { |
| 6459 return descs->GetKey(i); | 6473 return descs->GetKey(i); |
| 6460 } | 6474 } |
| 6461 } else if (property == value) { | 6475 } else if (property == value) { |
| 6462 return descs->GetKey(i); | 6476 return descs->GetKey(i); |
| 6463 } | 6477 } |
| 6464 } | 6478 } |
| 6465 } else if (descs->GetType(i) == CONSTANT) { | 6479 } else if (descs->GetType(i) == DATA_CONSTANT) { |
| 6466 if (descs->GetConstant(i) == value) { | 6480 if (descs->GetConstant(i) == value) { |
| 6467 return descs->GetKey(i); | 6481 return descs->GetKey(i); |
| 6468 } | 6482 } |
| 6469 } | 6483 } |
| 6470 } | 6484 } |
| 6471 return GetHeap()->undefined_value(); | 6485 return GetHeap()->undefined_value(); |
| 6472 } else { | 6486 } else { |
| 6473 return property_dictionary()->SlowReverseLookup(value); | 6487 return property_dictionary()->SlowReverseLookup(value); |
| 6474 } | 6488 } |
| 6475 } | 6489 } |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6700 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { | 6714 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
| 6701 result->InitializeDescriptors(*descriptors, *layout_descriptor); | 6715 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
| 6702 | 6716 |
| 6703 Handle<Name> name; | 6717 Handle<Name> name; |
| 6704 CHECK(maybe_name.ToHandle(&name)); | 6718 CHECK(maybe_name.ToHandle(&name)); |
| 6705 ConnectTransition(map, result, name, simple_flag); | 6719 ConnectTransition(map, result, name, simple_flag); |
| 6706 } else { | 6720 } else { |
| 6707 int length = descriptors->number_of_descriptors(); | 6721 int length = descriptors->number_of_descriptors(); |
| 6708 for (int i = 0; i < length; i++) { | 6722 for (int i = 0; i < length; i++) { |
| 6709 descriptors->SetRepresentation(i, Representation::Tagged()); | 6723 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 6710 if (descriptors->GetDetails(i).type() == FIELD) { | 6724 if (descriptors->GetDetails(i).type() == DATA_FIELD) { |
| 6711 descriptors->SetValue(i, HeapType::Any()); | 6725 descriptors->SetValue(i, HeapType::Any()); |
| 6712 } | 6726 } |
| 6713 } | 6727 } |
| 6714 result->InitializeDescriptors(*descriptors, | 6728 result->InitializeDescriptors(*descriptors, |
| 6715 LayoutDescriptor::FastPointerLayout()); | 6729 LayoutDescriptor::FastPointerLayout()); |
| 6716 } | 6730 } |
| 6717 } else { | 6731 } else { |
| 6718 result->InitializeDescriptors(*descriptors, *layout_descriptor); | 6732 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
| 6719 } | 6733 } |
| 6720 #if TRACE_MAPS | 6734 #if TRACE_MAPS |
| (...skipping 18 matching lines...) Expand all Loading... |
| 6739 Handle<LayoutDescriptor> full_layout_descriptor) { | 6753 Handle<LayoutDescriptor> full_layout_descriptor) { |
| 6740 DCHECK(descriptors->IsSortedNoDuplicates()); | 6754 DCHECK(descriptors->IsSortedNoDuplicates()); |
| 6741 | 6755 |
| 6742 Handle<Map> result = CopyDropDescriptors(map); | 6756 Handle<Map> result = CopyDropDescriptors(map); |
| 6743 | 6757 |
| 6744 result->set_instance_descriptors(*descriptors); | 6758 result->set_instance_descriptors(*descriptors); |
| 6745 result->SetNumberOfOwnDescriptors(new_descriptor + 1); | 6759 result->SetNumberOfOwnDescriptors(new_descriptor + 1); |
| 6746 | 6760 |
| 6747 int unused_property_fields = map->unused_property_fields(); | 6761 int unused_property_fields = map->unused_property_fields(); |
| 6748 PropertyDetails details = descriptors->GetDetails(new_descriptor); | 6762 PropertyDetails details = descriptors->GetDetails(new_descriptor); |
| 6749 if (details.type() == FIELD) { | 6763 if (details.type() == DATA_FIELD) { |
| 6750 unused_property_fields = map->unused_property_fields() - 1; | 6764 unused_property_fields = map->unused_property_fields() - 1; |
| 6751 if (unused_property_fields < 0) { | 6765 if (unused_property_fields < 0) { |
| 6752 unused_property_fields += JSObject::kFieldsAdded; | 6766 unused_property_fields += JSObject::kFieldsAdded; |
| 6753 } | 6767 } |
| 6754 } | 6768 } |
| 6755 result->set_unused_property_fields(unused_property_fields); | 6769 result->set_unused_property_fields(unused_property_fields); |
| 6756 | 6770 |
| 6757 if (FLAG_unbox_double_fields) { | 6771 if (FLAG_unbox_double_fields) { |
| 6758 Handle<LayoutDescriptor> layout_descriptor = | 6772 Handle<LayoutDescriptor> layout_descriptor = |
| 6759 LayoutDescriptor::AppendIfFastOrUseFull(map, details, | 6773 LayoutDescriptor::AppendIfFastOrUseFull(map, details, |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6903 transition_marker, reason, SPECIAL_TRANSITION); | 6917 transition_marker, reason, SPECIAL_TRANSITION); |
| 6904 new_map->set_is_extensible(false); | 6918 new_map->set_is_extensible(false); |
| 6905 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | 6919 new_map->set_elements_kind(DICTIONARY_ELEMENTS); |
| 6906 return new_map; | 6920 return new_map; |
| 6907 } | 6921 } |
| 6908 | 6922 |
| 6909 | 6923 |
| 6910 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { | 6924 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { |
| 6911 PropertyDetails details = GetDetails(descriptor); | 6925 PropertyDetails details = GetDetails(descriptor); |
| 6912 switch (details.type()) { | 6926 switch (details.type()) { |
| 6913 case FIELD: | 6927 case DATA_FIELD: |
| 6914 return value->FitsRepresentation(details.representation()) && | 6928 return value->FitsRepresentation(details.representation()) && |
| 6915 GetFieldType(descriptor)->NowContains(value); | 6929 GetFieldType(descriptor)->NowContains(value); |
| 6916 | 6930 |
| 6917 case CONSTANT: | 6931 case DATA_CONSTANT: |
| 6918 DCHECK(GetConstant(descriptor) != value || | 6932 DCHECK(GetConstant(descriptor) != value || |
| 6919 value->FitsRepresentation(details.representation())); | 6933 value->FitsRepresentation(details.representation())); |
| 6920 return GetConstant(descriptor) == value; | 6934 return GetConstant(descriptor) == value; |
| 6921 | 6935 |
| 6922 case ACCESSOR_FIELD: | 6936 case ACCESSOR_FIELD: |
| 6923 case CALLBACKS: | 6937 case ACCESSOR_CONSTANT: |
| 6924 return false; | 6938 return false; |
| 6925 } | 6939 } |
| 6926 | 6940 |
| 6927 UNREACHABLE(); | 6941 UNREACHABLE(); |
| 6928 return false; | 6942 return false; |
| 6929 } | 6943 } |
| 6930 | 6944 |
| 6931 | 6945 |
| 6932 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, | 6946 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, |
| 6933 Handle<Object> value) { | 6947 Handle<Object> value) { |
| 6934 // Dictionaries can store any property value. | 6948 // Dictionaries can store any property value. |
| 6935 if (map->is_dictionary_map()) return map; | 6949 if (map->is_dictionary_map()) return map; |
| 6936 | 6950 |
| 6937 // Migrate to the newest map before storing the property. | 6951 // Migrate to the newest map before storing the property. |
| 6938 map = Update(map); | 6952 map = Update(map); |
| 6939 | 6953 |
| 6940 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 6954 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 6941 | 6955 |
| 6942 if (descriptors->CanHoldValue(descriptor, *value)) return map; | 6956 if (descriptors->CanHoldValue(descriptor, *value)) return map; |
| 6943 | 6957 |
| 6944 Isolate* isolate = map->GetIsolate(); | 6958 Isolate* isolate = map->GetIsolate(); |
| 6945 Representation representation = value->OptimalRepresentation(); | 6959 Representation representation = value->OptimalRepresentation(); |
| 6946 Handle<HeapType> type = value->OptimalType(isolate, representation); | 6960 Handle<HeapType> type = value->OptimalType(isolate, representation); |
| 6947 | 6961 |
| 6948 return GeneralizeRepresentation(map, descriptor, representation, type, | 6962 return GeneralizeRepresentation(map, descriptor, representation, type, |
| 6949 FORCE_IN_OBJECT); | 6963 FORCE_FIELD); |
| 6950 } | 6964 } |
| 6951 | 6965 |
| 6952 | 6966 |
| 6953 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, | 6967 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
| 6954 Handle<Object> value, | 6968 Handle<Object> value, |
| 6955 PropertyAttributes attributes, | 6969 PropertyAttributes attributes, |
| 6956 StoreFromKeyed store_mode) { | 6970 StoreFromKeyed store_mode) { |
| 6957 // Dictionary maps can always have additional data properties. | 6971 // Dictionary maps can always have additional data properties. |
| 6958 if (map->is_dictionary_map()) return map; | 6972 if (map->is_dictionary_map()) return map; |
| 6959 | 6973 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7003 } | 7017 } |
| 7004 | 7018 |
| 7005 | 7019 |
| 7006 Handle<Map> Map::ReconfigureDataProperty(Handle<Map> map, int descriptor, | 7020 Handle<Map> Map::ReconfigureDataProperty(Handle<Map> map, int descriptor, |
| 7007 PropertyAttributes attributes) { | 7021 PropertyAttributes attributes) { |
| 7008 // Dictionaries have to be reconfigured in-place. | 7022 // Dictionaries have to be reconfigured in-place. |
| 7009 DCHECK(!map->is_dictionary_map()); | 7023 DCHECK(!map->is_dictionary_map()); |
| 7010 | 7024 |
| 7011 // For now, give up on transitioning and just create a unique map. | 7025 // For now, give up on transitioning and just create a unique map. |
| 7012 // TODO(verwaest/ishell): Cache transitions with different attributes. | 7026 // TODO(verwaest/ishell): Cache transitions with different attributes. |
| 7013 return CopyGeneralizeAllRepresentations(map, descriptor, FORCE_IN_OBJECT, | 7027 return CopyGeneralizeAllRepresentations( |
| 7014 attributes, | 7028 map, descriptor, FORCE_FIELD, attributes, "GenAll_AttributesMismatch"); |
| 7015 "GenAll_AttributesMismatch"); | |
| 7016 } | 7029 } |
| 7017 | 7030 |
| 7018 | 7031 |
| 7019 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, | 7032 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
| 7020 Handle<Name> name, | 7033 Handle<Name> name, |
| 7021 AccessorComponent component, | 7034 AccessorComponent component, |
| 7022 Handle<Object> accessor, | 7035 Handle<Object> accessor, |
| 7023 PropertyAttributes attributes) { | 7036 PropertyAttributes attributes) { |
| 7024 Isolate* isolate = name->GetIsolate(); | 7037 Isolate* isolate = name->GetIsolate(); |
| 7025 | 7038 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7062 } | 7075 } |
| 7063 | 7076 |
| 7064 Handle<AccessorPair> pair; | 7077 Handle<AccessorPair> pair; |
| 7065 DescriptorArray* old_descriptors = map->instance_descriptors(); | 7078 DescriptorArray* old_descriptors = map->instance_descriptors(); |
| 7066 int descriptor = old_descriptors->SearchWithCache(*name, *map); | 7079 int descriptor = old_descriptors->SearchWithCache(*name, *map); |
| 7067 if (descriptor != DescriptorArray::kNotFound) { | 7080 if (descriptor != DescriptorArray::kNotFound) { |
| 7068 if (descriptor != map->LastAdded()) { | 7081 if (descriptor != map->LastAdded()) { |
| 7069 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); | 7082 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); |
| 7070 } | 7083 } |
| 7071 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); | 7084 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); |
| 7072 if (old_details.type() != CALLBACKS) { | 7085 if (old_details.type() != ACCESSOR_CONSTANT) { |
| 7073 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); | 7086 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); |
| 7074 } | 7087 } |
| 7075 | 7088 |
| 7076 if (old_details.attributes() != attributes) { | 7089 if (old_details.attributes() != attributes) { |
| 7077 return Map::Normalize(map, mode, "AccessorsWithAttributes"); | 7090 return Map::Normalize(map, mode, "AccessorsWithAttributes"); |
| 7078 } | 7091 } |
| 7079 | 7092 |
| 7080 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); | 7093 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); |
| 7081 if (!maybe_pair->IsAccessorPair()) { | 7094 if (!maybe_pair->IsAccessorPair()) { |
| 7082 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair"); | 7095 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair"); |
| 7083 } | 7096 } |
| 7084 | 7097 |
| 7085 Object* current = Handle<AccessorPair>::cast(maybe_pair)->get(component); | 7098 Object* current = Handle<AccessorPair>::cast(maybe_pair)->get(component); |
| 7086 if (current == *accessor) return map; | 7099 if (current == *accessor) return map; |
| 7087 | 7100 |
| 7088 if (!current->IsTheHole()) { | 7101 if (!current->IsTheHole()) { |
| 7089 return Map::Normalize(map, mode, "AccessorsOverwritingAccessors"); | 7102 return Map::Normalize(map, mode, "AccessorsOverwritingAccessors"); |
| 7090 } | 7103 } |
| 7091 | 7104 |
| 7092 pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair)); | 7105 pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair)); |
| 7093 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || | 7106 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || |
| 7094 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { | 7107 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { |
| 7095 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors"); | 7108 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors"); |
| 7096 } else { | 7109 } else { |
| 7097 pair = isolate->factory()->NewAccessorPair(); | 7110 pair = isolate->factory()->NewAccessorPair(); |
| 7098 } | 7111 } |
| 7099 | 7112 |
| 7100 pair->set(component, *accessor); | 7113 pair->set(component, *accessor); |
| 7101 TransitionFlag flag = INSERT_TRANSITION; | 7114 TransitionFlag flag = INSERT_TRANSITION; |
| 7102 CallbacksDescriptor new_desc(name, pair, attributes); | 7115 AccessorConstantDescriptor new_desc(name, pair, attributes); |
| 7103 return Map::CopyInsertDescriptor(map, &new_desc, flag); | 7116 return Map::CopyInsertDescriptor(map, &new_desc, flag); |
| 7104 } | 7117 } |
| 7105 | 7118 |
| 7106 | 7119 |
| 7107 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, | 7120 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, |
| 7108 Descriptor* descriptor, | 7121 Descriptor* descriptor, |
| 7109 TransitionFlag flag) { | 7122 TransitionFlag flag) { |
| 7110 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 7123 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 7111 | 7124 |
| 7112 // Ensure the key is unique. | 7125 // Ensure the key is unique. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7176 | 7189 |
| 7177 if (attributes != NONE) { | 7190 if (attributes != NONE) { |
| 7178 for (int i = 0; i < size; ++i) { | 7191 for (int i = 0; i < size; ++i) { |
| 7179 Object* value = desc->GetValue(i); | 7192 Object* value = desc->GetValue(i); |
| 7180 Name* key = desc->GetKey(i); | 7193 Name* key = desc->GetKey(i); |
| 7181 PropertyDetails details = desc->GetDetails(i); | 7194 PropertyDetails details = desc->GetDetails(i); |
| 7182 // Bulk attribute changes never affect private properties. | 7195 // Bulk attribute changes never affect private properties. |
| 7183 if (!key->IsSymbol() || !Symbol::cast(key)->is_private()) { | 7196 if (!key->IsSymbol() || !Symbol::cast(key)->is_private()) { |
| 7184 int mask = DONT_DELETE | DONT_ENUM; | 7197 int mask = DONT_DELETE | DONT_ENUM; |
| 7185 // READ_ONLY is an invalid attribute for JS setters/getters. | 7198 // READ_ONLY is an invalid attribute for JS setters/getters. |
| 7186 if (details.type() != CALLBACKS || !value->IsAccessorPair()) { | 7199 if (details.type() != ACCESSOR_CONSTANT || !value->IsAccessorPair()) { |
| 7187 mask |= READ_ONLY; | 7200 mask |= READ_ONLY; |
| 7188 } | 7201 } |
| 7189 details = details.CopyAddAttributes( | 7202 details = details.CopyAddAttributes( |
| 7190 static_cast<PropertyAttributes>(attributes & mask)); | 7203 static_cast<PropertyAttributes>(attributes & mask)); |
| 7191 } | 7204 } |
| 7192 Descriptor inner_desc( | 7205 Descriptor inner_desc( |
| 7193 handle(key), handle(value, desc->GetIsolate()), details); | 7206 handle(key), handle(value, desc->GetIsolate()), details); |
| 7194 descriptors->Set(i, &inner_desc, witness); | 7207 descriptors->Set(i, &inner_desc, witness); |
| 7195 } | 7208 } |
| 7196 } else { | 7209 } else { |
| (...skipping 2449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9646 ClearOptimizedCodeMap(); | 9659 ClearOptimizedCodeMap(); |
| 9647 } | 9660 } |
| 9648 } | 9661 } |
| 9649 | 9662 |
| 9650 | 9663 |
| 9651 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, | 9664 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, |
| 9652 PrototypeOptimizationMode mode) { | 9665 PrototypeOptimizationMode mode) { |
| 9653 if (object->IsGlobalObject()) return; | 9666 if (object->IsGlobalObject()) return; |
| 9654 if (object->IsJSGlobalProxy()) return; | 9667 if (object->IsJSGlobalProxy()) return; |
| 9655 if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) { | 9668 if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) { |
| 9656 // First normalize to ensure all JSFunctions are CONSTANT. | 9669 // First normalize to ensure all JSFunctions are DATA_CONSTANT. |
| 9657 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, | 9670 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, |
| 9658 "NormalizeAsPrototype"); | 9671 "NormalizeAsPrototype"); |
| 9659 } | 9672 } |
| 9660 bool has_just_copied_map = false; | 9673 bool has_just_copied_map = false; |
| 9661 if (!object->HasFastProperties()) { | 9674 if (!object->HasFastProperties()) { |
| 9662 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); | 9675 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); |
| 9663 has_just_copied_map = true; | 9676 has_just_copied_map = true; |
| 9664 } | 9677 } |
| 9665 if (mode == FAST_PROTOTYPE && object->HasFastProperties() && | 9678 if (mode == FAST_PROTOTYPE && object->HasFastProperties() && |
| 9666 !object->map()->is_prototype_map()) { | 9679 !object->map()->is_prototype_map()) { |
| (...skipping 2758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12425 bool is_arguments = | 12438 bool is_arguments = |
| 12426 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); | 12439 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); |
| 12427 Handle<SeededNumberDictionary> dictionary(is_arguments | 12440 Handle<SeededNumberDictionary> dictionary(is_arguments |
| 12428 ? SeededNumberDictionary::cast(elements->get(1)) | 12441 ? SeededNumberDictionary::cast(elements->get(1)) |
| 12429 : SeededNumberDictionary::cast(*elements)); | 12442 : SeededNumberDictionary::cast(*elements)); |
| 12430 | 12443 |
| 12431 int entry = dictionary->FindEntry(index); | 12444 int entry = dictionary->FindEntry(index); |
| 12432 if (entry != SeededNumberDictionary::kNotFound) { | 12445 if (entry != SeededNumberDictionary::kNotFound) { |
| 12433 Handle<Object> element(dictionary->ValueAt(entry), isolate); | 12446 Handle<Object> element(dictionary->ValueAt(entry), isolate); |
| 12434 PropertyDetails details = dictionary->DetailsAt(entry); | 12447 PropertyDetails details = dictionary->DetailsAt(entry); |
| 12435 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { | 12448 if (details.type() == ACCESSOR_CONSTANT && set_mode == SET_PROPERTY) { |
| 12436 return SetElementWithCallback(object, element, index, value, object, | 12449 return SetElementWithCallback(object, element, index, value, object, |
| 12437 strict_mode); | 12450 strict_mode); |
| 12438 } else { | 12451 } else { |
| 12439 dictionary->UpdateMaxNumberKey(index); | 12452 dictionary->UpdateMaxNumberKey(index); |
| 12440 // If a value has not been initialized we allow writing to it even if it | 12453 // If a value has not been initialized we allow writing to it even if it |
| 12441 // is read-only (a declared const that has not been initialized). If a | 12454 // is read-only (a declared const that has not been initialized). If a |
| 12442 // value is being defined we skip attribute checks completely. | 12455 // value is being defined we skip attribute checks completely. |
| 12443 if (set_mode == DEFINE_PROPERTY) { | 12456 if (set_mode == DEFINE_PROPERTY) { |
| 12444 details = | 12457 details = |
| 12445 PropertyDetails(attributes, FIELD, details.dictionary_index()); | 12458 PropertyDetails(attributes, DATA_FIELD, details.dictionary_index()); |
| 12446 dictionary->DetailsAtPut(entry, details); | 12459 dictionary->DetailsAtPut(entry, details); |
| 12447 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 12460 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
| 12448 if (strict_mode == SLOPPY) { | 12461 if (strict_mode == SLOPPY) { |
| 12449 return isolate->factory()->undefined_value(); | 12462 return isolate->factory()->undefined_value(); |
| 12450 } else { | 12463 } else { |
| 12451 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12464 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12452 Handle<Object> args[2] = { number, object }; | 12465 Handle<Object> args[2] = { number, object }; |
| 12453 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | 12466 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
| 12454 HandleVector(args, 2)), | 12467 HandleVector(args, 2)), |
| 12455 Object); | 12468 Object); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 12486 } else { | 12499 } else { |
| 12487 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12500 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12488 Handle<String> name = isolate->factory()->NumberToString(number); | 12501 Handle<String> name = isolate->factory()->NumberToString(number); |
| 12489 Handle<Object> args[1] = { name }; | 12502 Handle<Object> args[1] = { name }; |
| 12490 THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible", | 12503 THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible", |
| 12491 HandleVector(args, 1)), | 12504 HandleVector(args, 1)), |
| 12492 Object); | 12505 Object); |
| 12493 } | 12506 } |
| 12494 } | 12507 } |
| 12495 | 12508 |
| 12496 PropertyDetails details(attributes, FIELD, 0); | 12509 PropertyDetails details(attributes, DATA_FIELD, 0); |
| 12497 Handle<SeededNumberDictionary> new_dictionary = | 12510 Handle<SeededNumberDictionary> new_dictionary = |
| 12498 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, | 12511 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, |
| 12499 details); | 12512 details); |
| 12500 if (*dictionary != *new_dictionary) { | 12513 if (*dictionary != *new_dictionary) { |
| 12501 if (is_arguments) { | 12514 if (is_arguments) { |
| 12502 elements->set(1, *new_dictionary); | 12515 elements->set(1, *new_dictionary); |
| 12503 } else { | 12516 } else { |
| 12504 object->set_elements(*new_dictionary); | 12517 object->set_elements(*new_dictionary); |
| 12505 } | 12518 } |
| 12506 dictionary = new_dictionary; | 12519 dictionary = new_dictionary; |
| (...skipping 2072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14579 if (!dict->IsKey(k)) continue; | 14592 if (!dict->IsKey(k)) continue; |
| 14580 | 14593 |
| 14581 DCHECK(k->IsNumber()); | 14594 DCHECK(k->IsNumber()); |
| 14582 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); | 14595 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); |
| 14583 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); | 14596 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); |
| 14584 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); | 14597 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); |
| 14585 | 14598 |
| 14586 HandleScope scope(isolate); | 14599 HandleScope scope(isolate); |
| 14587 Handle<Object> value(dict->ValueAt(i), isolate); | 14600 Handle<Object> value(dict->ValueAt(i), isolate); |
| 14588 PropertyDetails details = dict->DetailsAt(i); | 14601 PropertyDetails details = dict->DetailsAt(i); |
| 14589 if (details.type() == CALLBACKS || details.IsReadOnly()) { | 14602 if (details.type() == ACCESSOR_CONSTANT || details.IsReadOnly()) { |
| 14590 // Bail out and do the sorting of undefineds and array holes in JS. | 14603 // Bail out and do the sorting of undefineds and array holes in JS. |
| 14591 // Also bail out if the element is not supposed to be moved. | 14604 // Also bail out if the element is not supposed to be moved. |
| 14592 return bailout; | 14605 return bailout; |
| 14593 } | 14606 } |
| 14594 | 14607 |
| 14595 uint32_t key = NumberToUint32(k); | 14608 uint32_t key = NumberToUint32(k); |
| 14596 if (key < limit) { | 14609 if (key < limit) { |
| 14597 if (value->IsUndefined()) { | 14610 if (value->IsUndefined()) { |
| 14598 undefs++; | 14611 undefs++; |
| 14599 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { | 14612 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 14613 return bailout; | 14626 return bailout; |
| 14614 } else { | 14627 } else { |
| 14615 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( | 14628 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
| 14616 new_dict, key, value, details); | 14629 new_dict, key, value, details); |
| 14617 DCHECK(result.is_identical_to(new_dict)); | 14630 DCHECK(result.is_identical_to(new_dict)); |
| 14618 USE(result); | 14631 USE(result); |
| 14619 } | 14632 } |
| 14620 } | 14633 } |
| 14621 | 14634 |
| 14622 uint32_t result = pos; | 14635 uint32_t result = pos; |
| 14623 PropertyDetails no_details(NONE, FIELD, 0); | 14636 PropertyDetails no_details(NONE, DATA_FIELD, 0); |
| 14624 while (undefs > 0) { | 14637 while (undefs > 0) { |
| 14625 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { | 14638 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 14626 // Adding an entry with the key beyond smi-range requires | 14639 // Adding an entry with the key beyond smi-range requires |
| 14627 // allocation. Bailout. | 14640 // allocation. Bailout. |
| 14628 return bailout; | 14641 return bailout; |
| 14629 } | 14642 } |
| 14630 HandleScope scope(isolate); | 14643 HandleScope scope(isolate); |
| 14631 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( | 14644 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
| 14632 new_dict, pos, isolate->factory()->undefined_value(), no_details); | 14645 new_dict, pos, isolate->factory()->undefined_value(), no_details); |
| 14633 DCHECK(result.is_identical_to(new_dict)); | 14646 DCHECK(result.is_identical_to(new_dict)); |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14999 | 15012 |
| 15000 Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell( | 15013 Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell( |
| 15001 Handle<JSGlobalObject> global, | 15014 Handle<JSGlobalObject> global, |
| 15002 Handle<Name> name) { | 15015 Handle<Name> name) { |
| 15003 DCHECK(!global->HasFastProperties()); | 15016 DCHECK(!global->HasFastProperties()); |
| 15004 int entry = global->property_dictionary()->FindEntry(name); | 15017 int entry = global->property_dictionary()->FindEntry(name); |
| 15005 if (entry == NameDictionary::kNotFound) { | 15018 if (entry == NameDictionary::kNotFound) { |
| 15006 Isolate* isolate = global->GetIsolate(); | 15019 Isolate* isolate = global->GetIsolate(); |
| 15007 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell( | 15020 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell( |
| 15008 isolate->factory()->the_hole_value()); | 15021 isolate->factory()->the_hole_value()); |
| 15009 PropertyDetails details(NONE, FIELD, 0); | 15022 PropertyDetails details(NONE, DATA_FIELD, 0); |
| 15010 details = details.AsDeleted(); | 15023 details = details.AsDeleted(); |
| 15011 Handle<NameDictionary> dictionary = NameDictionary::Add( | 15024 Handle<NameDictionary> dictionary = NameDictionary::Add( |
| 15012 handle(global->property_dictionary()), name, cell, details); | 15025 handle(global->property_dictionary()), name, cell, details); |
| 15013 global->set_properties(*dictionary); | 15026 global->set_properties(*dictionary); |
| 15014 return cell; | 15027 return cell; |
| 15015 } else { | 15028 } else { |
| 15016 Object* value = global->property_dictionary()->ValueAt(entry); | 15029 Object* value = global->property_dictionary()->ValueAt(entry); |
| 15017 DCHECK(value->IsPropertyCell()); | 15030 DCHECK(value->IsPropertyCell()); |
| 15018 return handle(PropertyCell::cast(value)); | 15031 return handle(PropertyCell::cast(value)); |
| 15019 } | 15032 } |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15479 if (entry != Dictionary::kNotFound) { | 15492 if (entry != Dictionary::kNotFound) { |
| 15480 dictionary->ValueAtPut(entry, *value); | 15493 dictionary->ValueAtPut(entry, *value); |
| 15481 return dictionary; | 15494 return dictionary; |
| 15482 } | 15495 } |
| 15483 | 15496 |
| 15484 // Check whether the dictionary should be extended. | 15497 // Check whether the dictionary should be extended. |
| 15485 dictionary = EnsureCapacity(dictionary, 1, key); | 15498 dictionary = EnsureCapacity(dictionary, 1, key); |
| 15486 #ifdef DEBUG | 15499 #ifdef DEBUG |
| 15487 USE(Shape::AsHandle(dictionary->GetIsolate(), key)); | 15500 USE(Shape::AsHandle(dictionary->GetIsolate(), key)); |
| 15488 #endif | 15501 #endif |
| 15489 PropertyDetails details(NONE, FIELD, 0); | 15502 PropertyDetails details(NONE, DATA_FIELD, 0); |
| 15490 | 15503 |
| 15491 AddEntry(dictionary, key, value, details, dictionary->Hash(key)); | 15504 AddEntry(dictionary, key, value, details, dictionary->Hash(key)); |
| 15492 return dictionary; | 15505 return dictionary; |
| 15493 } | 15506 } |
| 15494 | 15507 |
| 15495 | 15508 |
| 15496 template<typename Derived, typename Shape, typename Key> | 15509 template<typename Derived, typename Shape, typename Key> |
| 15497 Handle<Derived> Dictionary<Derived, Shape, Key>::Add( | 15510 Handle<Derived> Dictionary<Derived, Shape, Key>::Add( |
| 15498 Handle<Derived> dictionary, | 15511 Handle<Derived> dictionary, |
| 15499 Key key, | 15512 Key key, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15567 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); | 15580 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); |
| 15568 return Add(dictionary, key, value, details); | 15581 return Add(dictionary, key, value, details); |
| 15569 } | 15582 } |
| 15570 | 15583 |
| 15571 | 15584 |
| 15572 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry( | 15585 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry( |
| 15573 Handle<UnseededNumberDictionary> dictionary, | 15586 Handle<UnseededNumberDictionary> dictionary, |
| 15574 uint32_t key, | 15587 uint32_t key, |
| 15575 Handle<Object> value) { | 15588 Handle<Object> value) { |
| 15576 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); | 15589 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); |
| 15577 return Add(dictionary, key, value, PropertyDetails(NONE, FIELD, 0)); | 15590 return Add(dictionary, key, value, PropertyDetails(NONE, DATA_FIELD, 0)); |
| 15578 } | 15591 } |
| 15579 | 15592 |
| 15580 | 15593 |
| 15581 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut( | 15594 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut( |
| 15582 Handle<SeededNumberDictionary> dictionary, | 15595 Handle<SeededNumberDictionary> dictionary, |
| 15583 uint32_t key, | 15596 uint32_t key, |
| 15584 Handle<Object> value) { | 15597 Handle<Object> value) { |
| 15585 dictionary->UpdateMaxNumberKey(key); | 15598 dictionary->UpdateMaxNumberKey(key); |
| 15586 return AtPut(dictionary, key, value); | 15599 return AtPut(dictionary, key, value); |
| 15587 } | 15600 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15655 | 15668 |
| 15656 | 15669 |
| 15657 template <typename Derived, typename Shape, typename Key> | 15670 template <typename Derived, typename Shape, typename Key> |
| 15658 bool Dictionary<Derived, Shape, Key>::HasComplexElements() { | 15671 bool Dictionary<Derived, Shape, Key>::HasComplexElements() { |
| 15659 int capacity = DerivedHashTable::Capacity(); | 15672 int capacity = DerivedHashTable::Capacity(); |
| 15660 for (int i = 0; i < capacity; i++) { | 15673 for (int i = 0; i < capacity; i++) { |
| 15661 Object* k = DerivedHashTable::KeyAt(i); | 15674 Object* k = DerivedHashTable::KeyAt(i); |
| 15662 if (DerivedHashTable::IsKey(k) && !FilterKey(k, NONE)) { | 15675 if (DerivedHashTable::IsKey(k) && !FilterKey(k, NONE)) { |
| 15663 PropertyDetails details = DetailsAt(i); | 15676 PropertyDetails details = DetailsAt(i); |
| 15664 if (details.IsDeleted()) continue; | 15677 if (details.IsDeleted()) continue; |
| 15665 if (details.type() == CALLBACKS) return true; | 15678 if (details.type() == ACCESSOR_CONSTANT) return true; |
| 15666 PropertyAttributes attr = details.attributes(); | 15679 PropertyAttributes attr = details.attributes(); |
| 15667 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; | 15680 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; |
| 15668 } | 15681 } |
| 15669 } | 15682 } |
| 15670 return false; | 15683 return false; |
| 15671 } | 15684 } |
| 15672 | 15685 |
| 15673 | 15686 |
| 15674 template <typename Derived, typename Shape, typename Key> | 15687 template <typename Derived, typename Shape, typename Key> |
| 15675 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 15688 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| (...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16829 Handle<DependentCode> codes = | 16842 Handle<DependentCode> codes = |
| 16830 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16843 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16831 DependentCode::kPropertyCellChangedGroup, | 16844 DependentCode::kPropertyCellChangedGroup, |
| 16832 info->object_wrapper()); | 16845 info->object_wrapper()); |
| 16833 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16846 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16834 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16847 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16835 cell, info->zone()); | 16848 cell, info->zone()); |
| 16836 } | 16849 } |
| 16837 | 16850 |
| 16838 } } // namespace v8::internal | 16851 } } // namespace v8::internal |
| OLD | NEW |