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...) 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...) 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...) 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...) 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...) 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 |