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