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 1868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4079 Handle<Object> error = isolate->factory()->NewTypeError( | 4080 Handle<Object> error = isolate->factory()->NewTypeError( |
4080 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 4081 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
4081 isolate->Throw(*error); | 4082 isolate->Throw(*error); |
4082 return Handle<Object>(); | 4083 return Handle<Object>(); |
4083 } else { | 4084 } else { |
4084 return value; | 4085 return value; |
4085 } | 4086 } |
4086 } | 4087 } |
4087 | 4088 |
4088 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4089 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
4089 bool is_observed = object->map()->is_observed() && | 4090 bool is_observed = FLAG_harmony_observation && |
| 4091 object->map()->is_observed() && |
4090 *name != isolate->heap()->hidden_string(); | 4092 *name != isolate->heap()->hidden_string(); |
4091 if (is_observed && lookup->IsDataProperty()) { | 4093 if (is_observed && lookup->IsDataProperty()) { |
4092 old_value = Object::GetProperty(object, name); | 4094 old_value = Object::GetProperty(object, name); |
4093 } | 4095 } |
4094 | 4096 |
4095 // This is a real property that is not read-only, or it is a | 4097 // This is a real property that is not read-only, or it is a |
4096 // transition or null descriptor and there are no setters in the prototypes. | 4098 // transition or null descriptor and there are no setters in the prototypes. |
4097 Handle<Object> result = value; | 4099 Handle<Object> result = value; |
4098 switch (lookup->type()) { | 4100 switch (lookup->type()) { |
4099 case NORMAL: | 4101 case NORMAL: |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4201 object->map()->LookupTransition(*object, *name, &lookup); | 4203 object->map()->LookupTransition(*object, *name, &lookup); |
4202 TransitionFlag flag = lookup.IsFound() | 4204 TransitionFlag flag = lookup.IsFound() |
4203 ? OMIT_TRANSITION : INSERT_TRANSITION; | 4205 ? OMIT_TRANSITION : INSERT_TRANSITION; |
4204 // Neither properties nor transitions found. | 4206 // Neither properties nor transitions found. |
4205 return AddProperty(object, name, value, attributes, SLOPPY, | 4207 return AddProperty(object, name, value, attributes, SLOPPY, |
4206 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); | 4208 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); |
4207 } | 4209 } |
4208 | 4210 |
4209 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4211 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
4210 PropertyAttributes old_attributes = ABSENT; | 4212 PropertyAttributes old_attributes = ABSENT; |
4211 bool is_observed = object->map()->is_observed() && | 4213 bool is_observed = FLAG_harmony_observation && |
| 4214 object->map()->is_observed() && |
4212 *name != isolate->heap()->hidden_string(); | 4215 *name != isolate->heap()->hidden_string(); |
4213 if (is_observed && lookup.IsProperty()) { | 4216 if (is_observed && lookup.IsProperty()) { |
4214 if (lookup.IsDataProperty()) old_value = | 4217 if (lookup.IsDataProperty()) old_value = |
4215 Object::GetProperty(object, name); | 4218 Object::GetProperty(object, name); |
4216 old_attributes = lookup.GetAttributes(); | 4219 old_attributes = lookup.GetAttributes(); |
4217 } | 4220 } |
4218 | 4221 |
4219 // Check of IsReadOnly removed from here in clone. | 4222 // Check of IsReadOnly removed from here in clone. |
4220 switch (lookup.type()) { | 4223 switch (lookup.type()) { |
4221 case NORMAL: | 4224 case NORMAL: |
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5183 | 5186 |
5184 if (object->IsJSGlobalProxy()) { | 5187 if (object->IsJSGlobalProxy()) { |
5185 Handle<Object> proto(object->GetPrototype(), isolate); | 5188 Handle<Object> proto(object->GetPrototype(), isolate); |
5186 if (proto->IsNull()) return factory->false_value(); | 5189 if (proto->IsNull()) return factory->false_value(); |
5187 ASSERT(proto->IsJSGlobalObject()); | 5190 ASSERT(proto->IsJSGlobalObject()); |
5188 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); | 5191 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); |
5189 } | 5192 } |
5190 | 5193 |
5191 Handle<Object> old_value; | 5194 Handle<Object> old_value; |
5192 bool should_enqueue_change_record = false; | 5195 bool should_enqueue_change_record = false; |
5193 if (object->map()->is_observed()) { | 5196 if (FLAG_harmony_observation && object->map()->is_observed()) { |
5194 should_enqueue_change_record = HasLocalElement(object, index); | 5197 should_enqueue_change_record = HasLocalElement(object, index); |
5195 if (should_enqueue_change_record) { | 5198 if (should_enqueue_change_record) { |
5196 old_value = object->GetLocalElementAccessorPair(index) != NULL | 5199 old_value = object->GetLocalElementAccessorPair(index) != NULL |
5197 ? Handle<Object>::cast(factory->the_hole_value()) | 5200 ? Handle<Object>::cast(factory->the_hole_value()) |
5198 : Object::GetElement(isolate, object, index); | 5201 : Object::GetElement(isolate, object, index); |
5199 } | 5202 } |
5200 } | 5203 } |
5201 | 5204 |
5202 // Skip interceptor if forcing deletion. | 5205 // Skip interceptor if forcing deletion. |
5203 Handle<Object> result; | 5206 Handle<Object> result; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5254 Handle<Object> args[2] = { name, object }; | 5257 Handle<Object> args[2] = { name, object }; |
5255 Handle<Object> error = isolate->factory()->NewTypeError( | 5258 Handle<Object> error = isolate->factory()->NewTypeError( |
5256 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); | 5259 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); |
5257 isolate->Throw(*error); | 5260 isolate->Throw(*error); |
5258 return Handle<Object>(); | 5261 return Handle<Object>(); |
5259 } | 5262 } |
5260 return isolate->factory()->false_value(); | 5263 return isolate->factory()->false_value(); |
5261 } | 5264 } |
5262 | 5265 |
5263 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 5266 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
5264 bool is_observed = object->map()->is_observed() && | 5267 bool is_observed = FLAG_harmony_observation && |
| 5268 object->map()->is_observed() && |
5265 *name != isolate->heap()->hidden_string(); | 5269 *name != isolate->heap()->hidden_string(); |
5266 if (is_observed && lookup.IsDataProperty()) { | 5270 if (is_observed && lookup.IsDataProperty()) { |
5267 old_value = Object::GetProperty(object, name); | 5271 old_value = Object::GetProperty(object, name); |
5268 } | 5272 } |
5269 Handle<Object> result; | 5273 Handle<Object> result; |
5270 | 5274 |
5271 // Check for interceptor. | 5275 // Check for interceptor. |
5272 if (lookup.IsInterceptor()) { | 5276 if (lookup.IsInterceptor()) { |
5273 // Skip interceptor if forcing a deletion. | 5277 // Skip interceptor if forcing a deletion. |
5274 if (mode == FORCE_DELETION) { | 5278 if (mode == FORCE_DELETION) { |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5490 | 5494 |
5491 // Do a map transition, other objects with this map may still | 5495 // Do a map transition, other objects with this map may still |
5492 // be extensible. | 5496 // be extensible. |
5493 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5497 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
5494 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5498 Handle<Map> new_map = Map::Copy(handle(object->map())); |
5495 | 5499 |
5496 new_map->set_is_extensible(false); | 5500 new_map->set_is_extensible(false); |
5497 object->set_map(*new_map); | 5501 object->set_map(*new_map); |
5498 ASSERT(!object->map()->is_extensible()); | 5502 ASSERT(!object->map()->is_extensible()); |
5499 | 5503 |
5500 if (object->map()->is_observed()) { | 5504 if (FLAG_harmony_observation && object->map()->is_observed()) { |
5501 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 5505 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
5502 isolate->factory()->the_hole_value()); | 5506 isolate->factory()->the_hole_value()); |
5503 } | 5507 } |
5504 return object; | 5508 return object; |
5505 } | 5509 } |
5506 | 5510 |
5507 | 5511 |
5508 template<typename Dictionary> | 5512 template<typename Dictionary> |
5509 static void FreezeDictionary(Dictionary* dictionary) { | 5513 static void FreezeDictionary(Dictionary* dictionary) { |
5510 int capacity = dictionary->Capacity(); | 5514 int capacity = dictionary->Capacity(); |
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6348 | 6352 |
6349 // Try to flatten before operating on the string. | 6353 // Try to flatten before operating on the string. |
6350 if (name->IsString()) String::cast(*name)->TryFlatten(); | 6354 if (name->IsString()) String::cast(*name)->TryFlatten(); |
6351 | 6355 |
6352 if (!JSObject::CanSetCallback(object, name)) return; | 6356 if (!JSObject::CanSetCallback(object, name)) return; |
6353 | 6357 |
6354 uint32_t index = 0; | 6358 uint32_t index = 0; |
6355 bool is_element = name->AsArrayIndex(&index); | 6359 bool is_element = name->AsArrayIndex(&index); |
6356 | 6360 |
6357 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 6361 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
6358 bool is_observed = object->map()->is_observed() && | 6362 bool is_observed = FLAG_harmony_observation && |
| 6363 object->map()->is_observed() && |
6359 *name != isolate->heap()->hidden_string(); | 6364 *name != isolate->heap()->hidden_string(); |
6360 bool preexists = false; | 6365 bool preexists = false; |
6361 if (is_observed) { | 6366 if (is_observed) { |
6362 if (is_element) { | 6367 if (is_element) { |
6363 preexists = HasLocalElement(object, index); | 6368 preexists = HasLocalElement(object, index); |
6364 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { | 6369 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { |
6365 old_value = Object::GetElement(isolate, object, index); | 6370 old_value = Object::GetElement(isolate, object, index); |
6366 } | 6371 } |
6367 } else { | 6372 } else { |
6368 LookupResult lookup(isolate); | 6373 LookupResult lookup(isolate); |
(...skipping 5039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11408 Handle<JSFunction>(isolate->observers_end_perform_splice()), | 11413 Handle<JSFunction>(isolate->observers_end_perform_splice()), |
11409 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, | 11414 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, |
11410 &threw); | 11415 &threw); |
11411 ASSERT(!threw); | 11416 ASSERT(!threw); |
11412 } | 11417 } |
11413 | 11418 |
11414 | 11419 |
11415 MaybeObject* JSArray::SetElementsLength(Object* len) { | 11420 MaybeObject* JSArray::SetElementsLength(Object* len) { |
11416 // We should never end in here with a pixel or external array. | 11421 // We should never end in here with a pixel or external array. |
11417 ASSERT(AllowsSetElementsLength()); | 11422 ASSERT(AllowsSetElementsLength()); |
11418 if (!map()->is_observed()) | 11423 if (!(FLAG_harmony_observation && map()->is_observed())) |
11419 return GetElementsAccessor()->SetLength(this, len); | 11424 return GetElementsAccessor()->SetLength(this, len); |
11420 | 11425 |
11421 Isolate* isolate = GetIsolate(); | 11426 Isolate* isolate = GetIsolate(); |
11422 HandleScope scope(isolate); | 11427 HandleScope scope(isolate); |
11423 Handle<JSArray> self(this); | 11428 Handle<JSArray> self(this); |
11424 List<uint32_t> indices; | 11429 List<uint32_t> indices; |
11425 List<Handle<Object> > old_values; | 11430 List<Handle<Object> > old_values; |
11426 Handle<Object> old_length_handle(self->length(), isolate); | 11431 Handle<Object> old_length_handle(self->length(), isolate); |
11427 Handle<Object> new_length_handle(len, isolate); | 11432 Handle<Object> new_length_handle(len, isolate); |
11428 uint32_t old_length = 0; | 11433 uint32_t old_length = 0; |
(...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12537 return Handle<Object>(); | 12542 return Handle<Object>(); |
12538 } | 12543 } |
12539 | 12544 |
12540 // Normalize the elements to enable attributes on the property. | 12545 // Normalize the elements to enable attributes on the property. |
12541 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12546 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
12542 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 12547 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
12543 // Make sure that we never go back to fast case. | 12548 // Make sure that we never go back to fast case. |
12544 dictionary->set_requires_slow_elements(); | 12549 dictionary->set_requires_slow_elements(); |
12545 } | 12550 } |
12546 | 12551 |
12547 if (!object->map()->is_observed()) { | 12552 if (!(FLAG_harmony_observation && object->map()->is_observed())) { |
12548 return object->HasIndexedInterceptor() | 12553 return object->HasIndexedInterceptor() |
12549 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, | 12554 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, |
12550 check_prototype, | 12555 check_prototype, |
12551 set_mode) | 12556 set_mode) |
12552 : SetElementWithoutInterceptor(object, index, value, attributes, | 12557 : SetElementWithoutInterceptor(object, index, value, attributes, |
12553 strict_mode, | 12558 strict_mode, |
12554 check_prototype, | 12559 check_prototype, |
12555 set_mode); | 12560 set_mode); |
12556 } | 12561 } |
12557 | 12562 |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13138 | 13143 |
13139 bool JSObject::ShouldConvertToFastElements() { | 13144 bool JSObject::ShouldConvertToFastElements() { |
13140 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 13145 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
13141 // If the elements are sparse, we should not go back to fast case. | 13146 // If the elements are sparse, we should not go back to fast case. |
13142 if (!HasDenseElements()) return false; | 13147 if (!HasDenseElements()) return false; |
13143 // An object requiring access checks is never allowed to have fast | 13148 // An object requiring access checks is never allowed to have fast |
13144 // elements. If it had fast elements we would skip security checks. | 13149 // elements. If it had fast elements we would skip security checks. |
13145 if (IsAccessCheckNeeded()) return false; | 13150 if (IsAccessCheckNeeded()) return false; |
13146 // Observed objects may not go to fast mode because they rely on map checks, | 13151 // Observed objects may not go to fast mode because they rely on map checks, |
13147 // and for fast element accesses we sometimes check element kinds only. | 13152 // and for fast element accesses we sometimes check element kinds only. |
13148 if (map()->is_observed()) return false; | 13153 if (FLAG_harmony_observation && map()->is_observed()) return false; |
13149 | 13154 |
13150 FixedArray* elements = FixedArray::cast(this->elements()); | 13155 FixedArray* elements = FixedArray::cast(this->elements()); |
13151 SeededNumberDictionary* dictionary = NULL; | 13156 SeededNumberDictionary* dictionary = NULL; |
13152 if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) { | 13157 if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) { |
13153 dictionary = SeededNumberDictionary::cast(elements->get(1)); | 13158 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
13154 } else { | 13159 } else { |
13155 dictionary = SeededNumberDictionary::cast(elements); | 13160 dictionary = SeededNumberDictionary::cast(elements); |
13156 } | 13161 } |
13157 // If an element has been added at a very high index in the elements | 13162 // If an element has been added at a very high index in the elements |
13158 // dictionary, we cannot go back to fast case. | 13163 // dictionary, we cannot go back to fast case. |
(...skipping 3317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16476 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16481 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16477 static const char* error_messages_[] = { | 16482 static const char* error_messages_[] = { |
16478 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16483 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16479 }; | 16484 }; |
16480 #undef ERROR_MESSAGES_TEXTS | 16485 #undef ERROR_MESSAGES_TEXTS |
16481 return error_messages_[reason]; | 16486 return error_messages_[reason]; |
16482 } | 16487 } |
16483 | 16488 |
16484 | 16489 |
16485 } } // namespace v8::internal | 16490 } } // namespace v8::internal |
OLD | NEW |