Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1817 // If the constructor is not present, return "Object". | 1817 // If the constructor is not present, return "Object". |
| 1818 return GetHeap()->Object_string(); | 1818 return GetHeap()->Object_string(); |
| 1819 } | 1819 } |
| 1820 | 1820 |
| 1821 | 1821 |
| 1822 String* JSReceiver::constructor_name() { | 1822 String* JSReceiver::constructor_name() { |
| 1823 return map()->constructor_name(); | 1823 return map()->constructor_name(); |
| 1824 } | 1824 } |
| 1825 | 1825 |
| 1826 | 1826 |
| 1827 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, | |
| 1828 Handle<Name> name, | |
| 1829 Handle<HeapType> type, | |
| 1830 PropertyAttributes attributes, | |
| 1831 Representation representation, | |
| 1832 TransitionFlag flag) { | |
| 1833 ASSERT(DescriptorArray::kNotFound == | |
| 1834 map->instance_descriptors()->Search( | |
| 1835 *name, map->NumberOfOwnDescriptors())); | |
| 1836 | |
| 1837 // Ensure the descriptor array does not get too big. | |
| 1838 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | |
| 1839 return MaybeHandle<Map>(); | |
| 1840 } | |
| 1841 | |
| 1842 // Normalize the object if the name is an actual name (not the | |
| 1843 // hidden strings) and is not a real identifier. | |
| 1844 // Normalize the object if it will have too many fast properties. | |
| 1845 Isolate* isolate = map->GetIsolate(); | |
| 1846 if (!name->IsCacheable(isolate)) return Handle<Map>(); | |
|
Igor Sheludko
2014/04/15 15:02:39
MaybeHandle<>
| |
| 1847 | |
| 1848 // Compute the new index for new field. | |
| 1849 int index = map->NextFreePropertyIndex(); | |
| 1850 | |
| 1851 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { | |
| 1852 representation = Representation::Tagged(); | |
|
Igor Sheludko
2014/04/15 15:02:39
Shouldn't we update type here as well?
| |
| 1853 } | |
| 1854 | |
| 1855 FieldDescriptor new_field_desc(name, index, type, attributes, representation); | |
| 1856 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); | |
| 1857 int unused_property_fields = new_map->unused_property_fields() - 1; | |
| 1858 if (unused_property_fields < 0) { | |
| 1859 unused_property_fields += JSObject::kFieldsAdded; | |
| 1860 } | |
| 1861 new_map->set_unused_property_fields(unused_property_fields); | |
| 1862 return new_map; | |
| 1863 } | |
| 1864 | |
| 1865 | |
| 1866 MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map, | |
| 1867 Handle<Name> name, | |
| 1868 Handle<Object> constant, | |
| 1869 PropertyAttributes attributes, | |
| 1870 TransitionFlag flag) { | |
| 1871 // Ensure the descriptor array does not get too big. | |
| 1872 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | |
| 1873 return MaybeHandle<Map>(); | |
| 1874 } | |
| 1875 | |
| 1876 // Allocate new instance descriptors with (name, constant) added. | |
| 1877 ConstantDescriptor new_constant_desc(name, constant, attributes); | |
| 1878 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); | |
| 1879 } | |
| 1880 | |
| 1881 | |
| 1827 void JSObject::AddFastProperty(Handle<JSObject> object, | 1882 void JSObject::AddFastProperty(Handle<JSObject> object, |
| 1828 Handle<Name> name, | 1883 Handle<Name> name, |
| 1829 Handle<Object> value, | 1884 Handle<Object> value, |
| 1830 PropertyAttributes attributes, | 1885 PropertyAttributes attributes, |
| 1831 StoreFromKeyed store_mode, | 1886 StoreFromKeyed store_mode, |
| 1832 ValueType value_type, | 1887 ValueType value_type, |
| 1833 TransitionFlag flag) { | 1888 TransitionFlag flag) { |
| 1834 ASSERT(!object->IsJSGlobalProxy()); | 1889 ASSERT(!object->IsJSGlobalProxy()); |
| 1835 ASSERT(DescriptorArray::kNotFound == | |
| 1836 object->map()->instance_descriptors()->Search( | |
| 1837 *name, object->map()->NumberOfOwnDescriptors())); | |
| 1838 | 1890 |
| 1839 // Normalize the object if the name is an actual name (not the | 1891 MaybeHandle<Map> maybe_map; |
| 1840 // hidden strings) and is not a real identifier. | 1892 if (value->IsJSFunction()) { |
| 1841 // Normalize the object if it will have too many fast properties. | 1893 maybe_map = Map::CopyWithConstant( |
| 1842 Isolate* isolate = object->GetIsolate(); | 1894 handle(object->map()), name, value, attributes, flag); |
| 1843 if (!name->IsCacheable(isolate) || | 1895 } else if (object->TooManyFastProperties(store_mode)) { |
| 1844 object->TooManyFastProperties(store_mode)) { | |
| 1845 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 1896 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 1846 AddSlowProperty(object, name, value, attributes); | 1897 return; |
| 1898 } else { | |
|
Igor Sheludko
2014/04/15 15:02:39
I think you can now write here:
} else if (!obje
| |
| 1899 Isolate* isolate = object->GetIsolate(); | |
| 1900 Representation representation = value->OptimalRepresentation(value_type); | |
| 1901 maybe_map = Map::CopyWithField( | |
| 1902 handle(object->map(), isolate), name, | |
| 1903 value->OptimalType(isolate, representation), | |
| 1904 attributes, representation, flag); | |
| 1905 } | |
| 1906 | |
| 1907 Handle<Map> new_map; | |
| 1908 if (!maybe_map.ToHandle(&new_map)) { | |
| 1909 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | |
| 1847 return; | 1910 return; |
| 1848 } | 1911 } |
| 1849 | 1912 |
| 1850 // Allocate new instance descriptors with (name, index) added | 1913 JSObject::MigrateToMap(object, new_map); |
| 1851 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; | |
| 1852 Representation representation = value->OptimalRepresentation(value_type); | |
| 1853 | 1914 |
| 1854 // Compute the new index for new field. | 1915 PropertyDetails details = new_map->GetLastDescriptorDetails(); |
| 1855 int index = object->map()->NextFreePropertyIndex(); | 1916 if (details.type() != FIELD) return; |
| 1856 | 1917 |
| 1857 Handle<HeapType> type = value->OptimalType(isolate, representation); | 1918 Representation representation = details.representation(); |
| 1858 FieldDescriptor new_field_desc(name, index, type, attributes, representation); | 1919 int index = details.field_index(); |
| 1859 Handle<Map> new_map = Map::CopyAddDescriptor( | |
| 1860 handle(object->map()), &new_field_desc, flag); | |
| 1861 int unused_property_fields = new_map->unused_property_fields() - 1; | |
| 1862 if (unused_property_fields < 0) { | |
| 1863 unused_property_fields += JSObject::kFieldsAdded; | |
| 1864 } | |
| 1865 new_map->set_unused_property_fields(unused_property_fields); | |
| 1866 | |
| 1867 JSObject::MigrateToMap(object, new_map); | |
| 1868 | 1920 |
| 1869 if (representation.IsDouble()) { | 1921 if (representation.IsDouble()) { |
| 1870 // Nothing more to be done. | 1922 // Nothing more to be done. |
| 1871 if (value->IsUninitialized()) return; | 1923 if (value->IsUninitialized()) return; |
| 1872 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); | 1924 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); |
| 1873 box->set_value(value->Number()); | 1925 box->set_value(value->Number()); |
| 1874 } else { | 1926 } else { |
| 1875 object->FastPropertyAtPut(index, *value); | 1927 object->FastPropertyAtPut(index, *value); |
| 1876 } | 1928 } |
| 1877 } | 1929 } |
| 1878 | 1930 |
| 1879 | 1931 |
| 1880 void JSObject::AddConstantProperty(Handle<JSObject> object, | |
| 1881 Handle<Name> name, | |
| 1882 Handle<Object> constant, | |
| 1883 PropertyAttributes attributes, | |
| 1884 TransitionFlag initial_flag) { | |
| 1885 ASSERT(!object->IsGlobalObject()); | |
| 1886 // Don't add transitions to special properties with non-trivial attributes. | |
| 1887 TransitionFlag flag = attributes != NONE ? OMIT_TRANSITION : initial_flag; | |
|
Igor Sheludko
2014/04/15 15:02:39
This code is lost.
| |
| 1888 | |
| 1889 // Allocate new instance descriptors with (name, constant) added. | |
| 1890 ConstantDescriptor new_constant_desc(name, constant, attributes); | |
| 1891 Handle<Map> new_map = Map::CopyAddDescriptor( | |
| 1892 handle(object->map()), &new_constant_desc, flag); | |
| 1893 | |
| 1894 JSObject::MigrateToMap(object, new_map); | |
| 1895 } | |
| 1896 | |
| 1897 | |
| 1898 void JSObject::AddSlowProperty(Handle<JSObject> object, | 1932 void JSObject::AddSlowProperty(Handle<JSObject> object, |
| 1899 Handle<Name> name, | 1933 Handle<Name> name, |
| 1900 Handle<Object> value, | 1934 Handle<Object> value, |
| 1901 PropertyAttributes attributes) { | 1935 PropertyAttributes attributes) { |
| 1902 ASSERT(!object->HasFastProperties()); | 1936 ASSERT(!object->HasFastProperties()); |
| 1903 Isolate* isolate = object->GetIsolate(); | 1937 Isolate* isolate = object->GetIsolate(); |
| 1904 Handle<NameDictionary> dict(object->property_dictionary()); | 1938 Handle<NameDictionary> dict(object->property_dictionary()); |
| 1905 if (object->IsGlobalObject()) { | 1939 if (object->IsGlobalObject()) { |
| 1906 // In case name is an orphaned property reuse the cell. | 1940 // In case name is an orphaned property reuse the cell. |
| 1907 int entry = dict->FindEntry(*name); | 1941 int entry = dict->FindEntry(*name); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1952 return value; | 1986 return value; |
| 1953 } else { | 1987 } else { |
| 1954 Handle<Object> args[1] = { name }; | 1988 Handle<Object> args[1] = { name }; |
| 1955 Handle<Object> error = isolate->factory()->NewTypeError( | 1989 Handle<Object> error = isolate->factory()->NewTypeError( |
| 1956 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | 1990 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
| 1957 return isolate->Throw<Object>(error); | 1991 return isolate->Throw<Object>(error); |
| 1958 } | 1992 } |
| 1959 } | 1993 } |
| 1960 | 1994 |
| 1961 if (object->HasFastProperties()) { | 1995 if (object->HasFastProperties()) { |
| 1962 // Ensure the descriptor array does not get too big. | 1996 AddFastProperty(object, name, value, attributes, store_mode, |
| 1963 if (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors) { | 1997 value_type, transition_flag); |
| 1964 // TODO(verwaest): Support other constants. | 1998 } |
| 1965 // if (mode == ALLOW_AS_CONSTANT && | 1999 |
| 1966 // !value->IsTheHole() && | 2000 if (!object->HasFastProperties()) { |
| 1967 // !value->IsConsString()) { | |
| 1968 if (value->IsJSFunction()) { | |
| 1969 AddConstantProperty(object, name, value, attributes, transition_flag); | |
| 1970 } else { | |
| 1971 AddFastProperty(object, name, value, attributes, store_mode, | |
| 1972 value_type, transition_flag); | |
| 1973 } | |
| 1974 } else { | |
| 1975 // Normalize the object to prevent very large instance descriptors. | |
| 1976 // This eliminates unwanted N^2 allocation and lookup behavior. | |
| 1977 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | |
| 1978 AddSlowProperty(object, name, value, attributes); | |
| 1979 } | |
| 1980 } else { | |
| 1981 AddSlowProperty(object, name, value, attributes); | 2001 AddSlowProperty(object, name, value, attributes); |
| 1982 } | 2002 } |
| 1983 | 2003 |
| 1984 if (object->map()->is_observed() && | 2004 if (object->map()->is_observed() && |
| 1985 *name != isolate->heap()->hidden_string()) { | 2005 *name != isolate->heap()->hidden_string()) { |
| 1986 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 2006 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 1987 EnqueueChangeRecord(object, "add", name, old_value); | 2007 EnqueueChangeRecord(object, "add", name, old_value); |
| 1988 } | 2008 } |
| 1989 | 2009 |
| 1990 return value; | 2010 return value; |
| (...skipping 4615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6606 JSObject::MigrateToMap(self, transitioned_map); | 6626 JSObject::MigrateToMap(self, transitioned_map); |
| 6607 return true; | 6627 return true; |
| 6608 } | 6628 } |
| 6609 | 6629 |
| 6610 // If either not the same accessor, or not the same attributes, fall back to | 6630 // If either not the same accessor, or not the same attributes, fall back to |
| 6611 // the slow case. | 6631 // the slow case. |
| 6612 return false; | 6632 return false; |
| 6613 } | 6633 } |
| 6614 | 6634 |
| 6615 | 6635 |
| 6616 static Handle<Map> CopyInsertDescriptor(Handle<Map> map, | |
| 6617 Handle<Name> name, | |
| 6618 Handle<AccessorPair> accessors, | |
| 6619 PropertyAttributes attributes) { | |
| 6620 CallbacksDescriptor new_accessors_desc(name, accessors, attributes); | |
| 6621 return Map::CopyInsertDescriptor(map, &new_accessors_desc, INSERT_TRANSITION); | |
| 6622 } | |
| 6623 | |
| 6624 | |
| 6625 bool JSObject::DefineFastAccessor(Handle<JSObject> object, | 6636 bool JSObject::DefineFastAccessor(Handle<JSObject> object, |
| 6626 Handle<Name> name, | 6637 Handle<Name> name, |
| 6627 AccessorComponent component, | 6638 AccessorComponent component, |
| 6628 Handle<Object> accessor, | 6639 Handle<Object> accessor, |
| 6629 PropertyAttributes attributes) { | 6640 PropertyAttributes attributes) { |
| 6630 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); | 6641 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); |
| 6631 Isolate* isolate = object->GetIsolate(); | 6642 Isolate* isolate = object->GetIsolate(); |
| 6632 LookupResult result(isolate); | 6643 LookupResult result(isolate); |
| 6633 object->LocalLookup(*name, &result); | 6644 object->LocalLookup(*name, &result); |
| 6634 | 6645 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6679 } | 6690 } |
| 6680 } | 6691 } |
| 6681 | 6692 |
| 6682 // If there is no transition yet, add a transition to the a new accessor pair | 6693 // If there is no transition yet, add a transition to the a new accessor pair |
| 6683 // containing the accessor. Allocate a new pair if there were no source | 6694 // containing the accessor. Allocate a new pair if there were no source |
| 6684 // accessors. Otherwise, copy the pair and modify the accessor. | 6695 // accessors. Otherwise, copy the pair and modify the accessor. |
| 6685 Handle<AccessorPair> accessors = source_accessors != NULL | 6696 Handle<AccessorPair> accessors = source_accessors != NULL |
| 6686 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors)) | 6697 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors)) |
| 6687 : isolate->factory()->NewAccessorPair(); | 6698 : isolate->factory()->NewAccessorPair(); |
| 6688 accessors->set(component, *accessor); | 6699 accessors->set(component, *accessor); |
| 6689 Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()), | 6700 |
| 6690 name, accessors, attributes); | 6701 CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
| 6702 Handle<Map> new_map = Map::CopyInsertDescriptor( | |
| 6703 handle(object->map()), &new_accessors_desc, INSERT_TRANSITION); | |
| 6704 | |
| 6691 JSObject::MigrateToMap(object, new_map); | 6705 JSObject::MigrateToMap(object, new_map); |
| 6692 return true; | 6706 return true; |
| 6693 } | 6707 } |
| 6694 | 6708 |
| 6695 | 6709 |
| 6696 Handle<Object> JSObject::SetAccessor(Handle<JSObject> object, | 6710 Handle<Object> JSObject::SetAccessor(Handle<JSObject> object, |
| 6697 Handle<AccessorInfo> info) { | 6711 Handle<AccessorInfo> info) { |
| 6698 Isolate* isolate = object->GetIsolate(); | 6712 Isolate* isolate = object->GetIsolate(); |
| 6699 Factory* factory = isolate->factory(); | 6713 Factory* factory = isolate->factory(); |
| 6700 Handle<Name> name(Name::cast(info->name())); | 6714 Handle<Name> name(Name::cast(info->name())); |
| (...skipping 9893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16594 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16608 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16595 static const char* error_messages_[] = { | 16609 static const char* error_messages_[] = { |
| 16596 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16610 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16597 }; | 16611 }; |
| 16598 #undef ERROR_MESSAGES_TEXTS | 16612 #undef ERROR_MESSAGES_TEXTS |
| 16599 return error_messages_[reason]; | 16613 return error_messages_[reason]; |
| 16600 } | 16614 } |
| 16601 | 16615 |
| 16602 | 16616 |
| 16603 } } // namespace v8::internal | 16617 } } // namespace v8::internal |
| OLD | NEW |