Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(642)

Side by Side Diff: src/objects.cc

Issue 24205004: Rollback trunk to 3.21.16.2 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 } 448 }
449 449
450 450
451 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, 451 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
452 Handle<JSReceiver> receiver, 452 Handle<JSReceiver> receiver,
453 uint32_t index, 453 uint32_t index,
454 Handle<Object> value, 454 Handle<Object> value,
455 StrictModeFlag strict_mode) { 455 StrictModeFlag strict_mode) {
456 Isolate* isolate = proxy->GetIsolate(); 456 Isolate* isolate = proxy->GetIsolate();
457 Handle<String> name = isolate->factory()->Uint32ToString(index); 457 Handle<String> name = isolate->factory()->Uint32ToString(index);
458 return SetPropertyWithHandler( 458 CALL_HEAP_FUNCTION(isolate,
459 proxy, receiver, name, value, NONE, strict_mode); 459 proxy->SetPropertyWithHandler(
460 *receiver, *name, *value, NONE, strict_mode),
461 Object);
460 } 462 }
461 463
462 464
463 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) { 465 bool JSProxy::HasElementWithHandler(uint32_t index) {
464 Isolate* isolate = proxy->GetIsolate(); 466 String* name;
465 Handle<String> name = isolate->factory()->Uint32ToString(index); 467 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
466 return HasPropertyWithHandler(proxy, name); 468 if (!maybe->To<String>(&name)) return maybe;
469 return HasPropertyWithHandler(name);
467 } 470 }
468 471
469 472
470 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, 473 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver,
471 JSReceiver* getter) { 474 JSReceiver* getter) {
472 Isolate* isolate = getter->GetIsolate(); 475 Isolate* isolate = getter->GetIsolate();
473 HandleScope scope(isolate); 476 HandleScope scope(isolate);
474 Handle<JSReceiver> fun(getter); 477 Handle<JSReceiver> fun(getter);
475 Handle<Object> self(receiver, isolate); 478 Handle<Object> self(receiver, isolate);
476 #ifdef ENABLE_DEBUGGER_SUPPORT 479 #ifdef ENABLE_DEBUGGER_SUPPORT
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 // If the constructor is not present, return "Object". 1864 // If the constructor is not present, return "Object".
1862 return GetHeap()->Object_string(); 1865 return GetHeap()->Object_string();
1863 } 1866 }
1864 1867
1865 1868
1866 String* JSReceiver::constructor_name() { 1869 String* JSReceiver::constructor_name() {
1867 return map()->constructor_name(); 1870 return map()->constructor_name();
1868 } 1871 }
1869 1872
1870 1873
1871 Handle<Object> JSObject::AddFastPropertyUsingMap(
1872 Handle<JSObject> object,
1873 Handle<Map> new_map,
1874 Handle<Name> name,
1875 Handle<Object> value,
1876 int field_index,
1877 Representation representation) {
1878 CALL_HEAP_FUNCTION(object->GetIsolate(),
1879 object->AddFastPropertyUsingMap(
1880 *new_map, *name, *value, field_index, representation),
1881 Object);
1882 }
1883
1884
1885 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, 1874 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
1886 Name* name, 1875 Name* name,
1887 Object* value, 1876 Object* value,
1888 int field_index, 1877 int field_index,
1889 Representation representation) { 1878 Representation representation) {
1890 // This method is used to transition to a field. If we are transitioning to a 1879 // This method is used to transition to a field. If we are transitioning to a
1891 // double field, allocate new storage. 1880 // double field, allocate new storage.
1892 Object* storage; 1881 Object* storage;
1893 MaybeObject* maybe_storage = 1882 MaybeObject* maybe_storage =
1894 value->AllocateNewStorageFor(GetHeap(), representation); 1883 value->AllocateNewStorageFor(GetHeap(), representation);
1895 if (!maybe_storage->To(&storage)) return maybe_storage; 1884 if (!maybe_storage->To(&storage)) return maybe_storage;
1896 1885
1897 if (map()->unused_property_fields() == 0) { 1886 if (map()->unused_property_fields() == 0) {
1898 int new_unused = new_map->unused_property_fields(); 1887 int new_unused = new_map->unused_property_fields();
1899 FixedArray* values; 1888 FixedArray* values;
1900 MaybeObject* maybe_values = 1889 MaybeObject* maybe_values =
1901 properties()->CopySize(properties()->length() + new_unused + 1); 1890 properties()->CopySize(properties()->length() + new_unused + 1);
1902 if (!maybe_values->To(&values)) return maybe_values; 1891 if (!maybe_values->To(&values)) return maybe_values;
1903 1892
1904 set_properties(values); 1893 set_properties(values);
1905 } 1894 }
1906 1895
1907 set_map(new_map); 1896 set_map(new_map);
1908 1897
1909 FastPropertyAtPut(field_index, storage); 1898 FastPropertyAtPut(field_index, storage);
1910 return value; 1899 return value;
1911 } 1900 }
1912 1901
1913 1902
1914 static MaybeObject* CopyAddFieldDescriptor(Map* map, 1903 MaybeObject* JSObject::AddFastProperty(Name* name,
1915 Name* name, 1904 Object* value,
1916 int index, 1905 PropertyAttributes attributes,
1917 PropertyAttributes attributes, 1906 StoreFromKeyed store_mode,
1918 Representation representation, 1907 ValueType value_type,
1919 TransitionFlag flag) { 1908 TransitionFlag flag) {
1920 Map* new_map; 1909 ASSERT(!IsJSGlobalProxy());
1921 FieldDescriptor new_field_desc(name, index, attributes, representation);
1922 MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag);
1923 if (!maybe_map->To(&new_map)) return maybe_map;
1924 int unused_property_fields = map->unused_property_fields() - 1;
1925 if (unused_property_fields < 0) {
1926 unused_property_fields += JSObject::kFieldsAdded;
1927 }
1928 new_map->set_unused_property_fields(unused_property_fields);
1929 return new_map;
1930 }
1931
1932
1933 static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
1934 Handle<Name> name,
1935 int index,
1936 PropertyAttributes attributes,
1937 Representation representation,
1938 TransitionFlag flag) {
1939 CALL_HEAP_FUNCTION(map->GetIsolate(),
1940 CopyAddFieldDescriptor(
1941 *map, *name, index, attributes, representation, flag),
1942 Map);
1943 }
1944
1945
1946 void JSObject::AddFastProperty(Handle<JSObject> object,
1947 Handle<Name> name,
1948 Handle<Object> value,
1949 PropertyAttributes attributes,
1950 StoreFromKeyed store_mode,
1951 ValueType value_type,
1952 TransitionFlag flag) {
1953 ASSERT(!object->IsJSGlobalProxy());
1954 ASSERT(DescriptorArray::kNotFound == 1910 ASSERT(DescriptorArray::kNotFound ==
1955 object->map()->instance_descriptors()->Search( 1911 map()->instance_descriptors()->Search(
1956 *name, object->map()->NumberOfOwnDescriptors())); 1912 name, map()->NumberOfOwnDescriptors()));
1957 1913
1958 // Normalize the object if the name is an actual name (not the 1914 // Normalize the object if the name is an actual name (not the
1959 // hidden strings) and is not a real identifier. 1915 // hidden strings) and is not a real identifier.
1960 // Normalize the object if it will have too many fast properties. 1916 // Normalize the object if it will have too many fast properties.
1961 Isolate* isolate = object->GetIsolate(); 1917 Isolate* isolate = GetHeap()->isolate();
1962 if (!name->IsCacheable(isolate) || 1918 if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) {
1963 object->TooManyFastProperties(store_mode)) { 1919 MaybeObject* maybe_failure =
1964 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 1920 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1965 AddSlowProperty(object, name, value, attributes); 1921 if (maybe_failure->IsFailure()) return maybe_failure;
1966 return; 1922 return AddSlowProperty(name, value, attributes);
1967 } 1923 }
1968 1924
1969 // Compute the new index for new field. 1925 // Compute the new index for new field.
1970 int index = object->map()->NextFreePropertyIndex(); 1926 int index = map()->NextFreePropertyIndex();
1971 1927
1972 // Allocate new instance descriptors with (name, index) added 1928 // Allocate new instance descriptors with (name, index) added
1973 if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; 1929 if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
1974 Representation representation = value->OptimalRepresentation(value_type); 1930 Representation representation = value->OptimalRepresentation(value_type);
1975 Handle<Map> new_map = CopyAddFieldDescriptor(
1976 handle(object->map()), name, index, attributes, representation, flag);
1977 1931
1978 AddFastPropertyUsingMap(object, new_map, name, value, index, representation); 1932 FieldDescriptor new_field(name, index, attributes, representation);
1933
1934 Map* new_map;
1935 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag);
1936 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
1937
1938 int unused_property_fields = map()->unused_property_fields() - 1;
1939 if (unused_property_fields < 0) {
1940 unused_property_fields += kFieldsAdded;
1941 }
1942 new_map->set_unused_property_fields(unused_property_fields);
1943
1944 return AddFastPropertyUsingMap(new_map, name, value, index, representation);
1979 } 1945 }
1980 1946
1981 1947
1982 static MaybeObject* CopyAddConstantDescriptor(Map* map, 1948 MaybeObject* JSObject::AddConstantProperty(
1983 Name* name, 1949 Name* name,
1984 Object* value, 1950 Object* constant,
1985 PropertyAttributes attributes, 1951 PropertyAttributes attributes,
1986 TransitionFlag flag) { 1952 TransitionFlag initial_flag) {
1987 ConstantDescriptor new_constant_desc(name, value, attributes); 1953 // Allocate new instance descriptors with (name, constant) added
1988 return map->CopyAddDescriptor(&new_constant_desc, flag); 1954 ConstantDescriptor d(name, constant, attributes);
1989 }
1990 1955
1991
1992 static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map,
1993 Handle<Name> name,
1994 Handle<Object> value,
1995 PropertyAttributes attributes,
1996 TransitionFlag flag) {
1997 CALL_HEAP_FUNCTION(map->GetIsolate(),
1998 CopyAddConstantDescriptor(
1999 *map, *name, *value, attributes, flag),
2000 Map);
2001 }
2002
2003
2004 void JSObject::AddConstantProperty(Handle<JSObject> object,
2005 Handle<Name> name,
2006 Handle<Object> constant,
2007 PropertyAttributes attributes,
2008 TransitionFlag initial_flag) {
2009 TransitionFlag flag = 1956 TransitionFlag flag =
2010 // Do not add transitions to global objects. 1957 // Do not add transitions to global objects.
2011 (object->IsGlobalObject() || 1958 (IsGlobalObject() ||
2012 // Don't add transitions to special properties with non-trivial 1959 // Don't add transitions to special properties with non-trivial
2013 // attributes. 1960 // attributes.
2014 attributes != NONE) 1961 attributes != NONE)
2015 ? OMIT_TRANSITION 1962 ? OMIT_TRANSITION
2016 : initial_flag; 1963 : initial_flag;
2017 1964
2018 // Allocate new instance descriptors with (name, constant) added. 1965 Map* new_map;
2019 Handle<Map> new_map = CopyAddConstantDescriptor( 1966 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag);
2020 handle(object->map()), name, constant, attributes, flag); 1967 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2021 1968
2022 object->set_map(*new_map); 1969 set_map(new_map);
1970 return constant;
2023 } 1971 }
2024 1972
2025 1973
2026 // TODO(mstarzinger): Temporary wrapper until handlified. 1974 // Add property in slow mode
2027 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict, 1975 MaybeObject* JSObject::AddSlowProperty(Name* name,
2028 Handle<Name> name, 1976 Object* value,
2029 Handle<Object> value, 1977 PropertyAttributes attributes) {
2030 PropertyDetails details) { 1978 ASSERT(!HasFastProperties());
2031 CALL_HEAP_FUNCTION(dict->GetIsolate(), 1979 NameDictionary* dict = property_dictionary();
2032 dict->Add(*name, *value, details), 1980 Object* store_value = value;
2033 NameDictionary); 1981 if (IsGlobalObject()) {
2034 }
2035
2036
2037 void JSObject::AddSlowProperty(Handle<JSObject> object,
2038 Handle<Name> name,
2039 Handle<Object> value,
2040 PropertyAttributes attributes) {
2041 ASSERT(!object->HasFastProperties());
2042 Isolate* isolate = object->GetIsolate();
2043 Handle<NameDictionary> dict(object->property_dictionary());
2044 if (object->IsGlobalObject()) {
2045 // In case name is an orphaned property reuse the cell. 1982 // In case name is an orphaned property reuse the cell.
2046 int entry = dict->FindEntry(*name); 1983 int entry = dict->FindEntry(name);
2047 if (entry != NameDictionary::kNotFound) { 1984 if (entry != NameDictionary::kNotFound) {
2048 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); 1985 store_value = dict->ValueAt(entry);
2049 PropertyCell::SetValueInferType(cell, value); 1986 MaybeObject* maybe_type =
1987 PropertyCell::cast(store_value)->SetValueInferType(value);
1988 if (maybe_type->IsFailure()) return maybe_type;
2050 // Assign an enumeration index to the property and update 1989 // Assign an enumeration index to the property and update
2051 // SetNextEnumerationIndex. 1990 // SetNextEnumerationIndex.
2052 int index = dict->NextEnumerationIndex(); 1991 int index = dict->NextEnumerationIndex();
2053 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); 1992 PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
2054 dict->SetNextEnumerationIndex(index + 1); 1993 dict->SetNextEnumerationIndex(index + 1);
2055 dict->SetEntry(entry, *name, *cell, details); 1994 dict->SetEntry(entry, name, store_value, details);
2056 return; 1995 return value;
2057 } 1996 }
2058 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value); 1997 Heap* heap = GetHeap();
2059 PropertyCell::SetValueInferType(cell, value); 1998 { MaybeObject* maybe_store_value =
2060 value = cell; 1999 heap->AllocatePropertyCell(value);
2000 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
2001 }
2002 MaybeObject* maybe_type =
2003 PropertyCell::cast(store_value)->SetValueInferType(value);
2004 if (maybe_type->IsFailure()) return maybe_type;
2061 } 2005 }
2062 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 2006 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
2063 Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details); 2007 Object* result;
2064 if (*dict != *result) object->set_properties(*result); 2008 { MaybeObject* maybe_result = dict->Add(name, store_value, details);
2009 if (!maybe_result->ToObject(&result)) return maybe_result;
2010 }
2011 if (dict != result) set_properties(NameDictionary::cast(result));
2012 return value;
2065 } 2013 }
2066 2014
2067 2015
2068 Handle<Object> JSObject::AddProperty(Handle<JSObject> object, 2016 MaybeObject* JSObject::AddProperty(Name* name,
2069 Handle<Name> name, 2017 Object* value,
2070 Handle<Object> value, 2018 PropertyAttributes attributes,
2071 PropertyAttributes attributes, 2019 StrictModeFlag strict_mode,
2072 StrictModeFlag strict_mode, 2020 JSReceiver::StoreFromKeyed store_mode,
2073 JSReceiver::StoreFromKeyed store_mode, 2021 ExtensibilityCheck extensibility_check,
2074 ExtensibilityCheck extensibility_check, 2022 ValueType value_type,
2075 ValueType value_type, 2023 StoreMode mode,
2076 StoreMode mode, 2024 TransitionFlag transition_flag) {
2077 TransitionFlag transition_flag) { 2025 ASSERT(!IsJSGlobalProxy());
2078 ASSERT(!object->IsJSGlobalProxy()); 2026 Map* map_of_this = map();
2079 Isolate* isolate = object->GetIsolate(); 2027 Heap* heap = GetHeap();
2028 Isolate* isolate = heap->isolate();
2029 MaybeObject* result;
2080 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && 2030 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
2081 !object->map()->is_extensible()) { 2031 !map_of_this->is_extensible()) {
2082 if (strict_mode == kNonStrictMode) { 2032 if (strict_mode == kNonStrictMode) {
2083 return value; 2033 return value;
2084 } else { 2034 } else {
2085 Handle<Object> args[1] = { name }; 2035 Handle<Object> args[1] = {Handle<Name>(name)};
2086 Handle<Object> error = isolate->factory()->NewTypeError( 2036 return isolate->Throw(
2087 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); 2037 *isolate->factory()->NewTypeError("object_not_extensible",
2088 isolate->Throw(*error); 2038 HandleVector(args, 1)));
2089 return Handle<Object>();
2090 } 2039 }
2091 } 2040 }
2092 2041
2093 if (object->HasFastProperties()) { 2042 if (HasFastProperties()) {
2094 // Ensure the descriptor array does not get too big. 2043 // Ensure the descriptor array does not get too big.
2095 if (object->map()->NumberOfOwnDescriptors() < 2044 if (map_of_this->NumberOfOwnDescriptors() <
2096 DescriptorArray::kMaxNumberOfDescriptors) { 2045 DescriptorArray::kMaxNumberOfDescriptors) {
2097 // TODO(verwaest): Support other constants. 2046 // TODO(verwaest): Support other constants.
2098 // if (mode == ALLOW_AS_CONSTANT && 2047 // if (mode == ALLOW_AS_CONSTANT &&
2099 // !value->IsTheHole() && 2048 // !value->IsTheHole() &&
2100 // !value->IsConsString()) { 2049 // !value->IsConsString()) {
2101 if (value->IsJSFunction()) { 2050 if (value->IsJSFunction()) {
2102 AddConstantProperty(object, name, value, attributes, transition_flag); 2051 result = AddConstantProperty(name, value, attributes, transition_flag);
2103 } else { 2052 } else {
2104 AddFastProperty(object, name, value, attributes, store_mode, 2053 result = AddFastProperty(
2105 value_type, transition_flag); 2054 name, value, attributes, store_mode, value_type, transition_flag);
2106 } 2055 }
2107 } else { 2056 } else {
2108 // Normalize the object to prevent very large instance descriptors. 2057 // Normalize the object to prevent very large instance descriptors.
2109 // This eliminates unwanted N^2 allocation and lookup behavior. 2058 // This eliminates unwanted N^2 allocation and lookup behavior.
2110 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 2059 Object* obj;
2111 AddSlowProperty(object, name, value, attributes); 2060 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2061 if (!maybe->To(&obj)) return maybe;
2062 result = AddSlowProperty(name, value, attributes);
2112 } 2063 }
2113 } else { 2064 } else {
2114 AddSlowProperty(object, name, value, attributes); 2065 result = AddSlowProperty(name, value, attributes);
2115 } 2066 }
2116 2067
2117 if (FLAG_harmony_observation && object->map()->is_observed()) { 2068 Handle<Object> hresult;
2118 Handle<Object> old_value = isolate->factory()->the_hole_value(); 2069 if (!result->ToHandle(&hresult, isolate)) return result;
2119 EnqueueChangeRecord(object, "new", name, old_value); 2070
2071 if (FLAG_harmony_observation && map()->is_observed()) {
2072 EnqueueChangeRecord(handle(this, isolate),
2073 "new",
2074 handle(name, isolate),
2075 handle(heap->the_hole_value(), isolate));
2120 } 2076 }
2121 2077
2122 return value; 2078 return *hresult;
2123 } 2079 }
2124 2080
2125 2081
2126 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, 2082 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
2127 const char* type_str, 2083 const char* type_str,
2128 Handle<Name> name, 2084 Handle<Name> name,
2129 Handle<Object> old_value) { 2085 Handle<Object> old_value) {
2130 Isolate* isolate = object->GetIsolate(); 2086 Isolate* isolate = object->GetIsolate();
2131 HandleScope scope(isolate); 2087 HandleScope scope(isolate);
2132 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); 2088 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str);
(...skipping 19 matching lines...) Expand all
2152 isolate->observers_deliver_changes(), 2108 isolate->observers_deliver_changes(),
2153 isolate->factory()->undefined_value(), 2109 isolate->factory()->undefined_value(),
2154 0, 2110 0,
2155 NULL, 2111 NULL,
2156 &threw); 2112 &threw);
2157 ASSERT(!threw); 2113 ASSERT(!threw);
2158 isolate->set_observer_delivery_pending(false); 2114 isolate->set_observer_delivery_pending(false);
2159 } 2115 }
2160 2116
2161 2117
2162 Handle<Object> JSObject::SetPropertyPostInterceptor( 2118 MaybeObject* JSObject::SetPropertyPostInterceptor(
2163 Handle<JSObject> object, 2119 Name* name,
2164 Handle<Name> name, 2120 Object* value,
2165 Handle<Object> value,
2166 PropertyAttributes attributes, 2121 PropertyAttributes attributes,
2167 StrictModeFlag strict_mode) { 2122 StrictModeFlag strict_mode,
2123 StoreMode mode) {
2168 // Check local property, ignore interceptor. 2124 // Check local property, ignore interceptor.
2169 LookupResult result(object->GetIsolate()); 2125 LookupResult result(GetIsolate());
2170 object->LocalLookupRealNamedProperty(*name, &result); 2126 LocalLookupRealNamedProperty(name, &result);
2171 if (!result.IsFound()) { 2127 if (!result.IsFound()) map()->LookupTransition(this, name, &result);
2172 object->map()->LookupTransition(*object, *name, &result);
2173 }
2174 if (result.IsFound()) { 2128 if (result.IsFound()) {
2175 // An existing property or a map transition was found. Use set property to 2129 // An existing property or a map transition was found. Use set property to
2176 // handle all these cases. 2130 // handle all these cases.
2177 return SetPropertyForResult(object, &result, name, value, attributes, 2131 return SetProperty(&result, name, value, attributes, strict_mode);
2178 strict_mode, MAY_BE_STORE_FROM_KEYED);
2179 } 2132 }
2180 bool done = false; 2133 bool done = false;
2181 Handle<Object> result_object = SetPropertyViaPrototypes( 2134 MaybeObject* result_object =
2182 object, name, value, attributes, strict_mode, &done); 2135 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
2183 if (done) return result_object; 2136 if (done) return result_object;
2184 // Add a new real property. 2137 // Add a new real property.
2185 return AddProperty(object, name, value, attributes, strict_mode); 2138 return AddProperty(name, value, attributes, strict_mode,
2139 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK,
2140 OPTIMAL_REPRESENTATION, mode);
2186 } 2141 }
2187 2142
2188 2143
2189 static Handle<Object> ReplaceSlowProperty(Handle<JSObject> object, 2144 MaybeObject* JSObject::ReplaceSlowProperty(Name* name,
2190 Handle<Name> name, 2145 Object* value,
2191 Handle<Object> value, 2146 PropertyAttributes attributes) {
2192 PropertyAttributes attributes) { 2147 NameDictionary* dictionary = property_dictionary();
2193 NameDictionary* dictionary = object->property_dictionary(); 2148 int old_index = dictionary->FindEntry(name);
2194 int old_index = dictionary->FindEntry(*name);
2195 int new_enumeration_index = 0; // 0 means "Use the next available index." 2149 int new_enumeration_index = 0; // 0 means "Use the next available index."
2196 if (old_index != -1) { 2150 if (old_index != -1) {
2197 // All calls to ReplaceSlowProperty have had all transitions removed. 2151 // All calls to ReplaceSlowProperty have had all transitions removed.
2198 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); 2152 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
2199 } 2153 }
2200 2154
2201 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 2155 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
2202 return JSObject::SetNormalizedProperty(object, name, value, new_details); 2156 return SetNormalizedProperty(name, value, new_details);
2203 } 2157 }
2204 2158
2205 2159
2206 const char* Representation::Mnemonic() const { 2160 const char* Representation::Mnemonic() const {
2207 switch (kind_) { 2161 switch (kind_) {
2208 case kNone: return "v"; 2162 case kNone: return "v";
2209 case kTagged: return "t"; 2163 case kTagged: return "t";
2210 case kSmi: return "s"; 2164 case kSmi: return "s";
2211 case kDouble: return "d"; 2165 case kDouble: return "d";
2212 case kInteger32: return "i"; 2166 case kInteger32: return "i";
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2299 ASSERT(target_inobject < inobject_properties()); 2253 ASSERT(target_inobject < inobject_properties());
2300 if (target_number_of_fields <= target_inobject) { 2254 if (target_number_of_fields <= target_inobject) {
2301 ASSERT(target_number_of_fields + target_unused == target_inobject); 2255 ASSERT(target_number_of_fields + target_unused == target_inobject);
2302 return false; 2256 return false;
2303 } 2257 }
2304 // Otherwise, properties will need to be moved to the backing store. 2258 // Otherwise, properties will need to be moved to the backing store.
2305 return true; 2259 return true;
2306 } 2260 }
2307 2261
2308 2262
2309 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
2310 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->MigrateToMap(*new_map));
2311 }
2312
2313
2314 // To migrate an instance to a map: 2263 // To migrate an instance to a map:
2315 // - First check whether the instance needs to be rewritten. If not, simply 2264 // - First check whether the instance needs to be rewritten. If not, simply
2316 // change the map. 2265 // change the map.
2317 // - Otherwise, allocate a fixed array large enough to hold all fields, in 2266 // - Otherwise, allocate a fixed array large enough to hold all fields, in
2318 // addition to unused space. 2267 // addition to unused space.
2319 // - Copy all existing properties in, in the following order: backing store 2268 // - Copy all existing properties in, in the following order: backing store
2320 // properties, unused fields, inobject properties. 2269 // properties, unused fields, inobject properties.
2321 // - If all allocation succeeded, commit the state atomically: 2270 // - If all allocation succeeded, commit the state atomically:
2322 // * Copy inobject properties from the backing store back into the object. 2271 // * Copy inobject properties from the backing store back into the object.
2323 // * Trim the difference in instance size of the object. This also cleanly 2272 // * Trim the difference in instance size of the object. This also cleanly
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject); 2354 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject);
2406 set_properties(array); 2355 set_properties(array);
2407 } 2356 }
2408 2357
2409 set_map(new_map); 2358 set_map(new_map);
2410 2359
2411 return this; 2360 return this;
2412 } 2361 }
2413 2362
2414 2363
2415 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, 2364 MaybeObject* JSObject::GeneralizeFieldRepresentation(
2416 int modify_index, 2365 int modify_index,
2417 Representation new_representation, 2366 Representation new_representation,
2418 StoreMode store_mode) { 2367 StoreMode store_mode) {
2419 Handle<Map> new_map = Map::GeneralizeRepresentation( 2368 Map* new_map;
2420 handle(object->map()), modify_index, new_representation, store_mode); 2369 MaybeObject* maybe_new_map = map()->GeneralizeRepresentation(
2421 if (object->map() == *new_map) return; 2370 modify_index, new_representation, store_mode);
2422 return MigrateToMap(object, new_map); 2371 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2372 if (map() == new_map) return this;
2373
2374 return MigrateToMap(new_map);
2423 } 2375 }
2424 2376
2425 2377
2426 int Map::NumberOfFields() { 2378 int Map::NumberOfFields() {
2427 DescriptorArray* descriptors = instance_descriptors(); 2379 DescriptorArray* descriptors = instance_descriptors();
2428 int result = 0; 2380 int result = 0;
2429 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { 2381 for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
2430 if (descriptors->GetDetails(i).type() == FIELD) result++; 2382 if (descriptors->GetDetails(i).type() == FIELD) result++;
2431 } 2383 }
2432 return result; 2384 return result;
2433 } 2385 }
2434 2386
2435 2387
2436 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, 2388 MaybeObject* Map::CopyGeneralizeAllRepresentations(
2437 int modify_index, 2389 int modify_index,
2438 StoreMode store_mode, 2390 StoreMode store_mode,
2439 PropertyAttributes attributes, 2391 PropertyAttributes attributes,
2440 const char* reason) { 2392 const char* reason) {
2441 Handle<Map> new_map = Copy(map); 2393 Map* new_map;
2394 MaybeObject* maybe_map = this->Copy();
2395 if (!maybe_map->To(&new_map)) return maybe_map;
2442 2396
2443 DescriptorArray* descriptors = new_map->instance_descriptors(); 2397 DescriptorArray* descriptors = new_map->instance_descriptors();
2444 descriptors->InitializeRepresentations(Representation::Tagged()); 2398 descriptors->InitializeRepresentations(Representation::Tagged());
2445 2399
2446 // Unless the instance is being migrated, ensure that modify_index is a field. 2400 // Unless the instance is being migrated, ensure that modify_index is a field.
2447 PropertyDetails details = descriptors->GetDetails(modify_index); 2401 PropertyDetails details = descriptors->GetDetails(modify_index);
2448 if (store_mode == FORCE_FIELD && details.type() != FIELD) { 2402 if (store_mode == FORCE_FIELD && details.type() != FIELD) {
2449 FieldDescriptor d(descriptors->GetKey(modify_index), 2403 FieldDescriptor d(descriptors->GetKey(modify_index),
2450 new_map->NumberOfFields(), 2404 new_map->NumberOfFields(),
2451 attributes, 2405 attributes,
2452 Representation::Tagged()); 2406 Representation::Tagged());
2453 d.SetSortedKeyIndex(details.pointer()); 2407 d.SetSortedKeyIndex(details.pointer());
2454 descriptors->Set(modify_index, &d); 2408 descriptors->Set(modify_index, &d);
2455 int unused_property_fields = new_map->unused_property_fields() - 1; 2409 int unused_property_fields = new_map->unused_property_fields() - 1;
2456 if (unused_property_fields < 0) { 2410 if (unused_property_fields < 0) {
2457 unused_property_fields += JSObject::kFieldsAdded; 2411 unused_property_fields += JSObject::kFieldsAdded;
2458 } 2412 }
2459 new_map->set_unused_property_fields(unused_property_fields); 2413 new_map->set_unused_property_fields(unused_property_fields);
2460 } 2414 }
2461 2415
2462 if (FLAG_trace_generalization) { 2416 if (FLAG_trace_generalization) {
2463 map->PrintGeneralization(stdout, reason, modify_index, 2417 PrintGeneralization(stdout, reason, modify_index,
2464 new_map->NumberOfOwnDescriptors(), 2418 new_map->NumberOfOwnDescriptors(),
2465 new_map->NumberOfOwnDescriptors(), 2419 new_map->NumberOfOwnDescriptors(),
2466 details.type() == CONSTANT && store_mode == FORCE_FIELD, 2420 details.type() == CONSTANT && store_mode == FORCE_FIELD,
2467 Representation::Tagged(), Representation::Tagged()); 2421 Representation::Tagged(), Representation::Tagged());
2468 } 2422 }
2469 return new_map; 2423 return new_map;
2470 } 2424 }
2471 2425
2472 2426
2473 void Map::DeprecateTransitionTree() { 2427 void Map::DeprecateTransitionTree() {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2601 // FindUpdatedMap. This uses the keys in the own map's descriptor array to 2555 // FindUpdatedMap. This uses the keys in the own map's descriptor array to
2602 // walk the transition tree. 2556 // walk the transition tree.
2603 // - Merge/generalize the descriptor array of the current map and |updated|. 2557 // - Merge/generalize the descriptor array of the current map and |updated|.
2604 // - Generalize the |modify_index| descriptor using |new_representation|. 2558 // - Generalize the |modify_index| descriptor using |new_representation|.
2605 // - Walk the tree again starting from the root towards |updated|. Stop at 2559 // - Walk the tree again starting from the root towards |updated|. Stop at
2606 // |split_map|, the first map who's descriptor array does not match the merged 2560 // |split_map|, the first map who's descriptor array does not match the merged
2607 // descriptor array. 2561 // descriptor array.
2608 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. 2562 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2609 // - Otherwise, invalidate the outdated transition target from |updated|, and 2563 // - Otherwise, invalidate the outdated transition target from |updated|, and
2610 // replace its transition tree with a new branch for the updated descriptors. 2564 // replace its transition tree with a new branch for the updated descriptors.
2611 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, 2565 MaybeObject* Map::GeneralizeRepresentation(int modify_index,
2612 int modify_index, 2566 Representation new_representation,
2613 Representation new_representation, 2567 StoreMode store_mode) {
2614 StoreMode store_mode) { 2568 Map* old_map = this;
2615 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); 2569 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2616 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2570 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2617 Representation old_representation = old_details.representation(); 2571 Representation old_representation = old_details.representation();
2618 2572
2619 // It's fine to transition from None to anything but double without any 2573 // It's fine to transition from None to anything but double without any
2620 // modification to the object, because the default uninitialized value for 2574 // modification to the object, because the default uninitialized value for
2621 // representation None can be overwritten by both smi and tagged values. 2575 // representation None can be overwritten by both smi and tagged values.
2622 // Doubles, however, would require a box allocation. 2576 // Doubles, however, would require a box allocation.
2623 if (old_representation.IsNone() && 2577 if (old_representation.IsNone() &&
2624 !new_representation.IsNone() && 2578 !new_representation.IsNone() &&
2625 !new_representation.IsDouble()) { 2579 !new_representation.IsDouble()) {
2626 old_descriptors->SetRepresentation(modify_index, new_representation); 2580 old_descriptors->SetRepresentation(modify_index, new_representation);
2627 return old_map; 2581 return old_map;
2628 } 2582 }
2629 2583
2630 int descriptors = old_map->NumberOfOwnDescriptors(); 2584 int descriptors = old_map->NumberOfOwnDescriptors();
2631 Handle<Map> root_map(old_map->FindRootMap()); 2585 Map* root_map = old_map->FindRootMap();
2632 2586
2633 // Check the state of the root map. 2587 // Check the state of the root map.
2634 if (!old_map->EquivalentToForTransition(*root_map)) { 2588 if (!old_map->EquivalentToForTransition(root_map)) {
2635 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2589 return CopyGeneralizeAllRepresentations(
2636 old_details.attributes(), "not equivalent"); 2590 modify_index, store_mode, old_details.attributes(), "not equivalent");
2637 } 2591 }
2638 2592
2639 int verbatim = root_map->NumberOfOwnDescriptors(); 2593 int verbatim = root_map->NumberOfOwnDescriptors();
2640 2594
2641 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { 2595 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2642 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2596 return CopyGeneralizeAllRepresentations(
2597 modify_index, store_mode,
2643 old_details.attributes(), "root modification"); 2598 old_details.attributes(), "root modification");
2644 } 2599 }
2645 2600
2646 Map* raw_updated = root_map->FindUpdatedMap( 2601 Map* updated = root_map->FindUpdatedMap(
2647 verbatim, descriptors, *old_descriptors); 2602 verbatim, descriptors, old_descriptors);
2648 if (raw_updated == NULL) { 2603 if (updated == NULL) {
2649 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2604 return CopyGeneralizeAllRepresentations(
2650 old_details.attributes(), "incompatible"); 2605 modify_index, store_mode, old_details.attributes(), "incompatible");
2651 } 2606 }
2652 2607
2653 Handle<Map> updated(raw_updated); 2608 DescriptorArray* updated_descriptors = updated->instance_descriptors();
2654 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors());
2655 2609
2656 int valid = updated->NumberOfOwnDescriptors(); 2610 int valid = updated->NumberOfOwnDescriptors();
2657 2611
2658 // Directly change the map if the target map is more general. Ensure that the 2612 // Directly change the map if the target map is more general. Ensure that the
2659 // target type of the modify_index is a FIELD, unless we are migrating. 2613 // target type of the modify_index is a FIELD, unless we are migrating.
2660 if (updated_descriptors->IsMoreGeneralThan( 2614 if (updated_descriptors->IsMoreGeneralThan(
2661 verbatim, valid, descriptors, *old_descriptors) && 2615 verbatim, valid, descriptors, old_descriptors) &&
2662 (store_mode == ALLOW_AS_CONSTANT || 2616 (store_mode == ALLOW_AS_CONSTANT ||
2663 updated_descriptors->GetDetails(modify_index).type() == FIELD)) { 2617 updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
2664 Representation updated_representation = 2618 Representation updated_representation =
2665 updated_descriptors->GetDetails(modify_index).representation(); 2619 updated_descriptors->GetDetails(modify_index).representation();
2666 if (new_representation.fits_into(updated_representation)) return updated; 2620 if (new_representation.fits_into(updated_representation)) return updated;
2667 } 2621 }
2668 2622
2669 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge( 2623 DescriptorArray* new_descriptors;
2670 updated_descriptors, verbatim, valid, descriptors, modify_index, 2624 MaybeObject* maybe_descriptors = updated_descriptors->Merge(
2671 store_mode, old_descriptors); 2625 verbatim, valid, descriptors, modify_index, store_mode, old_descriptors);
2626 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
2672 ASSERT(store_mode == ALLOW_AS_CONSTANT || 2627 ASSERT(store_mode == ALLOW_AS_CONSTANT ||
2673 new_descriptors->GetDetails(modify_index).type() == FIELD); 2628 new_descriptors->GetDetails(modify_index).type() == FIELD);
2674 2629
2675 old_representation = 2630 old_representation =
2676 new_descriptors->GetDetails(modify_index).representation(); 2631 new_descriptors->GetDetails(modify_index).representation();
2677 Representation updated_representation = 2632 Representation updated_representation =
2678 new_representation.generalize(old_representation); 2633 new_representation.generalize(old_representation);
2679 if (!updated_representation.Equals(old_representation)) { 2634 if (!updated_representation.Equals(old_representation)) {
2680 new_descriptors->SetRepresentation(modify_index, updated_representation); 2635 new_descriptors->SetRepresentation(modify_index, updated_representation);
2681 } 2636 }
2682 2637
2683 Handle<Map> split_map(root_map->FindLastMatchMap( 2638 Map* split_map = root_map->FindLastMatchMap(
2684 verbatim, descriptors, *new_descriptors)); 2639 verbatim, descriptors, new_descriptors);
2685 2640
2686 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2641 int split_descriptors = split_map->NumberOfOwnDescriptors();
2687 // This is shadowed by |updated_descriptors| being more general than 2642 // This is shadowed by |updated_descriptors| being more general than
2688 // |old_descriptors|. 2643 // |old_descriptors|.
2689 ASSERT(descriptors != split_descriptors); 2644 ASSERT(descriptors != split_descriptors);
2690 2645
2691 int descriptor = split_descriptors; 2646 int descriptor = split_descriptors;
2692 split_map->DeprecateTarget( 2647 split_map->DeprecateTarget(
2693 old_descriptors->GetKey(descriptor), *new_descriptors); 2648 old_descriptors->GetKey(descriptor), new_descriptors);
2694 2649
2695 if (FLAG_trace_generalization) { 2650 if (FLAG_trace_generalization) {
2696 old_map->PrintGeneralization( 2651 PrintGeneralization(
2697 stdout, "", modify_index, descriptor, descriptors, 2652 stdout, "", modify_index, descriptor, descriptors,
2698 old_descriptors->GetDetails(modify_index).type() == CONSTANT && 2653 old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
2699 store_mode == FORCE_FIELD, 2654 store_mode == FORCE_FIELD,
2700 old_representation, updated_representation); 2655 old_representation, updated_representation);
2701 } 2656 }
2702 2657
2658 Map* new_map = split_map;
2703 // Add missing transitions. 2659 // Add missing transitions.
2704 Handle<Map> new_map = split_map;
2705 for (; descriptor < descriptors; descriptor++) { 2660 for (; descriptor < descriptors; descriptor++) {
2706 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); 2661 MaybeObject* maybe_map = new_map->CopyInstallDescriptors(
2662 descriptor, new_descriptors);
2663 if (!maybe_map->To(&new_map)) {
2664 // Create a handle for the last created map to ensure it stays alive
2665 // during GC. Its descriptor array is too large, but it will be
2666 // overwritten during retry anyway.
2667 Handle<Map>(new_map);
2668 return maybe_map;
2669 }
2707 new_map->set_migration_target(true); 2670 new_map->set_migration_target(true);
2708 } 2671 }
2709 2672
2710 new_map->set_owns_descriptors(true); 2673 new_map->set_owns_descriptors(true);
2711 return new_map; 2674 return new_map;
2712 } 2675 }
2713 2676
2714 2677
2715 Map* Map::CurrentMapForDeprecated() { 2678 Map* Map::CurrentMapForDeprecated() {
2716 DisallowHeapAllocation no_allocation; 2679 DisallowHeapAllocation no_allocation;
(...skipping 16 matching lines...) Expand all
2733 int valid = updated->NumberOfOwnDescriptors(); 2696 int valid = updated->NumberOfOwnDescriptors();
2734 if (!updated_descriptors->IsMoreGeneralThan( 2697 if (!updated_descriptors->IsMoreGeneralThan(
2735 verbatim, valid, descriptors, old_descriptors)) { 2698 verbatim, valid, descriptors, old_descriptors)) {
2736 return NULL; 2699 return NULL;
2737 } 2700 }
2738 2701
2739 return updated; 2702 return updated;
2740 } 2703 }
2741 2704
2742 2705
2743 Handle<Object> JSObject::SetPropertyWithInterceptor( 2706 MaybeObject* JSObject::SetPropertyWithInterceptor(
2744 Handle<JSObject> object, 2707 Name* name,
2745 Handle<Name> name, 2708 Object* value,
2746 Handle<Object> value,
2747 PropertyAttributes attributes, 2709 PropertyAttributes attributes,
2748 StrictModeFlag strict_mode) { 2710 StrictModeFlag strict_mode) {
2749 // TODO(rossberg): Support symbols in the API. 2711 // TODO(rossberg): Support symbols in the API.
2750 if (name->IsSymbol()) return value; 2712 if (name->IsSymbol()) return value;
2751 Isolate* isolate = object->GetIsolate(); 2713 Isolate* isolate = GetIsolate();
2752 Handle<String> name_string = Handle<String>::cast(name); 2714 HandleScope scope(isolate);
2753 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); 2715 Handle<JSObject> this_handle(this);
2716 Handle<String> name_handle(String::cast(name));
2717 Handle<Object> value_handle(value, isolate);
2718 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2754 if (!interceptor->setter()->IsUndefined()) { 2719 if (!interceptor->setter()->IsUndefined()) {
2755 LOG(isolate, 2720 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name));
2756 ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); 2721 PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
2757 PropertyCallbackArguments args(
2758 isolate, interceptor->data(), *object, *object);
2759 v8::NamedPropertySetterCallback setter = 2722 v8::NamedPropertySetterCallback setter =
2760 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); 2723 v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
2761 Handle<Object> value_unhole = value->IsTheHole() 2724 Handle<Object> value_unhole(value->IsTheHole() ?
2762 ? Handle<Object>(isolate->factory()->undefined_value()) : value; 2725 isolate->heap()->undefined_value() :
2726 value,
2727 isolate);
2763 v8::Handle<v8::Value> result = args.Call(setter, 2728 v8::Handle<v8::Value> result = args.Call(setter,
2764 v8::Utils::ToLocal(name_string), 2729 v8::Utils::ToLocal(name_handle),
2765 v8::Utils::ToLocal(value_unhole)); 2730 v8::Utils::ToLocal(value_unhole));
2766 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 2731 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2767 if (!result.IsEmpty()) return value; 2732 if (!result.IsEmpty()) return *value_handle;
2768 } 2733 }
2769 Handle<Object> result = 2734 MaybeObject* raw_result =
2770 SetPropertyPostInterceptor(object, name, value, attributes, strict_mode); 2735 this_handle->SetPropertyPostInterceptor(*name_handle,
2771 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 2736 *value_handle,
2772 return result; 2737 attributes,
2738 strict_mode);
2739 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2740 return raw_result;
2773 } 2741 }
2774 2742
2775 2743
2776 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 2744 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
2777 Handle<Name> name, 2745 Handle<Name> key,
2778 Handle<Object> value, 2746 Handle<Object> value,
2779 PropertyAttributes attributes, 2747 PropertyAttributes attributes,
2780 StrictModeFlag strict_mode, 2748 StrictModeFlag strict_mode) {
2781 StoreFromKeyed store_mode) { 2749 CALL_HEAP_FUNCTION(object->GetIsolate(),
2782 LookupResult result(object->GetIsolate()); 2750 object->SetProperty(*key, *value, attributes, strict_mode),
2783 object->LocalLookup(*name, &result, true); 2751 Object);
2784 if (!result.IsFound()) {
2785 object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
2786 }
2787 return SetProperty(object, &result, name, value, attributes, strict_mode,
2788 store_mode);
2789 } 2752 }
2790 2753
2791 2754
2755 MaybeObject* JSReceiver::SetPropertyOrFail(
2756 Handle<JSReceiver> object,
2757 Handle<Name> key,
2758 Handle<Object> value,
2759 PropertyAttributes attributes,
2760 StrictModeFlag strict_mode,
2761 JSReceiver::StoreFromKeyed store_mode) {
2762 CALL_HEAP_FUNCTION_PASS_EXCEPTION(
2763 object->GetIsolate(),
2764 object->SetProperty(*key, *value, attributes, strict_mode, store_mode));
2765 }
2766
2767
2768 MaybeObject* JSReceiver::SetProperty(Name* name,
2769 Object* value,
2770 PropertyAttributes attributes,
2771 StrictModeFlag strict_mode,
2772 JSReceiver::StoreFromKeyed store_mode) {
2773 LookupResult result(GetIsolate());
2774 LocalLookup(name, &result, true);
2775 if (!result.IsFound()) {
2776 map()->LookupTransition(JSObject::cast(this), name, &result);
2777 }
2778 return SetProperty(&result, name, value, attributes, strict_mode, store_mode);
2779 }
2780
2781
2792 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, 2782 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
2793 Name* name, 2783 Name* name,
2794 Object* value, 2784 Object* value,
2795 JSObject* holder, 2785 JSObject* holder,
2796 StrictModeFlag strict_mode) { 2786 StrictModeFlag strict_mode) {
2797 Isolate* isolate = GetIsolate(); 2787 Isolate* isolate = GetIsolate();
2798 HandleScope scope(isolate); 2788 HandleScope scope(isolate);
2799 2789
2800 // We should never get here to initialize a const with the hole 2790 // We should never get here to initialize a const with the hole
2801 // value since a const declaration would conflict with the setter. 2791 // value since a const declaration would conflict with the setter.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2933 value, 2923 value,
2934 JSObject::cast(pt), 2924 JSObject::cast(pt),
2935 strict_mode); 2925 strict_mode);
2936 } 2926 }
2937 } 2927 }
2938 } 2928 }
2939 *found = false; 2929 *found = false;
2940 return heap->the_hole_value(); 2930 return heap->the_hole_value();
2941 } 2931 }
2942 2932
2943 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, 2933 MaybeObject* JSObject::SetPropertyViaPrototypes(
2944 Handle<Name> name, 2934 Name* name,
2945 Handle<Object> value, 2935 Object* value,
2946 PropertyAttributes attributes, 2936 PropertyAttributes attributes,
2947 StrictModeFlag strict_mode, 2937 StrictModeFlag strict_mode,
2948 bool* done) { 2938 bool* done) {
2949 Isolate* isolate = object->GetIsolate(); 2939 Heap* heap = GetHeap();
2940 Isolate* isolate = heap->isolate();
2950 2941
2951 *done = false; 2942 *done = false;
2952 // We could not find a local property so let's check whether there is an 2943 // We could not find a local property so let's check whether there is an
2953 // accessor that wants to handle the property, or whether the property is 2944 // accessor that wants to handle the property, or whether the property is
2954 // read-only on the prototype chain. 2945 // read-only on the prototype chain.
2955 LookupResult result(isolate); 2946 LookupResult result(isolate);
2956 object->LookupRealNamedPropertyInPrototypes(*name, &result); 2947 LookupRealNamedPropertyInPrototypes(name, &result);
2957 if (result.IsFound()) { 2948 if (result.IsFound()) {
2958 switch (result.type()) { 2949 switch (result.type()) {
2959 case NORMAL: 2950 case NORMAL:
2960 case FIELD: 2951 case FIELD:
2961 case CONSTANT: 2952 case CONSTANT:
2962 *done = result.IsReadOnly(); 2953 *done = result.IsReadOnly();
2963 break; 2954 break;
2964 case INTERCEPTOR: { 2955 case INTERCEPTOR: {
2965 PropertyAttributes attr = 2956 PropertyAttributes attr =
2966 result.holder()->GetPropertyAttributeWithInterceptor( 2957 result.holder()->GetPropertyAttributeWithInterceptor(
2967 *object, *name, true); 2958 this, name, true);
2968 *done = !!(attr & READ_ONLY); 2959 *done = !!(attr & READ_ONLY);
2969 break; 2960 break;
2970 } 2961 }
2971 case CALLBACKS: { 2962 case CALLBACKS: {
2972 if (!FLAG_es5_readonly && result.IsReadOnly()) break; 2963 if (!FLAG_es5_readonly && result.IsReadOnly()) break;
2973 *done = true; 2964 *done = true;
2974 CALL_HEAP_FUNCTION(isolate, 2965 return SetPropertyWithCallback(result.GetCallbackObject(),
2975 object->SetPropertyWithCallback( 2966 name, value, result.holder(), strict_mode);
2976 result.GetCallbackObject(),
2977 *name, *value, result.holder(), strict_mode),
2978 Object);
2979 } 2967 }
2980 case HANDLER: { 2968 case HANDLER: {
2981 CALL_HEAP_FUNCTION(isolate, 2969 return result.proxy()->SetPropertyViaPrototypesWithHandler(
2982 result.proxy()->SetPropertyViaPrototypesWithHandler( 2970 this, name, value, attributes, strict_mode, done);
2983 *object, *name, *value, attributes, strict_mode,
2984 done),
2985 Object);
2986 } 2971 }
2987 case TRANSITION: 2972 case TRANSITION:
2988 case NONEXISTENT: 2973 case NONEXISTENT:
2989 UNREACHABLE(); 2974 UNREACHABLE();
2990 break; 2975 break;
2991 } 2976 }
2992 } 2977 }
2993 2978
2994 // If we get here with *done true, we have encountered a read-only property. 2979 // If we get here with *done true, we have encountered a read-only property.
2995 if (!FLAG_es5_readonly) *done = false; 2980 if (!FLAG_es5_readonly) *done = false;
2996 if (*done) { 2981 if (*done) {
2997 if (strict_mode == kNonStrictMode) return value; 2982 if (strict_mode == kNonStrictMode) return value;
2998 Handle<Object> args[] = { name, object }; 2983 Handle<Object> args[] = { Handle<Object>(name, isolate),
2999 Handle<Object> error = isolate->factory()->NewTypeError( 2984 Handle<Object>(this, isolate)};
3000 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 2985 return isolate->Throw(*isolate->factory()->NewTypeError(
3001 isolate->Throw(*error); 2986 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
3002 return Handle<Object>();
3003 } 2987 }
3004 return isolate->factory()->the_hole_value(); 2988 return heap->the_hole_value();
3005 } 2989 }
3006 2990
3007 2991
3008 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { 2992 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
3009 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 2993 Handle<DescriptorArray> descriptors(map->instance_descriptors());
3010 if (slack <= descriptors->NumberOfSlackDescriptors()) return; 2994 if (slack <= descriptors->NumberOfSlackDescriptors()) return;
3011 int number_of_descriptors = descriptors->number_of_descriptors(); 2995 int number_of_descriptors = descriptors->number_of_descriptors();
3012 Isolate* isolate = map->GetIsolate(); 2996 Isolate* isolate = map->GetIsolate();
3013 Handle<DescriptorArray> new_descriptors = 2997 Handle<DescriptorArray> new_descriptors =
3014 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack); 2998 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
3415 3399
3416 Isolate* isolate = GetIsolate(); 3400 Isolate* isolate = GetIsolate();
3417 HandleScope scope(isolate); 3401 HandleScope scope(isolate);
3418 Handle<Object> value_handle(value, isolate); 3402 Handle<Object> value_handle(value, isolate);
3419 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 3403 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
3420 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 3404 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
3421 return *value_handle; 3405 return *value_handle;
3422 } 3406 }
3423 3407
3424 3408
3425 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 3409 MaybeObject* JSReceiver::SetProperty(LookupResult* result,
3426 LookupResult* result, 3410 Name* key,
3427 Handle<Name> key, 3411 Object* value,
3428 Handle<Object> value, 3412 PropertyAttributes attributes,
3429 PropertyAttributes attributes, 3413 StrictModeFlag strict_mode,
3430 StrictModeFlag strict_mode, 3414 JSReceiver::StoreFromKeyed store_mode) {
3431 StoreFromKeyed store_mode) {
3432 if (result->IsHandler()) { 3415 if (result->IsHandler()) {
3433 return JSProxy::SetPropertyWithHandler(handle(result->proxy()), 3416 return result->proxy()->SetPropertyWithHandler(
3434 object, key, value, attributes, strict_mode); 3417 this, key, value, attributes, strict_mode);
3435 } else { 3418 } else {
3436 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object), 3419 return JSObject::cast(this)->SetPropertyForResult(
3437 result, key, value, attributes, strict_mode, store_mode); 3420 result, key, value, attributes, strict_mode, store_mode);
3438 } 3421 }
3439 } 3422 }
3440 3423
3441 3424
3442 bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) { 3425 bool JSProxy::HasPropertyWithHandler(Name* name_raw) {
3443 Isolate* isolate = proxy->GetIsolate(); 3426 Isolate* isolate = GetIsolate();
3427 HandleScope scope(isolate);
3428 Handle<Object> receiver(this, isolate);
3429 Handle<Object> name(name_raw, isolate);
3444 3430
3445 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3431 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3446 if (name->IsSymbol()) return false; 3432 if (name->IsSymbol()) return false;
3447 3433
3448 Handle<Object> args[] = { name }; 3434 Handle<Object> args[] = { name };
3449 Handle<Object> result = proxy->CallTrap( 3435 Handle<Object> result = CallTrap(
3450 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); 3436 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args);
3451 if (isolate->has_pending_exception()) return false; 3437 if (isolate->has_pending_exception()) return false;
3452 3438
3453 return result->BooleanValue(); 3439 return result->BooleanValue();
3454 } 3440 }
3455 3441
3456 3442
3457 Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, 3443 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
3458 Handle<JSReceiver> receiver, 3444 JSReceiver* receiver_raw,
3459 Handle<Name> name, 3445 Name* name_raw,
3460 Handle<Object> value, 3446 Object* value_raw,
3461 PropertyAttributes attributes, 3447 PropertyAttributes attributes,
3462 StrictModeFlag strict_mode) { 3448 StrictModeFlag strict_mode) {
3463 Isolate* isolate = proxy->GetIsolate(); 3449 Isolate* isolate = GetIsolate();
3450 HandleScope scope(isolate);
3451 Handle<JSReceiver> receiver(receiver_raw);
3452 Handle<Object> name(name_raw, isolate);
3453 Handle<Object> value(value_raw, isolate);
3464 3454
3465 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3455 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3466 if (name->IsSymbol()) return value; 3456 if (name->IsSymbol()) return *value;
3467 3457
3468 Handle<Object> args[] = { receiver, name, value }; 3458 Handle<Object> args[] = { receiver, name, value };
3469 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); 3459 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
3470 if (isolate->has_pending_exception()) return Handle<Object>(); 3460 if (isolate->has_pending_exception()) return Failure::Exception();
3471 3461
3472 return value; 3462 return *value;
3473 } 3463 }
3474 3464
3475 3465
3476 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( 3466 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler(
3477 JSReceiver* receiver_raw, 3467 JSReceiver* receiver_raw,
3478 Name* name_raw, 3468 Name* name_raw,
3479 Object* value_raw, 3469 Object* value_raw,
3480 PropertyAttributes attributes, 3470 PropertyAttributes attributes,
3481 StrictModeFlag strict_mode, 3471 StrictModeFlag strict_mode,
3482 bool* done) { 3472 bool* done) {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
3737 3727
3738 3728
3739 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { 3729 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
3740 CALL_HEAP_FUNCTION_VOID( 3730 CALL_HEAP_FUNCTION_VOID(
3741 object->GetIsolate(), 3731 object->GetIsolate(),
3742 object->AllocateStorageForMap(*map)); 3732 object->AllocateStorageForMap(*map));
3743 } 3733 }
3744 3734
3745 3735
3746 void JSObject::MigrateInstance(Handle<JSObject> object) { 3736 void JSObject::MigrateInstance(Handle<JSObject> object) {
3747 // Converting any field to the most specific type will cause the 3737 CALL_HEAP_FUNCTION_VOID(
3748 // GeneralizeFieldRepresentation algorithm to create the most general existing 3738 object->GetIsolate(),
3749 // transition that matches the object. This achieves what is needed. 3739 object->MigrateInstance());
3750 Handle<Map> original_map(object->map());
3751 GeneralizeFieldRepresentation(
3752 object, 0, Representation::None(), ALLOW_AS_CONSTANT);
3753 if (FLAG_trace_migration) {
3754 object->PrintInstanceMigration(stdout, *original_map, object->map());
3755 }
3756 } 3740 }
3757 3741
3758 3742
3759 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3743 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3760 MigrateInstance(object); 3744 CALL_HEAP_FUNCTION(
3761 return object; 3745 object->GetIsolate(),
3746 object->MigrateInstance(),
3747 Object);
3762 } 3748 }
3763 3749
3764 3750
3765 Handle<Object> JSObject::SetPropertyUsingTransition( 3751 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map,
3766 Handle<JSObject> object, 3752 int modify_index,
3767 LookupResult* lookup, 3753 Representation representation,
3768 Handle<Name> name, 3754 StoreMode store_mode) {
3769 Handle<Object> value, 3755 CALL_HEAP_FUNCTION(
3770 PropertyAttributes attributes) { 3756 map->GetIsolate(),
3771 Handle<Map> transition_map(lookup->GetTransitionTarget()); 3757 map->GeneralizeRepresentation(modify_index, representation, store_mode),
3758 Map);
3759 }
3760
3761
3762 static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
3763 Handle<Name> name,
3764 Handle<Object> value,
3765 PropertyAttributes attributes) {
3766 Map* transition_map = lookup->GetTransitionTarget();
3772 int descriptor = transition_map->LastAdded(); 3767 int descriptor = transition_map->LastAdded();
3773 3768
3774 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3769 DescriptorArray* descriptors = transition_map->instance_descriptors();
3775 PropertyDetails details = descriptors->GetDetails(descriptor); 3770 PropertyDetails details = descriptors->GetDetails(descriptor);
3776 3771
3777 if (details.type() == CALLBACKS || attributes != details.attributes()) { 3772 if (details.type() == CALLBACKS || attributes != details.attributes()) {
3778 // AddProperty will either normalize the object, or create a new fast copy 3773 // AddProperty will either normalize the object, or create a new fast copy
3779 // of the map. If we get a fast copy of the map, all field representations 3774 // of the map. If we get a fast copy of the map, all field representations
3780 // will be tagged since the transition is omitted. 3775 // will be tagged since the transition is omitted.
3781 return JSObject::AddProperty( 3776 return lookup->holder()->AddProperty(
3782 object, name, value, attributes, kNonStrictMode, 3777 *name, *value, attributes, kNonStrictMode,
3783 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, 3778 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
3784 JSReceiver::OMIT_EXTENSIBILITY_CHECK, 3779 JSReceiver::OMIT_EXTENSIBILITY_CHECK,
3785 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); 3780 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
3786 } 3781 }
3787 3782
3788 // Keep the target CONSTANT if the same value is stored. 3783 // Keep the target CONSTANT if the same value is stored.
3789 // TODO(verwaest): Also support keeping the placeholder 3784 // TODO(verwaest): Also support keeping the placeholder
3790 // (value->IsUninitialized) as constant. 3785 // (value->IsUninitialized) as constant.
3791 if (details.type() == CONSTANT && 3786 if (details.type() == CONSTANT &&
3792 descriptors->GetValue(descriptor) == *value) { 3787 descriptors->GetValue(descriptor) == *value) {
3793 object->set_map(*transition_map); 3788 lookup->holder()->set_map(transition_map);
3794 return value; 3789 return *value;
3795 } 3790 }
3796 3791
3797 Representation representation = details.representation(); 3792 Representation representation = details.representation();
3798 3793
3799 if (!value->FitsRepresentation(representation) || 3794 if (!value->FitsRepresentation(representation) ||
3800 details.type() == CONSTANT) { 3795 details.type() == CONSTANT) {
3801 transition_map = Map::GeneralizeRepresentation(transition_map, 3796 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation(
3802 descriptor, value->OptimalRepresentation(), FORCE_FIELD); 3797 descriptor, value->OptimalRepresentation(), FORCE_FIELD);
3798 if (!maybe_map->To(&transition_map)) return maybe_map;
3803 Object* back = transition_map->GetBackPointer(); 3799 Object* back = transition_map->GetBackPointer();
3804 if (back->IsMap()) { 3800 if (back->IsMap()) {
3805 MigrateToMap(object, handle(Map::cast(back))); 3801 MaybeObject* maybe_failure =
3802 lookup->holder()->MigrateToMap(Map::cast(back));
3803 if (maybe_failure->IsFailure()) return maybe_failure;
3806 } 3804 }
3807 descriptors = transition_map->instance_descriptors(); 3805 descriptors = transition_map->instance_descriptors();
3808 representation = descriptors->GetDetails(descriptor).representation(); 3806 representation = descriptors->GetDetails(descriptor).representation();
3809 } 3807 }
3810 3808
3811 int field_index = descriptors->GetFieldIndex(descriptor); 3809 int field_index = descriptors->GetFieldIndex(descriptor);
3812 return AddFastPropertyUsingMap( 3810 return lookup->holder()->AddFastPropertyUsingMap(
3813 object, transition_map, name, value, field_index, representation); 3811 transition_map, *name, *value, field_index, representation);
3814 } 3812 }
3815 3813
3816 3814
3817 static Handle<Object> SetPropertyToField(LookupResult* lookup, 3815 static MaybeObject* SetPropertyToField(LookupResult* lookup,
3818 Handle<Name> name, 3816 Handle<Name> name,
3819 Handle<Object> value) { 3817 Handle<Object> value) {
3820 Representation representation = lookup->representation(); 3818 Representation representation = lookup->representation();
3821 if (!value->FitsRepresentation(representation) || 3819 if (!value->FitsRepresentation(representation) ||
3822 lookup->type() == CONSTANT) { 3820 lookup->type() == CONSTANT) {
3823 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), 3821 MaybeObject* maybe_failure =
3824 lookup->GetDescriptorIndex(), 3822 lookup->holder()->GeneralizeFieldRepresentation(
3825 value->OptimalRepresentation(), 3823 lookup->GetDescriptorIndex(),
3826 FORCE_FIELD); 3824 value->OptimalRepresentation(),
3825 FORCE_FIELD);
3826 if (maybe_failure->IsFailure()) return maybe_failure;
3827 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); 3827 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3828 int descriptor = lookup->GetDescriptorIndex(); 3828 int descriptor = lookup->GetDescriptorIndex();
3829 representation = desc->GetDetails(descriptor).representation(); 3829 representation = desc->GetDetails(descriptor).representation();
3830 } 3830 }
3831 3831
3832 if (FLAG_track_double_fields && representation.IsDouble()) { 3832 if (FLAG_track_double_fields && representation.IsDouble()) {
3833 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( 3833 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3834 lookup->GetFieldIndex().field_index())); 3834 lookup->GetFieldIndex().field_index()));
3835 storage->set_value(value->Number()); 3835 storage->set_value(value->Number());
3836 return value; 3836 return *value;
3837 } 3837 }
3838 3838
3839 lookup->holder()->FastPropertyAtPut( 3839 lookup->holder()->FastPropertyAtPut(
3840 lookup->GetFieldIndex().field_index(), *value); 3840 lookup->GetFieldIndex().field_index(), *value);
3841 return *value;
3842 }
3843
3844
3845 static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup,
3846 Name* name,
3847 Object* value,
3848 PropertyAttributes attributes) {
3849 JSObject* object = lookup->holder();
3850 if (object->TooManyFastProperties()) {
3851 MaybeObject* maybe_failure = object->NormalizeProperties(
3852 CLEAR_INOBJECT_PROPERTIES, 0);
3853 if (maybe_failure->IsFailure()) return maybe_failure;
3854 }
3855
3856 if (!object->HasFastProperties()) {
3857 return object->ReplaceSlowProperty(name, value, attributes);
3858 }
3859
3860 int descriptor_index = lookup->GetDescriptorIndex();
3861 if (lookup->GetAttributes() == attributes) {
3862 MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation(
3863 descriptor_index, Representation::Tagged(), FORCE_FIELD);
3864 if (maybe_failure->IsFailure()) return maybe_failure;
3865 } else {
3866 Map* map;
3867 MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations(
3868 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
3869 if (!maybe_map->To(&map)) return maybe_map;
3870 MaybeObject* maybe_failure = object->MigrateToMap(map);
3871 if (maybe_failure->IsFailure()) return maybe_failure;
3872 }
3873
3874 DescriptorArray* descriptors = object->map()->instance_descriptors();
3875 int index = descriptors->GetDetails(descriptor_index).field_index();
3876 object->FastPropertyAtPut(index, value);
3841 return value; 3877 return value;
3842 } 3878 }
3843 3879
3844 3880
3845 static Handle<Object> ConvertAndSetLocalProperty( 3881 static MaybeObject* SetPropertyToFieldWithAttributes(
3846 LookupResult* lookup,
3847 Handle<Name> name,
3848 Handle<Object> value,
3849 PropertyAttributes attributes) {
3850 Handle<JSObject> object(lookup->holder());
3851 if (object->TooManyFastProperties()) {
3852 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
3853 }
3854
3855 if (!object->HasFastProperties()) {
3856 return ReplaceSlowProperty(object, name, value, attributes);
3857 }
3858
3859 int descriptor_index = lookup->GetDescriptorIndex();
3860 if (lookup->GetAttributes() == attributes) {
3861 JSObject::GeneralizeFieldRepresentation(
3862 object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
3863 } else {
3864 Handle<Map> old_map(object->map());
3865 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
3866 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
3867 JSObject::MigrateToMap(object, new_map);
3868 }
3869
3870 DescriptorArray* descriptors = object->map()->instance_descriptors();
3871 int index = descriptors->GetDetails(descriptor_index).field_index();
3872 object->FastPropertyAtPut(index, *value);
3873 return value;
3874 }
3875
3876
3877 static Handle<Object> SetPropertyToFieldWithAttributes(
3878 LookupResult* lookup, 3882 LookupResult* lookup,
3879 Handle<Name> name, 3883 Handle<Name> name,
3880 Handle<Object> value, 3884 Handle<Object> value,
3881 PropertyAttributes attributes) { 3885 PropertyAttributes attributes) {
3882 if (lookup->GetAttributes() == attributes) { 3886 if (lookup->GetAttributes() == attributes) {
3883 if (value->IsUninitialized()) return value; 3887 if (value->IsUninitialized()) return *value;
3884 return SetPropertyToField(lookup, name, value); 3888 return SetPropertyToField(lookup, name, value);
3885 } else { 3889 } else {
3886 return ConvertAndSetLocalProperty(lookup, name, value, attributes); 3890 return ConvertAndSetLocalProperty(lookup, *name, *value, attributes);
3887 } 3891 }
3888 } 3892 }
3889 3893
3890 3894
3891 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object, 3895 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
3892 LookupResult* lookup, 3896 Name* name_raw,
3893 Handle<Name> name, 3897 Object* value_raw,
3894 Handle<Object> value, 3898 PropertyAttributes attributes,
3895 PropertyAttributes attributes, 3899 StrictModeFlag strict_mode,
3896 StrictModeFlag strict_mode, 3900 StoreFromKeyed store_mode) {
3897 StoreFromKeyed store_mode) { 3901 Heap* heap = GetHeap();
3898 Isolate* isolate = object->GetIsolate(); 3902 Isolate* isolate = heap->isolate();
3899 3903
3900 // Make sure that the top context does not change when doing callbacks or 3904 // Make sure that the top context does not change when doing callbacks or
3901 // interceptor calls. 3905 // interceptor calls.
3902 AssertNoContextChange ncc; 3906 AssertNoContextChangeWithHandleScope ncc;
3903 3907
3904 // Optimization for 2-byte strings often used as keys in a decompression 3908 // Optimization for 2-byte strings often used as keys in a decompression
3905 // dictionary. We internalize these short keys to avoid constantly 3909 // dictionary. We internalize these short keys to avoid constantly
3906 // reallocating them. 3910 // reallocating them.
3907 if (name->IsString() && !name->IsInternalizedString() && 3911 if (name_raw->IsString() && !name_raw->IsInternalizedString() &&
3908 Handle<String>::cast(name)->length() <= 2) { 3912 String::cast(name_raw)->length() <= 2) {
3909 name = isolate->factory()->InternalizeString(Handle<String>::cast(name)); 3913 Object* internalized_version;
3914 { MaybeObject* maybe_string_version =
3915 heap->InternalizeString(String::cast(name_raw));
3916 if (maybe_string_version->ToObject(&internalized_version)) {
3917 name_raw = String::cast(internalized_version);
3918 }
3919 }
3910 } 3920 }
3911 3921
3912 // Check access rights if needed. 3922 // Check access rights if needed.
3913 if (object->IsAccessCheckNeeded()) { 3923 if (IsAccessCheckNeeded()) {
3914 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 3924 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) {
3915 CALL_HEAP_FUNCTION( 3925 return SetPropertyWithFailedAccessCheck(
3916 isolate, 3926 lookup, name_raw, value_raw, true, strict_mode);
3917 object->SetPropertyWithFailedAccessCheck(
3918 lookup, *name, *value, true, strict_mode),
3919 Object);
3920 } 3927 }
3921 } 3928 }
3922 3929
3923 if (object->IsJSGlobalProxy()) { 3930 if (IsJSGlobalProxy()) {
3924 Handle<Object> proto(object->GetPrototype(), isolate); 3931 Object* proto = GetPrototype();
3925 if (proto->IsNull()) return value; 3932 if (proto->IsNull()) return value_raw;
3926 ASSERT(proto->IsJSGlobalObject()); 3933 ASSERT(proto->IsJSGlobalObject());
3927 return SetPropertyForResult(Handle<JSObject>::cast(proto), 3934 return JSObject::cast(proto)->SetPropertyForResult(
3928 lookup, name, value, attributes, strict_mode, store_mode); 3935 lookup, name_raw, value_raw, attributes, strict_mode, store_mode);
3929 } 3936 }
3930 3937
3931 ASSERT(!lookup->IsFound() || lookup->holder() == *object || 3938 ASSERT(!lookup->IsFound() || lookup->holder() == this ||
3932 lookup->holder()->map()->is_hidden_prototype()); 3939 lookup->holder()->map()->is_hidden_prototype());
3933 3940
3934 if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) { 3941 // From this point on everything needs to be handlified, because
3942 // SetPropertyViaPrototypes might call back into JavaScript.
3943 HandleScope scope(isolate);
3944 Handle<JSObject> self(this);
3945 Handle<Name> name(name_raw);
3946 Handle<Object> value(value_raw, isolate);
3947
3948 if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) {
3935 bool done = false; 3949 bool done = false;
3936 Handle<Object> result_object = SetPropertyViaPrototypes( 3950 MaybeObject* result_object = self->SetPropertyViaPrototypes(
3937 object, name, value, attributes, strict_mode, &done); 3951 *name, *value, attributes, strict_mode, &done);
3938 if (done) return result_object; 3952 if (done) return result_object;
3939 } 3953 }
3940 3954
3941 if (!lookup->IsFound()) { 3955 if (!lookup->IsFound()) {
3942 // Neither properties nor transitions found. 3956 // Neither properties nor transitions found.
3943 return AddProperty( 3957 return self->AddProperty(
3944 object, name, value, attributes, strict_mode, store_mode); 3958 *name, *value, attributes, strict_mode, store_mode);
3945 } 3959 }
3946 3960
3947 if (lookup->IsProperty() && lookup->IsReadOnly()) { 3961 if (lookup->IsProperty() && lookup->IsReadOnly()) {
3948 if (strict_mode == kStrictMode) { 3962 if (strict_mode == kStrictMode) {
3949 Handle<Object> args[] = { name, object }; 3963 Handle<Object> args[] = { name, self };
3950 Handle<Object> error = isolate->factory()->NewTypeError( 3964 return isolate->Throw(*isolate->factory()->NewTypeError(
3951 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 3965 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
3952 isolate->Throw(*error);
3953 return Handle<Object>();
3954 } else { 3966 } else {
3955 return value; 3967 return *value;
3956 } 3968 }
3957 } 3969 }
3958 3970
3959 Handle<Object> old_value = isolate->factory()->the_hole_value(); 3971 Handle<Object> old_value(heap->the_hole_value(), isolate);
3960 if (FLAG_harmony_observation && 3972 if (FLAG_harmony_observation &&
3961 object->map()->is_observed() && lookup->IsDataProperty()) { 3973 map()->is_observed() && lookup->IsDataProperty()) {
3962 old_value = Object::GetProperty(object, name); 3974 old_value = Object::GetProperty(self, name);
3963 } 3975 }
3964 3976
3965 // This is a real property that is not read-only, or it is a 3977 // This is a real property that is not read-only, or it is a
3966 // transition or null descriptor and there are no setters in the prototypes. 3978 // transition or null descriptor and there are no setters in the prototypes.
3967 Handle<Object> result = value; 3979 MaybeObject* result = *value;
3968 switch (lookup->type()) { 3980 switch (lookup->type()) {
3969 case NORMAL: 3981 case NORMAL:
3970 result = SetNormalizedProperty(handle(lookup->holder()), lookup, value); 3982 result = lookup->holder()->SetNormalizedProperty(lookup, *value);
3971 break; 3983 break;
3972 case FIELD: 3984 case FIELD:
3973 result = SetPropertyToField(lookup, name, value); 3985 result = SetPropertyToField(lookup, name, value);
3974 break; 3986 break;
3975 case CONSTANT: 3987 case CONSTANT:
3976 // Only replace the constant if necessary. 3988 // Only replace the constant if necessary.
3977 if (*value == lookup->GetConstant()) return value; 3989 if (*value == lookup->GetConstant()) return *value;
3978 result = SetPropertyToField(lookup, name, value); 3990 result = SetPropertyToField(lookup, name, value);
3979 break; 3991 break;
3980 case CALLBACKS: { 3992 case CALLBACKS: {
3981 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate); 3993 Object* callback_object = lookup->GetCallbackObject();
3982 CALL_HEAP_FUNCTION( 3994 return self->SetPropertyWithCallback(
3983 isolate, 3995 callback_object, *name, *value, lookup->holder(), strict_mode);
3984 object->SetPropertyWithCallback(*callback_object, *name, *value,
3985 lookup->holder(), strict_mode),
3986 Object);
3987 } 3996 }
3988 case INTERCEPTOR: 3997 case INTERCEPTOR:
3989 result = SetPropertyWithInterceptor(handle(lookup->holder()), name, value, 3998 result = lookup->holder()->SetPropertyWithInterceptor(
3990 attributes, strict_mode); 3999 *name, *value, attributes, strict_mode);
3991 break; 4000 break;
3992 case TRANSITION: 4001 case TRANSITION: {
3993 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup, 4002 result = SetPropertyUsingTransition(lookup, name, value, attributes);
3994 name, value, attributes);
3995 break; 4003 break;
4004 }
3996 case HANDLER: 4005 case HANDLER:
3997 case NONEXISTENT: 4006 case NONEXISTENT:
3998 UNREACHABLE(); 4007 UNREACHABLE();
3999 } 4008 }
4000 4009
4001 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); 4010 Handle<Object> hresult;
4011 if (!result->ToHandle(&hresult, isolate)) return result;
4002 4012
4003 if (FLAG_harmony_observation && object->map()->is_observed()) { 4013 if (FLAG_harmony_observation && self->map()->is_observed()) {
4004 if (lookup->IsTransition()) { 4014 if (lookup->IsTransition()) {
4005 EnqueueChangeRecord(object, "new", name, old_value); 4015 EnqueueChangeRecord(self, "new", name, old_value);
4006 } else { 4016 } else {
4007 LookupResult new_lookup(isolate); 4017 LookupResult new_lookup(isolate);
4008 object->LocalLookup(*name, &new_lookup, true); 4018 self->LocalLookup(*name, &new_lookup, true);
4009 if (new_lookup.IsDataProperty()) { 4019 if (new_lookup.IsDataProperty()) {
4010 Handle<Object> new_value = Object::GetProperty(object, name); 4020 Handle<Object> new_value = Object::GetProperty(self, name);
4011 if (!new_value->SameValue(*old_value)) { 4021 if (!new_value->SameValue(*old_value)) {
4012 EnqueueChangeRecord(object, "updated", name, old_value); 4022 EnqueueChangeRecord(self, "updated", name, old_value);
4013 } 4023 }
4014 } 4024 }
4015 } 4025 }
4016 } 4026 }
4017 4027
4018 return result; 4028 return *hresult;
4019 } 4029 }
4020 4030
4021 4031
4022 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributesTrampoline( 4032 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributesTrampoline(
4023 Name* key, 4033 Name* key,
4024 Object* value, 4034 Object* value,
4025 PropertyAttributes attributes, 4035 PropertyAttributes attributes,
4026 ValueType value_type, 4036 ValueType value_type,
4027 StoreMode mode, 4037 StoreMode mode,
4028 ExtensibilityCheck extensibility_check) { 4038 ExtensibilityCheck extensibility_check) {
(...skipping 17 matching lines...) Expand all
4046 // present, add it with attributes NONE. This code is an exact clone of 4056 // present, add it with attributes NONE. This code is an exact clone of
4047 // SetProperty, with the check for IsReadOnly and the check for a 4057 // SetProperty, with the check for IsReadOnly and the check for a
4048 // callback setter removed. The two lines looking up the LookupResult 4058 // callback setter removed. The two lines looking up the LookupResult
4049 // result are also added. If one of the functions is changed, the other 4059 // result are also added. If one of the functions is changed, the other
4050 // should be. 4060 // should be.
4051 // Note that this method cannot be used to set the prototype of a function 4061 // Note that this method cannot be used to set the prototype of a function
4052 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" 4062 // because ConvertDescriptorToField() which is called in "case CALLBACKS:"
4053 // doesn't handle function prototypes correctly. 4063 // doesn't handle function prototypes correctly.
4054 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( 4064 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
4055 Handle<JSObject> object, 4065 Handle<JSObject> object,
4056 Handle<Name> name, 4066 Handle<Name> key,
4057 Handle<Object> value, 4067 Handle<Object> value,
4058 PropertyAttributes attributes, 4068 PropertyAttributes attributes,
4059 ValueType value_type, 4069 ValueType value_type,
4060 StoreMode mode, 4070 StoreMode mode,
4061 ExtensibilityCheck extensibility_check) { 4071 ExtensibilityCheck extensibility_check) {
4062 Isolate* isolate = object->GetIsolate(); 4072 CALL_HEAP_FUNCTION(
4073 object->GetIsolate(),
4074 object->SetLocalPropertyIgnoreAttributes(
4075 *key, *value, attributes, value_type, mode, extensibility_check),
4076 Object);
4077 }
4063 4078
4079
4080 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
4081 Name* name_raw,
4082 Object* value_raw,
4083 PropertyAttributes attributes,
4084 ValueType value_type,
4085 StoreMode mode,
4086 ExtensibilityCheck extensibility_check) {
4064 // Make sure that the top context does not change when doing callbacks or 4087 // Make sure that the top context does not change when doing callbacks or
4065 // interceptor calls. 4088 // interceptor calls.
4066 AssertNoContextChange ncc; 4089 AssertNoContextChangeWithHandleScope ncc;
4067 4090 Isolate* isolate = GetIsolate();
4068 LookupResult lookup(isolate); 4091 LookupResult lookup(isolate);
4069 object->LocalLookup(*name, &lookup, true); 4092 LocalLookup(name_raw, &lookup, true);
4070 if (!lookup.IsFound()) { 4093 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup);
4071 object->map()->LookupTransition(*object, *name, &lookup);
4072 }
4073
4074 // Check access rights if needed. 4094 // Check access rights if needed.
4075 if (object->IsAccessCheckNeeded()) { 4095 if (IsAccessCheckNeeded()) {
4076 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 4096 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) {
4077 CALL_HEAP_FUNCTION( 4097 return SetPropertyWithFailedAccessCheck(&lookup,
4078 isolate, 4098 name_raw,
4079 object->SetPropertyWithFailedAccessCheck( 4099 value_raw,
4080 &lookup, *name, *value, false, kNonStrictMode), 4100 false,
4081 Object); 4101 kNonStrictMode);
4082 } 4102 }
4083 } 4103 }
4084 4104
4085 if (object->IsJSGlobalProxy()) { 4105 if (IsJSGlobalProxy()) {
4086 Handle<Object> proto(object->GetPrototype(), isolate); 4106 Object* proto = GetPrototype();
4087 if (proto->IsNull()) return value; 4107 if (proto->IsNull()) return value_raw;
4088 ASSERT(proto->IsJSGlobalObject()); 4108 ASSERT(proto->IsJSGlobalObject());
4089 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), 4109 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes(
4090 name, value, attributes, value_type, mode, extensibility_check); 4110 name_raw,
4111 value_raw,
4112 attributes,
4113 value_type,
4114 mode,
4115 extensibility_check);
4091 } 4116 }
4092 4117
4093 if (lookup.IsFound() && 4118 if (lookup.IsFound() &&
4094 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { 4119 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) {
4095 object->LocalLookupRealNamedProperty(*name, &lookup); 4120 LocalLookupRealNamedProperty(name_raw, &lookup);
4096 } 4121 }
4097 4122
4098 // Check for accessor in prototype chain removed here in clone. 4123 // Check for accessor in prototype chain removed here in clone.
4099 if (!lookup.IsFound()) { 4124 if (!lookup.IsFound()) {
4100 // Neither properties nor transitions found. 4125 // Neither properties nor transitions found.
4101 return AddProperty(object, name, value, attributes, kNonStrictMode, 4126 return AddProperty(
4127 name_raw, value_raw, attributes, kNonStrictMode,
4102 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); 4128 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
4103 } 4129 }
4104 4130
4105 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4131 // From this point on everything needs to be handlified.
4132 HandleScope scope(isolate);
4133 Handle<JSObject> self(this);
4134 Handle<Name> name(name_raw);
4135 Handle<Object> value(value_raw, isolate);
4136
4137 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate);
4106 PropertyAttributes old_attributes = ABSENT; 4138 PropertyAttributes old_attributes = ABSENT;
4107 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 4139 bool is_observed = FLAG_harmony_observation && self->map()->is_observed();
4108 if (is_observed && lookup.IsProperty()) { 4140 if (is_observed && lookup.IsProperty()) {
4109 if (lookup.IsDataProperty()) old_value = 4141 if (lookup.IsDataProperty()) old_value =
4110 Object::GetProperty(object, name); 4142 Object::GetProperty(self, name);
4111 old_attributes = lookup.GetAttributes(); 4143 old_attributes = lookup.GetAttributes();
4112 } 4144 }
4113 4145
4114 // Check of IsReadOnly removed from here in clone. 4146 // Check of IsReadOnly removed from here in clone.
4115 Handle<Object> result = value; 4147 MaybeObject* result = *value;
4116 switch (lookup.type()) { 4148 switch (lookup.type()) {
4117 case NORMAL: 4149 case NORMAL:
4118 result = ReplaceSlowProperty(object, name, value, attributes); 4150 result = self->ReplaceSlowProperty(*name, *value, attributes);
4119 break; 4151 break;
4120 case FIELD: 4152 case FIELD:
4121 result = SetPropertyToFieldWithAttributes( 4153 result = SetPropertyToFieldWithAttributes(
4122 &lookup, name, value, attributes); 4154 &lookup, name, value, attributes);
4123 break; 4155 break;
4124 case CONSTANT: 4156 case CONSTANT:
4125 // Only replace the constant if necessary. 4157 // Only replace the constant if necessary.
4126 if (lookup.GetAttributes() != attributes || 4158 if (lookup.GetAttributes() != attributes ||
4127 *value != lookup.GetConstant()) { 4159 *value != lookup.GetConstant()) {
4128 result = SetPropertyToFieldWithAttributes( 4160 result = SetPropertyToFieldWithAttributes(
4129 &lookup, name, value, attributes); 4161 &lookup, name, value, attributes);
4130 } 4162 }
4131 break; 4163 break;
4132 case CALLBACKS: 4164 case CALLBACKS:
4133 result = ConvertAndSetLocalProperty(&lookup, name, value, attributes); 4165 result = ConvertAndSetLocalProperty(&lookup, *name, *value, attributes);
4134 break; 4166 break;
4135 case TRANSITION: 4167 case TRANSITION:
4136 result = SetPropertyUsingTransition(handle(lookup.holder()), &lookup, 4168 result = SetPropertyUsingTransition(&lookup, name, value, attributes);
4137 name, value, attributes);
4138 break; 4169 break;
4139 case NONEXISTENT: 4170 case NONEXISTENT:
4140 case HANDLER: 4171 case HANDLER:
4141 case INTERCEPTOR: 4172 case INTERCEPTOR:
4142 UNREACHABLE(); 4173 UNREACHABLE();
4143 } 4174 }
4144 4175
4145 if (result.is_null()) return result; 4176 Handle<Object> hresult;
4177 if (!result->ToHandle(&hresult, isolate)) return result;
4146 4178
4147 if (is_observed) { 4179 if (is_observed) {
4148 if (lookup.IsTransition()) { 4180 if (lookup.IsTransition()) {
4149 EnqueueChangeRecord(object, "new", name, old_value); 4181 EnqueueChangeRecord(self, "new", name, old_value);
4150 } else if (old_value->IsTheHole()) { 4182 } else if (old_value->IsTheHole()) {
4151 EnqueueChangeRecord(object, "reconfigured", name, old_value); 4183 EnqueueChangeRecord(self, "reconfigured", name, old_value);
4152 } else { 4184 } else {
4153 LookupResult new_lookup(isolate); 4185 LookupResult new_lookup(isolate);
4154 object->LocalLookup(*name, &new_lookup, true); 4186 self->LocalLookup(*name, &new_lookup, true);
4155 bool value_changed = false; 4187 bool value_changed = false;
4156 if (new_lookup.IsDataProperty()) { 4188 if (new_lookup.IsDataProperty()) {
4157 Handle<Object> new_value = Object::GetProperty(object, name); 4189 Handle<Object> new_value = Object::GetProperty(self, name);
4158 value_changed = !old_value->SameValue(*new_value); 4190 value_changed = !old_value->SameValue(*new_value);
4159 } 4191 }
4160 if (new_lookup.GetAttributes() != old_attributes) { 4192 if (new_lookup.GetAttributes() != old_attributes) {
4161 if (!value_changed) old_value = isolate->factory()->the_hole_value(); 4193 if (!value_changed) old_value = isolate->factory()->the_hole_value();
4162 EnqueueChangeRecord(object, "reconfigured", name, old_value); 4194 EnqueueChangeRecord(self, "reconfigured", name, old_value);
4163 } else if (value_changed) { 4195 } else if (value_changed) {
4164 EnqueueChangeRecord(object, "updated", name, old_value); 4196 EnqueueChangeRecord(self, "updated", name, old_value);
4165 } 4197 }
4166 } 4198 }
4167 } 4199 }
4168 4200
4169 return result; 4201 return *hresult;
4170 } 4202 }
4171 4203
4172 4204
4173 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 4205 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
4174 JSObject* receiver, 4206 JSObject* receiver,
4175 Name* name, 4207 Name* name,
4176 bool continue_search) { 4208 bool continue_search) {
4177 // Check local property, ignore interceptor. 4209 // Check local property, ignore interceptor.
4178 LookupResult result(GetIsolate()); 4210 LookupResult result(GetIsolate());
4179 LocalLookupRealNamedProperty(name, &result); 4211 LocalLookupRealNamedProperty(name, &result);
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
5113 if (object->IsJSGlobalProxy()) { 5145 if (object->IsJSGlobalProxy()) {
5114 Handle<Object> proto(object->GetPrototype(), isolate); 5146 Handle<Object> proto(object->GetPrototype(), isolate);
5115 if (proto->IsNull()) return factory->false_value(); 5147 if (proto->IsNull()) return factory->false_value();
5116 ASSERT(proto->IsJSGlobalObject()); 5148 ASSERT(proto->IsJSGlobalObject());
5117 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); 5149 return DeleteElement(Handle<JSObject>::cast(proto), index, mode);
5118 } 5150 }
5119 5151
5120 Handle<Object> old_value; 5152 Handle<Object> old_value;
5121 bool should_enqueue_change_record = false; 5153 bool should_enqueue_change_record = false;
5122 if (FLAG_harmony_observation && object->map()->is_observed()) { 5154 if (FLAG_harmony_observation && object->map()->is_observed()) {
5123 should_enqueue_change_record = HasLocalElement(object, index); 5155 should_enqueue_change_record = object->HasLocalElement(index);
5124 if (should_enqueue_change_record) { 5156 if (should_enqueue_change_record) {
5125 old_value = object->GetLocalElementAccessorPair(index) != NULL 5157 old_value = object->GetLocalElementAccessorPair(index) != NULL
5126 ? Handle<Object>::cast(factory->the_hole_value()) 5158 ? Handle<Object>::cast(factory->the_hole_value())
5127 : Object::GetElement(isolate, object, index); 5159 : Object::GetElement(isolate, object, index);
5128 } 5160 }
5129 } 5161 }
5130 5162
5131 // Skip interceptor if forcing deletion. 5163 // Skip interceptor if forcing deletion.
5132 Handle<Object> result; 5164 Handle<Object> result;
5133 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { 5165 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) {
5134 result = DeleteElementWithInterceptor(object, index); 5166 result = DeleteElementWithInterceptor(object, index);
5135 } else { 5167 } else {
5136 result = AccessorDelete(object, index, mode); 5168 result = AccessorDelete(object, index, mode);
5137 } 5169 }
5138 5170
5139 if (should_enqueue_change_record && !HasLocalElement(object, index)) { 5171 if (should_enqueue_change_record && !object->HasLocalElement(index)) {
5140 Handle<String> name = factory->Uint32ToString(index); 5172 Handle<String> name = factory->Uint32ToString(index);
5141 EnqueueChangeRecord(object, "deleted", name, old_value); 5173 EnqueueChangeRecord(object, "deleted", name, old_value);
5142 } 5174 }
5143 5175
5144 return result; 5176 return result;
5145 } 5177 }
5146 5178
5147 5179
5148 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object, 5180 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
5149 Handle<Name> name, 5181 Handle<Name> name,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
5204 } else { 5236 } else {
5205 result = DeletePropertyWithInterceptor(object, name); 5237 result = DeletePropertyWithInterceptor(object, name);
5206 } 5238 }
5207 } else { 5239 } else {
5208 // Normalize object if needed. 5240 // Normalize object if needed.
5209 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 5241 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
5210 // Make sure the properties are normalized before removing the entry. 5242 // Make sure the properties are normalized before removing the entry.
5211 result = DeleteNormalizedProperty(object, name, mode); 5243 result = DeleteNormalizedProperty(object, name, mode);
5212 } 5244 }
5213 5245
5214 if (is_observed && !HasLocalProperty(object, name)) { 5246 if (is_observed && !object->HasLocalProperty(*name)) {
5215 EnqueueChangeRecord(object, "deleted", name, old_value); 5247 EnqueueChangeRecord(object, "deleted", name, old_value);
5216 } 5248 }
5217 5249
5218 return result; 5250 return result;
5219 } 5251 }
5220 5252
5221 5253
5222 Handle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, 5254 Handle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
5223 uint32_t index, 5255 uint32_t index,
5224 DeleteMode mode) { 5256 DeleteMode mode) {
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
5596 MaybeObject* maybe_copy = map()->Copy(); 5628 MaybeObject* maybe_copy = map()->Copy();
5597 if (!maybe_copy->To(&new_map)) return maybe_copy; 5629 if (!maybe_copy->To(&new_map)) return maybe_copy;
5598 new_map->set_is_observed(true); 5630 new_map->set_is_observed(true);
5599 } 5631 }
5600 set_map(new_map); 5632 set_map(new_map);
5601 5633
5602 return heap->undefined_value(); 5634 return heap->undefined_value();
5603 } 5635 }
5604 5636
5605 5637
5606 // TODO(mstarzinger): Temporary wrapper until handlified. 5638 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
5607 static Handle<Object> NewStorageFor(Isolate* isolate, 5639 StackLimitCheck check(isolate);
5608 Handle<Object> object, 5640 if (check.HasOverflowed()) return isolate->StackOverflow();
5609 Representation representation) {
5610 Heap* heap = isolate->heap();
5611 CALL_HEAP_FUNCTION(isolate,
5612 object->AllocateNewStorageFor(heap, representation),
5613 Object);
5614 }
5615 5641
5616 5642 if (map()->is_deprecated()) {
5617 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { 5643 MaybeObject* maybe_failure = MigrateInstance();
5618 Isolate* isolate = object->GetIsolate(); 5644 if (maybe_failure->IsFailure()) return maybe_failure;
5619 CALL_HEAP_FUNCTION(isolate,
5620 isolate->heap()->CopyJSObject(*object), JSObject);
5621 }
5622
5623
5624 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
5625 Isolate* isolate = object->GetIsolate();
5626 StackLimitCheck check(isolate);
5627 if (check.HasOverflowed()) {
5628 isolate->StackOverflow();
5629 return Handle<JSObject>::null();
5630 } 5645 }
5631 5646
5632 if (object->map()->is_deprecated()) { 5647 Heap* heap = isolate->heap();
5633 MigrateInstance(object); 5648 Object* result;
5649 { MaybeObject* maybe_result = heap->CopyJSObject(this);
5650 if (!maybe_result->ToObject(&result)) return maybe_result;
5634 } 5651 }
5635 5652 JSObject* copy = JSObject::cast(result);
5636 Handle<JSObject> copy = Copy(object);
5637
5638 HandleScope scope(isolate);
5639 5653
5640 // Deep copy local properties. 5654 // Deep copy local properties.
5641 if (copy->HasFastProperties()) { 5655 if (copy->HasFastProperties()) {
5642 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); 5656 DescriptorArray* descriptors = copy->map()->instance_descriptors();
5643 int limit = copy->map()->NumberOfOwnDescriptors(); 5657 int limit = copy->map()->NumberOfOwnDescriptors();
5644 for (int i = 0; i < limit; i++) { 5658 for (int i = 0; i < limit; i++) {
5645 PropertyDetails details = descriptors->GetDetails(i); 5659 PropertyDetails details = descriptors->GetDetails(i);
5646 if (details.type() != FIELD) continue; 5660 if (details.type() != FIELD) continue;
5647 int index = descriptors->GetFieldIndex(i); 5661 int index = descriptors->GetFieldIndex(i);
5648 Handle<Object> value(object->RawFastPropertyAt(index), isolate); 5662 Object* value = RawFastPropertyAt(index);
5649 if (value->IsJSObject()) { 5663 if (value->IsJSObject()) {
5650 value = DeepCopy(Handle<JSObject>::cast(value)); 5664 JSObject* js_object = JSObject::cast(value);
5651 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); 5665 MaybeObject* maybe_copy = js_object->DeepCopy(isolate);
5666 if (!maybe_copy->To(&value)) return maybe_copy;
5652 } else { 5667 } else {
5653 Representation representation = details.representation(); 5668 Representation representation = details.representation();
5654 value = NewStorageFor(isolate, value, representation); 5669 MaybeObject* maybe_storage =
5670 value->AllocateNewStorageFor(heap, representation);
5671 if (!maybe_storage->To(&value)) return maybe_storage;
5655 } 5672 }
5656 copy->FastPropertyAtPut(index, *value); 5673 copy->FastPropertyAtPut(index, value);
5657 } 5674 }
5658 } else { 5675 } else {
5659 Handle<FixedArray> names = 5676 { MaybeObject* maybe_result =
5660 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); 5677 heap->AllocateFixedArray(copy->NumberOfLocalProperties());
5661 copy->GetLocalPropertyNames(*names, 0); 5678 if (!maybe_result->ToObject(&result)) return maybe_result;
5679 }
5680 FixedArray* names = FixedArray::cast(result);
5681 copy->GetLocalPropertyNames(names, 0);
5662 for (int i = 0; i < names->length(); i++) { 5682 for (int i = 0; i < names->length(); i++) {
5663 ASSERT(names->get(i)->IsString()); 5683 ASSERT(names->get(i)->IsString());
5664 Handle<String> key_string(String::cast(names->get(i))); 5684 String* key_string = String::cast(names->get(i));
5665 PropertyAttributes attributes = 5685 PropertyAttributes attributes =
5666 copy->GetLocalPropertyAttribute(*key_string); 5686 copy->GetLocalPropertyAttribute(key_string);
5667 // Only deep copy fields from the object literal expression. 5687 // Only deep copy fields from the object literal expression.
5668 // In particular, don't try to copy the length attribute of 5688 // In particular, don't try to copy the length attribute of
5669 // an array. 5689 // an array.
5670 if (attributes != NONE) continue; 5690 if (attributes != NONE) continue;
5671 Handle<Object> value( 5691 Object* value =
5672 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), 5692 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
5673 isolate);
5674 if (value->IsJSObject()) { 5693 if (value->IsJSObject()) {
5675 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); 5694 JSObject* js_object = JSObject::cast(value);
5676 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); 5695 { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
5677 // Creating object copy for literals. No strict mode needed. 5696 if (!maybe_result->ToObject(&result)) return maybe_result;
5678 CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty( 5697 }
5679 copy, key_string, result, NONE, kNonStrictMode)); 5698 { MaybeObject* maybe_result =
5699 // Creating object copy for literals. No strict mode needed.
5700 copy->SetProperty(key_string, result, NONE, kNonStrictMode);
5701 if (!maybe_result->ToObject(&result)) return maybe_result;
5702 }
5680 } 5703 }
5681 } 5704 }
5682 } 5705 }
5683 5706
5684 // Deep copy local elements. 5707 // Deep copy local elements.
5685 // Pixel elements cannot be created using an object literal. 5708 // Pixel elements cannot be created using an object literal.
5686 ASSERT(!copy->HasExternalArrayElements()); 5709 ASSERT(!copy->HasExternalArrayElements());
5687 switch (copy->GetElementsKind()) { 5710 switch (copy->GetElementsKind()) {
5688 case FAST_SMI_ELEMENTS: 5711 case FAST_SMI_ELEMENTS:
5689 case FAST_ELEMENTS: 5712 case FAST_ELEMENTS:
5690 case FAST_HOLEY_SMI_ELEMENTS: 5713 case FAST_HOLEY_SMI_ELEMENTS:
5691 case FAST_HOLEY_ELEMENTS: { 5714 case FAST_HOLEY_ELEMENTS: {
5692 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); 5715 FixedArray* elements = FixedArray::cast(copy->elements());
5693 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { 5716 if (elements->map() == heap->fixed_cow_array_map()) {
5694 isolate->counters()->cow_arrays_created_runtime()->Increment(); 5717 isolate->counters()->cow_arrays_created_runtime()->Increment();
5695 #ifdef DEBUG 5718 #ifdef DEBUG
5696 for (int i = 0; i < elements->length(); i++) { 5719 for (int i = 0; i < elements->length(); i++) {
5697 ASSERT(!elements->get(i)->IsJSObject()); 5720 ASSERT(!elements->get(i)->IsJSObject());
5698 } 5721 }
5699 #endif 5722 #endif
5700 } else { 5723 } else {
5701 for (int i = 0; i < elements->length(); i++) { 5724 for (int i = 0; i < elements->length(); i++) {
5702 Handle<Object> value(elements->get(i), isolate); 5725 Object* value = elements->get(i);
5703 ASSERT(value->IsSmi() || 5726 ASSERT(value->IsSmi() ||
5704 value->IsTheHole() || 5727 value->IsTheHole() ||
5705 (IsFastObjectElementsKind(copy->GetElementsKind()))); 5728 (IsFastObjectElementsKind(copy->GetElementsKind())));
5706 if (value->IsJSObject()) { 5729 if (value->IsJSObject()) {
5707 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); 5730 JSObject* js_object = JSObject::cast(value);
5708 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); 5731 { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
5709 elements->set(i, *result); 5732 if (!maybe_result->ToObject(&result)) return maybe_result;
5733 }
5734 elements->set(i, result);
5710 } 5735 }
5711 } 5736 }
5712 } 5737 }
5713 break; 5738 break;
5714 } 5739 }
5715 case DICTIONARY_ELEMENTS: { 5740 case DICTIONARY_ELEMENTS: {
5716 Handle<SeededNumberDictionary> element_dictionary( 5741 SeededNumberDictionary* element_dictionary = copy->element_dictionary();
5717 copy->element_dictionary());
5718 int capacity = element_dictionary->Capacity(); 5742 int capacity = element_dictionary->Capacity();
5719 for (int i = 0; i < capacity; i++) { 5743 for (int i = 0; i < capacity; i++) {
5720 Object* k = element_dictionary->KeyAt(i); 5744 Object* k = element_dictionary->KeyAt(i);
5721 if (element_dictionary->IsKey(k)) { 5745 if (element_dictionary->IsKey(k)) {
5722 Handle<Object> value(element_dictionary->ValueAt(i), isolate); 5746 Object* value = element_dictionary->ValueAt(i);
5723 if (value->IsJSObject()) { 5747 if (value->IsJSObject()) {
5724 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); 5748 JSObject* js_object = JSObject::cast(value);
5725 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); 5749 { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
5726 element_dictionary->ValueAtPut(i, *result); 5750 if (!maybe_result->ToObject(&result)) return maybe_result;
5751 }
5752 element_dictionary->ValueAtPut(i, result);
5727 } 5753 }
5728 } 5754 }
5729 } 5755 }
5730 break; 5756 break;
5731 } 5757 }
5732 case NON_STRICT_ARGUMENTS_ELEMENTS: 5758 case NON_STRICT_ARGUMENTS_ELEMENTS:
5733 UNIMPLEMENTED(); 5759 UNIMPLEMENTED();
5734 break; 5760 break;
5735 case EXTERNAL_PIXEL_ELEMENTS: 5761 case EXTERNAL_PIXEL_ELEMENTS:
5736 case EXTERNAL_BYTE_ELEMENTS: 5762 case EXTERNAL_BYTE_ELEMENTS:
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
6157 if (!object->CanSetCallback(*name)) return; 6183 if (!object->CanSetCallback(*name)) return;
6158 6184
6159 uint32_t index = 0; 6185 uint32_t index = 0;
6160 bool is_element = name->AsArrayIndex(&index); 6186 bool is_element = name->AsArrayIndex(&index);
6161 6187
6162 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6188 Handle<Object> old_value = isolate->factory()->the_hole_value();
6163 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 6189 bool is_observed = FLAG_harmony_observation && object->map()->is_observed();
6164 bool preexists = false; 6190 bool preexists = false;
6165 if (is_observed) { 6191 if (is_observed) {
6166 if (is_element) { 6192 if (is_element) {
6167 preexists = HasLocalElement(object, index); 6193 preexists = object->HasLocalElement(index);
6168 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { 6194 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6169 old_value = Object::GetElement(isolate, object, index); 6195 old_value = Object::GetElement(isolate, object, index);
6170 } 6196 }
6171 } else { 6197 } else {
6172 LookupResult lookup(isolate); 6198 LookupResult lookup(isolate);
6173 object->LocalLookup(*name, &lookup, true); 6199 object->LocalLookup(*name, &lookup, true);
6174 preexists = lookup.IsProperty(); 6200 preexists = lookup.IsProperty();
6175 if (preexists && lookup.IsDataProperty()) { 6201 if (preexists && lookup.IsDataProperty()) {
6176 old_value = Object::GetProperty(object, name); 6202 old_value = Object::GetProperty(object, name);
6177 } 6203 }
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
6653 set_transitions(transitions); 6679 set_transitions(transitions);
6654 result->SetBackPointer(this); 6680 result->SetBackPointer(this);
6655 } else { 6681 } else {
6656 descriptors->InitializeRepresentations(Representation::Tagged()); 6682 descriptors->InitializeRepresentations(Representation::Tagged());
6657 } 6683 }
6658 6684
6659 return result; 6685 return result;
6660 } 6686 }
6661 6687
6662 6688
6663 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
6664 int new_descriptor,
6665 Handle<DescriptorArray> descriptors) {
6666 CALL_HEAP_FUNCTION(map->GetIsolate(),
6667 map->CopyInstallDescriptors(new_descriptor, *descriptors),
6668 Map);
6669 }
6670
6671
6672 // Since this method is used to rewrite an existing transition tree, it can 6689 // Since this method is used to rewrite an existing transition tree, it can
6673 // always insert transitions without checking. 6690 // always insert transitions without checking.
6674 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, 6691 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor,
6675 DescriptorArray* descriptors) { 6692 DescriptorArray* descriptors) {
6676 ASSERT(descriptors->IsSortedNoDuplicates()); 6693 ASSERT(descriptors->IsSortedNoDuplicates());
6677 6694
6678 Map* result; 6695 Map* result;
6679 MaybeObject* maybe_result = CopyDropDescriptors(); 6696 MaybeObject* maybe_result = CopyDropDescriptors();
6680 if (!maybe_result->To(&result)) return maybe_result; 6697 if (!maybe_result->To(&result)) return maybe_result;
6681 6698
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
7774 DescriptorArray* src, 7791 DescriptorArray* src,
7775 int src_index, 7792 int src_index,
7776 const WhitenessWitness& witness) { 7793 const WhitenessWitness& witness) {
7777 Object* value = src->GetValue(src_index); 7794 Object* value = src->GetValue(src_index);
7778 PropertyDetails details = src->GetDetails(src_index); 7795 PropertyDetails details = src->GetDetails(src_index);
7779 Descriptor desc(src->GetKey(src_index), value, details); 7796 Descriptor desc(src->GetKey(src_index), value, details);
7780 Set(dst_index, &desc, witness); 7797 Set(dst_index, &desc, witness);
7781 } 7798 }
7782 7799
7783 7800
7784 Handle<DescriptorArray> DescriptorArray::Merge(Handle<DescriptorArray> desc,
7785 int verbatim,
7786 int valid,
7787 int new_size,
7788 int modify_index,
7789 StoreMode store_mode,
7790 Handle<DescriptorArray> other) {
7791 CALL_HEAP_FUNCTION(desc->GetIsolate(),
7792 desc->Merge(verbatim, valid, new_size, modify_index,
7793 store_mode, *other),
7794 DescriptorArray);
7795 }
7796
7797
7798 // Generalize the |other| descriptor array by merging it into the (at least 7801 // Generalize the |other| descriptor array by merging it into the (at least
7799 // partly) updated |this| descriptor array. 7802 // partly) updated |this| descriptor array.
7800 // The method merges two descriptor array in three parts. Both descriptor arrays 7803 // The method merges two descriptor array in three parts. Both descriptor arrays
7801 // are identical up to |verbatim|. They also overlap in keys up to |valid|. 7804 // are identical up to |verbatim|. They also overlap in keys up to |valid|.
7802 // Between |verbatim| and |valid|, the resulting descriptor type as well as the 7805 // Between |verbatim| and |valid|, the resulting descriptor type as well as the
7803 // representation are generalized from both |this| and |other|. Beyond |valid|, 7806 // representation are generalized from both |this| and |other|. Beyond |valid|,
7804 // the descriptors are copied verbatim from |other| up to |new_size|. 7807 // the descriptors are copied verbatim from |other| up to |new_size|.
7805 // In case of incompatible types, the type and representation of |other| is 7808 // In case of incompatible types, the type and representation of |other| is
7806 // used. 7809 // used.
7807 MaybeObject* DescriptorArray::Merge(int verbatim, 7810 MaybeObject* DescriptorArray::Merge(int verbatim,
(...skipping 2618 matching lines...) Expand 10 before | Expand all | Expand 10 after
10426 } 10429 }
10427 10430
10428 10431
10429 bool Code::allowed_in_shared_map_code_cache() { 10432 bool Code::allowed_in_shared_map_code_cache() {
10430 return is_keyed_load_stub() || is_keyed_store_stub() || 10433 return is_keyed_load_stub() || is_keyed_store_stub() ||
10431 (is_compare_ic_stub() && 10434 (is_compare_ic_stub() &&
10432 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); 10435 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT);
10433 } 10436 }
10434 10437
10435 10438
10436 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { 10439 void Code::MakeCodeAgeSequenceYoung(byte* sequence) {
10437 PatchPlatformCodeAge(isolate, sequence, kNoAge, NO_MARKING_PARITY); 10440 PatchPlatformCodeAge(sequence, kNoAge, NO_MARKING_PARITY);
10438 } 10441 }
10439 10442
10440 10443
10441 void Code::MakeOlder(MarkingParity current_parity) { 10444 void Code::MakeOlder(MarkingParity current_parity) {
10442 byte* sequence = FindCodeAgeSequence(); 10445 byte* sequence = FindCodeAgeSequence();
10443 if (sequence != NULL) { 10446 if (sequence != NULL) {
10444 Age age; 10447 Age age;
10445 MarkingParity code_parity; 10448 MarkingParity code_parity;
10446 GetCodeAgeAndParity(sequence, &age, &code_parity); 10449 GetCodeAgeAndParity(sequence, &age, &code_parity);
10447 if (age != kLastCodeAge && code_parity != current_parity) { 10450 if (age != kLastCodeAge && code_parity != current_parity) {
10448 PatchPlatformCodeAge(GetIsolate(), 10451 PatchPlatformCodeAge(sequence, static_cast<Age>(age + 1),
10449 sequence,
10450 static_cast<Age>(age + 1),
10451 current_parity); 10452 current_parity);
10452 } 10453 }
10453 } 10454 }
10454 } 10455 }
10455 10456
10456 10457
10457 bool Code::IsOld() { 10458 bool Code::IsOld() {
10458 byte* sequence = FindCodeAgeSequence(); 10459 byte* sequence = FindCodeAgeSequence();
10459 if (sequence == NULL) return false; 10460 if (sequence == NULL) return false;
10460 Age age; 10461 Age age;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
10503 *age = k##AGE##CodeAge; \ 10504 *age = k##AGE##CodeAge; \
10504 *parity = ODD_MARKING_PARITY; \ 10505 *parity = ODD_MARKING_PARITY; \
10505 return; \ 10506 return; \
10506 } 10507 }
10507 CODE_AGE_LIST(HANDLE_CODE_AGE) 10508 CODE_AGE_LIST(HANDLE_CODE_AGE)
10508 #undef HANDLE_CODE_AGE 10509 #undef HANDLE_CODE_AGE
10509 UNREACHABLE(); 10510 UNREACHABLE();
10510 } 10511 }
10511 10512
10512 10513
10513 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) { 10514 Code* Code::GetCodeAgeStub(Age age, MarkingParity parity) {
10515 Isolate* isolate = Isolate::Current();
10514 Builtins* builtins = isolate->builtins(); 10516 Builtins* builtins = isolate->builtins();
10515 switch (age) { 10517 switch (age) {
10516 #define HANDLE_CODE_AGE(AGE) \ 10518 #define HANDLE_CODE_AGE(AGE) \
10517 case k##AGE##CodeAge: { \ 10519 case k##AGE##CodeAge: { \
10518 Code* stub = parity == EVEN_MARKING_PARITY \ 10520 Code* stub = parity == EVEN_MARKING_PARITY \
10519 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ 10521 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \
10520 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ 10522 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \
10521 return stub; \ 10523 return stub; \
10522 } 10524 }
10523 CODE_AGE_LIST(HANDLE_CODE_AGE) 10525 CODE_AGE_LIST(HANDLE_CODE_AGE)
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
10774 } 10776 }
10775 10777
10776 10778
10777 const char* Code::StubType2String(StubType type) { 10779 const char* Code::StubType2String(StubType type) {
10778 switch (type) { 10780 switch (type) {
10779 case NORMAL: return "NORMAL"; 10781 case NORMAL: return "NORMAL";
10780 case FIELD: return "FIELD"; 10782 case FIELD: return "FIELD";
10781 case CONSTANT: return "CONSTANT"; 10783 case CONSTANT: return "CONSTANT";
10782 case CALLBACKS: return "CALLBACKS"; 10784 case CALLBACKS: return "CALLBACKS";
10783 case INTERCEPTOR: return "INTERCEPTOR"; 10785 case INTERCEPTOR: return "INTERCEPTOR";
10784 case TRANSITION: return "TRANSITION"; 10786 case MAP_TRANSITION: return "MAP_TRANSITION";
10785 case NONEXISTENT: return "NONEXISTENT"; 10787 case NONEXISTENT: return "NONEXISTENT";
10786 } 10788 }
10787 UNREACHABLE(); // keep the compiler happy 10789 UNREACHABLE(); // keep the compiler happy
10788 return NULL; 10790 return NULL;
10789 } 10791 }
10790 10792
10791 10793
10792 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { 10794 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) {
10793 PrintF(out, "extra_ic_state = "); 10795 PrintF(out, "extra_ic_state = ");
10794 const char* name = NULL; 10796 const char* name = NULL;
(...skipping 3715 matching lines...) Expand 10 before | Expand all | Expand 10 after
14510 } 14512 }
14511 14513
14512 14514
14513 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { 14515 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
14514 ASSERT(!HasFastProperties()); 14516 ASSERT(!HasFastProperties());
14515 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 14517 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
14516 return PropertyCell::cast(value); 14518 return PropertyCell::cast(value);
14517 } 14519 }
14518 14520
14519 14521
14522 // TODO(mstarzinger): Temporary wrapper until handlified.
14523 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
14524 Handle<Name> name,
14525 Handle<Object> value,
14526 PropertyDetails details) {
14527 CALL_HEAP_FUNCTION(dict->GetIsolate(),
14528 dict->Add(*name, *value, details),
14529 NameDictionary);
14530 }
14531
14532
14520 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( 14533 Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
14521 Handle<GlobalObject> global, 14534 Handle<GlobalObject> global,
14522 Handle<Name> name) { 14535 Handle<Name> name) {
14523 ASSERT(!global->HasFastProperties()); 14536 ASSERT(!global->HasFastProperties());
14524 int entry = global->property_dictionary()->FindEntry(*name); 14537 int entry = global->property_dictionary()->FindEntry(*name);
14525 if (entry == NameDictionary::kNotFound) { 14538 if (entry == NameDictionary::kNotFound) {
14526 Isolate* isolate = global->GetIsolate(); 14539 Isolate* isolate = global->GetIsolate();
14527 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell( 14540 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(
14528 isolate->factory()->the_hole_value()); 14541 isolate->factory()->the_hole_value());
14529 PropertyDetails details(NONE, NORMAL, 0); 14542 PropertyDetails details(NONE, NORMAL, 0);
(...skipping 1558 matching lines...) Expand 10 before | Expand all | Expand 10 after
16088 isolate, DependentCode::kPropertyCellChangedGroup); 16101 isolate, DependentCode::kPropertyCellChangedGroup);
16089 16102
16090 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) { 16103 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) {
16091 return *new_type; 16104 return *new_type;
16092 } 16105 }
16093 16106
16094 return Type::Any(); 16107 return Type::Any();
16095 } 16108 }
16096 16109
16097 16110
16098 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
16099 Handle<Object> value,
16100 WriteBarrierMode mode) {
16101 CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(),
16102 cell->SetValueInferType(*value, mode));
16103 }
16104
16105
16106 MaybeObject* PropertyCell::SetValueInferType(Object* value, 16111 MaybeObject* PropertyCell::SetValueInferType(Object* value,
16107 WriteBarrierMode ignored) { 16112 WriteBarrierMode ignored) {
16108 set_value(value, ignored); 16113 set_value(value, ignored);
16109 if (!Type::Any()->Is(type())) { 16114 if (!Type::Any()->Is(type())) {
16110 IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate()); 16115 IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate());
16111 MaybeObject* maybe_type = trampoline.CallWithReturnValue( 16116 MaybeObject* maybe_type = trampoline.CallWithReturnValue(
16112 &PropertyCell::UpdateType, 16117 &PropertyCell::UpdateType,
16113 Handle<PropertyCell>(this), 16118 Handle<PropertyCell>(this),
16114 Handle<Object>(value, GetIsolate())); 16119 Handle<Object>(value, GetIsolate()));
16115 Type* new_type = NULL; 16120 Type* new_type = NULL;
(...skipping 28 matching lines...) Expand all
16144 #define ERROR_MESSAGES_TEXTS(C, T) T, 16149 #define ERROR_MESSAGES_TEXTS(C, T) T,
16145 static const char* error_messages_[] = { 16150 static const char* error_messages_[] = {
16146 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16151 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16147 }; 16152 };
16148 #undef ERROR_MESSAGES_TEXTS 16153 #undef ERROR_MESSAGES_TEXTS
16149 return error_messages_[reason]; 16154 return error_messages_[reason];
16150 } 16155 }
16151 16156
16152 16157
16153 } } // namespace v8::internal 16158 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698