| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2190 } else { | 2190 } else { |
| 2191 // Normalize the object to prevent very large instance descriptors. | 2191 // Normalize the object to prevent very large instance descriptors. |
| 2192 // This eliminates unwanted N^2 allocation and lookup behavior. | 2192 // This eliminates unwanted N^2 allocation and lookup behavior. |
| 2193 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 2193 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 2194 AddSlowProperty(object, name, value, attributes); | 2194 AddSlowProperty(object, name, value, attributes); |
| 2195 } | 2195 } |
| 2196 } else { | 2196 } else { |
| 2197 AddSlowProperty(object, name, value, attributes); | 2197 AddSlowProperty(object, name, value, attributes); |
| 2198 } | 2198 } |
| 2199 | 2199 |
| 2200 if (object->map()->is_observed() && | 2200 if (FLAG_harmony_observation && |
| 2201 object->map()->is_observed() && |
| 2201 *name != isolate->heap()->hidden_string()) { | 2202 *name != isolate->heap()->hidden_string()) { |
| 2202 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 2203 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 2203 EnqueueChangeRecord(object, "add", name, old_value); | 2204 EnqueueChangeRecord(object, "add", name, old_value); |
| 2204 } | 2205 } |
| 2205 | 2206 |
| 2206 return value; | 2207 return value; |
| 2207 } | 2208 } |
| 2208 | 2209 |
| 2209 | 2210 |
| 2210 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, | 2211 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, |
| (...skipping 1870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4081 Handle<Object> error = isolate->factory()->NewTypeError( | 4082 Handle<Object> error = isolate->factory()->NewTypeError( |
| 4082 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 4083 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
| 4083 isolate->Throw(*error); | 4084 isolate->Throw(*error); |
| 4084 return Handle<Object>(); | 4085 return Handle<Object>(); |
| 4085 } else { | 4086 } else { |
| 4086 return value; | 4087 return value; |
| 4087 } | 4088 } |
| 4088 } | 4089 } |
| 4089 | 4090 |
| 4090 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4091 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 4091 bool is_observed = object->map()->is_observed() && | 4092 bool is_observed = FLAG_harmony_observation && |
| 4093 object->map()->is_observed() && |
| 4092 *name != isolate->heap()->hidden_string(); | 4094 *name != isolate->heap()->hidden_string(); |
| 4093 if (is_observed && lookup->IsDataProperty()) { | 4095 if (is_observed && lookup->IsDataProperty()) { |
| 4094 old_value = Object::GetProperty(object, name); | 4096 old_value = Object::GetProperty(object, name); |
| 4095 } | 4097 } |
| 4096 | 4098 |
| 4097 // This is a real property that is not read-only, or it is a | 4099 // This is a real property that is not read-only, or it is a |
| 4098 // transition or null descriptor and there are no setters in the prototypes. | 4100 // transition or null descriptor and there are no setters in the prototypes. |
| 4099 Handle<Object> result = value; | 4101 Handle<Object> result = value; |
| 4100 switch (lookup->type()) { | 4102 switch (lookup->type()) { |
| 4101 case NORMAL: | 4103 case NORMAL: |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4203 object->map()->LookupTransition(*object, *name, &lookup); | 4205 object->map()->LookupTransition(*object, *name, &lookup); |
| 4204 TransitionFlag flag = lookup.IsFound() | 4206 TransitionFlag flag = lookup.IsFound() |
| 4205 ? OMIT_TRANSITION : INSERT_TRANSITION; | 4207 ? OMIT_TRANSITION : INSERT_TRANSITION; |
| 4206 // Neither properties nor transitions found. | 4208 // Neither properties nor transitions found. |
| 4207 return AddProperty(object, name, value, attributes, kNonStrictMode, | 4209 return AddProperty(object, name, value, attributes, kNonStrictMode, |
| 4208 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); | 4210 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); |
| 4209 } | 4211 } |
| 4210 | 4212 |
| 4211 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4213 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 4212 PropertyAttributes old_attributes = ABSENT; | 4214 PropertyAttributes old_attributes = ABSENT; |
| 4213 bool is_observed = object->map()->is_observed() && | 4215 bool is_observed = FLAG_harmony_observation && |
| 4216 object->map()->is_observed() && |
| 4214 *name != isolate->heap()->hidden_string(); | 4217 *name != isolate->heap()->hidden_string(); |
| 4215 if (is_observed && lookup.IsProperty()) { | 4218 if (is_observed && lookup.IsProperty()) { |
| 4216 if (lookup.IsDataProperty()) old_value = | 4219 if (lookup.IsDataProperty()) old_value = |
| 4217 Object::GetProperty(object, name); | 4220 Object::GetProperty(object, name); |
| 4218 old_attributes = lookup.GetAttributes(); | 4221 old_attributes = lookup.GetAttributes(); |
| 4219 } | 4222 } |
| 4220 | 4223 |
| 4221 // Check of IsReadOnly removed from here in clone. | 4224 // Check of IsReadOnly removed from here in clone. |
| 4222 switch (lookup.type()) { | 4225 switch (lookup.type()) { |
| 4223 case NORMAL: | 4226 case NORMAL: |
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5185 | 5188 |
| 5186 if (object->IsJSGlobalProxy()) { | 5189 if (object->IsJSGlobalProxy()) { |
| 5187 Handle<Object> proto(object->GetPrototype(), isolate); | 5190 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5188 if (proto->IsNull()) return factory->false_value(); | 5191 if (proto->IsNull()) return factory->false_value(); |
| 5189 ASSERT(proto->IsJSGlobalObject()); | 5192 ASSERT(proto->IsJSGlobalObject()); |
| 5190 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); | 5193 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); |
| 5191 } | 5194 } |
| 5192 | 5195 |
| 5193 Handle<Object> old_value; | 5196 Handle<Object> old_value; |
| 5194 bool should_enqueue_change_record = false; | 5197 bool should_enqueue_change_record = false; |
| 5195 if (object->map()->is_observed()) { | 5198 if (FLAG_harmony_observation && object->map()->is_observed()) { |
| 5196 should_enqueue_change_record = HasLocalElement(object, index); | 5199 should_enqueue_change_record = HasLocalElement(object, index); |
| 5197 if (should_enqueue_change_record) { | 5200 if (should_enqueue_change_record) { |
| 5198 old_value = object->GetLocalElementAccessorPair(index) != NULL | 5201 old_value = object->GetLocalElementAccessorPair(index) != NULL |
| 5199 ? Handle<Object>::cast(factory->the_hole_value()) | 5202 ? Handle<Object>::cast(factory->the_hole_value()) |
| 5200 : Object::GetElement(isolate, object, index); | 5203 : Object::GetElement(isolate, object, index); |
| 5201 } | 5204 } |
| 5202 } | 5205 } |
| 5203 | 5206 |
| 5204 // Skip interceptor if forcing deletion. | 5207 // Skip interceptor if forcing deletion. |
| 5205 Handle<Object> result; | 5208 Handle<Object> result; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5256 Handle<Object> args[2] = { name, object }; | 5259 Handle<Object> args[2] = { name, object }; |
| 5257 Handle<Object> error = isolate->factory()->NewTypeError( | 5260 Handle<Object> error = isolate->factory()->NewTypeError( |
| 5258 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); | 5261 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); |
| 5259 isolate->Throw(*error); | 5262 isolate->Throw(*error); |
| 5260 return Handle<Object>(); | 5263 return Handle<Object>(); |
| 5261 } | 5264 } |
| 5262 return isolate->factory()->false_value(); | 5265 return isolate->factory()->false_value(); |
| 5263 } | 5266 } |
| 5264 | 5267 |
| 5265 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 5268 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 5266 bool is_observed = object->map()->is_observed() && | 5269 bool is_observed = FLAG_harmony_observation && |
| 5270 object->map()->is_observed() && |
| 5267 *name != isolate->heap()->hidden_string(); | 5271 *name != isolate->heap()->hidden_string(); |
| 5268 if (is_observed && lookup.IsDataProperty()) { | 5272 if (is_observed && lookup.IsDataProperty()) { |
| 5269 old_value = Object::GetProperty(object, name); | 5273 old_value = Object::GetProperty(object, name); |
| 5270 } | 5274 } |
| 5271 Handle<Object> result; | 5275 Handle<Object> result; |
| 5272 | 5276 |
| 5273 // Check for interceptor. | 5277 // Check for interceptor. |
| 5274 if (lookup.IsInterceptor()) { | 5278 if (lookup.IsInterceptor()) { |
| 5275 // Skip interceptor if forcing a deletion. | 5279 // Skip interceptor if forcing a deletion. |
| 5276 if (mode == FORCE_DELETION) { | 5280 if (mode == FORCE_DELETION) { |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5492 | 5496 |
| 5493 // Do a map transition, other objects with this map may still | 5497 // Do a map transition, other objects with this map may still |
| 5494 // be extensible. | 5498 // be extensible. |
| 5495 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5499 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
| 5496 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5500 Handle<Map> new_map = Map::Copy(handle(object->map())); |
| 5497 | 5501 |
| 5498 new_map->set_is_extensible(false); | 5502 new_map->set_is_extensible(false); |
| 5499 object->set_map(*new_map); | 5503 object->set_map(*new_map); |
| 5500 ASSERT(!object->map()->is_extensible()); | 5504 ASSERT(!object->map()->is_extensible()); |
| 5501 | 5505 |
| 5502 if (object->map()->is_observed()) { | 5506 if (FLAG_harmony_observation && object->map()->is_observed()) { |
| 5503 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 5507 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
| 5504 isolate->factory()->the_hole_value()); | 5508 isolate->factory()->the_hole_value()); |
| 5505 } | 5509 } |
| 5506 return object; | 5510 return object; |
| 5507 } | 5511 } |
| 5508 | 5512 |
| 5509 | 5513 |
| 5510 template<typename Dictionary> | 5514 template<typename Dictionary> |
| 5511 static void FreezeDictionary(Dictionary* dictionary) { | 5515 static void FreezeDictionary(Dictionary* dictionary) { |
| 5512 int capacity = dictionary->Capacity(); | 5516 int capacity = dictionary->Capacity(); |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6350 | 6354 |
| 6351 // Try to flatten before operating on the string. | 6355 // Try to flatten before operating on the string. |
| 6352 if (name->IsString()) String::cast(*name)->TryFlatten(); | 6356 if (name->IsString()) String::cast(*name)->TryFlatten(); |
| 6353 | 6357 |
| 6354 if (!JSObject::CanSetCallback(object, name)) return; | 6358 if (!JSObject::CanSetCallback(object, name)) return; |
| 6355 | 6359 |
| 6356 uint32_t index = 0; | 6360 uint32_t index = 0; |
| 6357 bool is_element = name->AsArrayIndex(&index); | 6361 bool is_element = name->AsArrayIndex(&index); |
| 6358 | 6362 |
| 6359 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 6363 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 6360 bool is_observed = object->map()->is_observed() && | 6364 bool is_observed = FLAG_harmony_observation && |
| 6365 object->map()->is_observed() && |
| 6361 *name != isolate->heap()->hidden_string(); | 6366 *name != isolate->heap()->hidden_string(); |
| 6362 bool preexists = false; | 6367 bool preexists = false; |
| 6363 if (is_observed) { | 6368 if (is_observed) { |
| 6364 if (is_element) { | 6369 if (is_element) { |
| 6365 preexists = HasLocalElement(object, index); | 6370 preexists = HasLocalElement(object, index); |
| 6366 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { | 6371 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { |
| 6367 old_value = Object::GetElement(isolate, object, index); | 6372 old_value = Object::GetElement(isolate, object, index); |
| 6368 } | 6373 } |
| 6369 } else { | 6374 } else { |
| 6370 LookupResult lookup(isolate); | 6375 LookupResult lookup(isolate); |
| (...skipping 5041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11412 Handle<JSFunction>(isolate->observers_end_perform_splice()), | 11417 Handle<JSFunction>(isolate->observers_end_perform_splice()), |
| 11413 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, | 11418 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, |
| 11414 &threw); | 11419 &threw); |
| 11415 ASSERT(!threw); | 11420 ASSERT(!threw); |
| 11416 } | 11421 } |
| 11417 | 11422 |
| 11418 | 11423 |
| 11419 MaybeObject* JSArray::SetElementsLength(Object* len) { | 11424 MaybeObject* JSArray::SetElementsLength(Object* len) { |
| 11420 // We should never end in here with a pixel or external array. | 11425 // We should never end in here with a pixel or external array. |
| 11421 ASSERT(AllowsSetElementsLength()); | 11426 ASSERT(AllowsSetElementsLength()); |
| 11422 if (!map()->is_observed()) | 11427 if (!(FLAG_harmony_observation && map()->is_observed())) |
| 11423 return GetElementsAccessor()->SetLength(this, len); | 11428 return GetElementsAccessor()->SetLength(this, len); |
| 11424 | 11429 |
| 11425 Isolate* isolate = GetIsolate(); | 11430 Isolate* isolate = GetIsolate(); |
| 11426 HandleScope scope(isolate); | 11431 HandleScope scope(isolate); |
| 11427 Handle<JSArray> self(this); | 11432 Handle<JSArray> self(this); |
| 11428 List<uint32_t> indices; | 11433 List<uint32_t> indices; |
| 11429 List<Handle<Object> > old_values; | 11434 List<Handle<Object> > old_values; |
| 11430 Handle<Object> old_length_handle(self->length(), isolate); | 11435 Handle<Object> old_length_handle(self->length(), isolate); |
| 11431 Handle<Object> new_length_handle(len, isolate); | 11436 Handle<Object> new_length_handle(len, isolate); |
| 11432 uint32_t old_length = 0; | 11437 uint32_t old_length = 0; |
| (...skipping 1110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12543 return Handle<Object>(); | 12548 return Handle<Object>(); |
| 12544 } | 12549 } |
| 12545 | 12550 |
| 12546 // Normalize the elements to enable attributes on the property. | 12551 // Normalize the elements to enable attributes on the property. |
| 12547 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12552 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
| 12548 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 12553 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
| 12549 // Make sure that we never go back to fast case. | 12554 // Make sure that we never go back to fast case. |
| 12550 dictionary->set_requires_slow_elements(); | 12555 dictionary->set_requires_slow_elements(); |
| 12551 } | 12556 } |
| 12552 | 12557 |
| 12553 if (!object->map()->is_observed()) { | 12558 if (!(FLAG_harmony_observation && object->map()->is_observed())) { |
| 12554 return object->HasIndexedInterceptor() | 12559 return object->HasIndexedInterceptor() |
| 12555 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, | 12560 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, |
| 12556 check_prototype, | 12561 check_prototype, |
| 12557 set_mode) | 12562 set_mode) |
| 12558 : SetElementWithoutInterceptor(object, index, value, attributes, | 12563 : SetElementWithoutInterceptor(object, index, value, attributes, |
| 12559 strict_mode, | 12564 strict_mode, |
| 12560 check_prototype, | 12565 check_prototype, |
| 12561 set_mode); | 12566 set_mode); |
| 12562 } | 12567 } |
| 12563 | 12568 |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13144 | 13149 |
| 13145 bool JSObject::ShouldConvertToFastElements() { | 13150 bool JSObject::ShouldConvertToFastElements() { |
| 13146 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 13151 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 13147 // If the elements are sparse, we should not go back to fast case. | 13152 // If the elements are sparse, we should not go back to fast case. |
| 13148 if (!HasDenseElements()) return false; | 13153 if (!HasDenseElements()) return false; |
| 13149 // An object requiring access checks is never allowed to have fast | 13154 // An object requiring access checks is never allowed to have fast |
| 13150 // elements. If it had fast elements we would skip security checks. | 13155 // elements. If it had fast elements we would skip security checks. |
| 13151 if (IsAccessCheckNeeded()) return false; | 13156 if (IsAccessCheckNeeded()) return false; |
| 13152 // Observed objects may not go to fast mode because they rely on map checks, | 13157 // Observed objects may not go to fast mode because they rely on map checks, |
| 13153 // and for fast element accesses we sometimes check element kinds only. | 13158 // and for fast element accesses we sometimes check element kinds only. |
| 13154 if (map()->is_observed()) return false; | 13159 if (FLAG_harmony_observation && map()->is_observed()) return false; |
| 13155 | 13160 |
| 13156 FixedArray* elements = FixedArray::cast(this->elements()); | 13161 FixedArray* elements = FixedArray::cast(this->elements()); |
| 13157 SeededNumberDictionary* dictionary = NULL; | 13162 SeededNumberDictionary* dictionary = NULL; |
| 13158 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { | 13163 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { |
| 13159 dictionary = SeededNumberDictionary::cast(elements->get(1)); | 13164 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
| 13160 } else { | 13165 } else { |
| 13161 dictionary = SeededNumberDictionary::cast(elements); | 13166 dictionary = SeededNumberDictionary::cast(elements); |
| 13162 } | 13167 } |
| 13163 // If an element has been added at a very high index in the elements | 13168 // If an element has been added at a very high index in the elements |
| 13164 // dictionary, we cannot go back to fast case. | 13169 // dictionary, we cannot go back to fast case. |
| (...skipping 3333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16498 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16503 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16499 static const char* error_messages_[] = { | 16504 static const char* error_messages_[] = { |
| 16500 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16505 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16501 }; | 16506 }; |
| 16502 #undef ERROR_MESSAGES_TEXTS | 16507 #undef ERROR_MESSAGES_TEXTS |
| 16503 return error_messages_[reason]; | 16508 return error_messages_[reason]; |
| 16504 } | 16509 } |
| 16505 | 16510 |
| 16506 | 16511 |
| 16507 } } // namespace v8::internal | 16512 } } // namespace v8::internal |
| OLD | NEW |