| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2121 if (!maybe->To<String>(&name)) { | 2121 if (!maybe->To<String>(&name)) { |
| 2122 *found = true; // Force abort | 2122 *found = true; // Force abort |
| 2123 return maybe; | 2123 return maybe; |
| 2124 } | 2124 } |
| 2125 return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter( | 2125 return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter( |
| 2126 name, value, NONE, strict_mode, found); | 2126 name, value, NONE, strict_mode, found); |
| 2127 } | 2127 } |
| 2128 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 2128 if (!JSObject::cast(pt)->HasDictionaryElements()) { |
| 2129 continue; | 2129 continue; |
| 2130 } | 2130 } |
| 2131 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); | 2131 SeededNumberDictionary* dictionary = |
| 2132 JSObject::cast(pt)->element_dictionary(); |
| 2132 int entry = dictionary->FindEntry(index); | 2133 int entry = dictionary->FindEntry(index); |
| 2133 if (entry != NumberDictionary::kNotFound) { | 2134 if (entry != SeededNumberDictionary::kNotFound) { |
| 2134 PropertyDetails details = dictionary->DetailsAt(entry); | 2135 PropertyDetails details = dictionary->DetailsAt(entry); |
| 2135 if (details.type() == CALLBACKS) { | 2136 if (details.type() == CALLBACKS) { |
| 2136 *found = true; | 2137 *found = true; |
| 2137 return SetElementWithCallback(dictionary->ValueAt(entry), | 2138 return SetElementWithCallback(dictionary->ValueAt(entry), |
| 2138 index, | 2139 index, |
| 2139 value, | 2140 value, |
| 2140 JSObject::cast(pt), | 2141 JSObject::cast(pt), |
| 2141 strict_mode); | 2142 strict_mode); |
| 2142 } | 2143 } |
| 2143 } | 2144 } |
| (...skipping 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3489 | 3490 |
| 3490 | 3491 |
| 3491 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { | 3492 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { |
| 3492 if (HasFastProperties()) return this; | 3493 if (HasFastProperties()) return this; |
| 3493 ASSERT(!IsGlobalObject()); | 3494 ASSERT(!IsGlobalObject()); |
| 3494 return property_dictionary()-> | 3495 return property_dictionary()-> |
| 3495 TransformPropertiesToFastFor(this, unused_property_fields); | 3496 TransformPropertiesToFastFor(this, unused_property_fields); |
| 3496 } | 3497 } |
| 3497 | 3498 |
| 3498 | 3499 |
| 3499 Handle<NumberDictionary> JSObject::NormalizeElements(Handle<JSObject> object) { | 3500 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
| 3500 CALL_HEAP_FUNCTION( | 3501 Handle<JSObject> object) { |
| 3501 object->GetIsolate(), object->NormalizeElements(), NumberDictionary); | 3502 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 3503 object->NormalizeElements(), |
| 3504 SeededNumberDictionary); |
| 3502 } | 3505 } |
| 3503 | 3506 |
| 3504 | 3507 |
| 3505 MaybeObject* JSObject::NormalizeElements() { | 3508 MaybeObject* JSObject::NormalizeElements() { |
| 3506 ASSERT(!HasExternalArrayElements()); | 3509 ASSERT(!HasExternalArrayElements()); |
| 3507 | 3510 |
| 3508 // Find the backing store. | 3511 // Find the backing store. |
| 3509 FixedArrayBase* array = FixedArrayBase::cast(elements()); | 3512 FixedArrayBase* array = FixedArrayBase::cast(elements()); |
| 3510 Map* old_map = array->map(); | 3513 Map* old_map = array->map(); |
| 3511 bool is_arguments = | 3514 bool is_arguments = |
| 3512 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); | 3515 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); |
| 3513 if (is_arguments) { | 3516 if (is_arguments) { |
| 3514 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); | 3517 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); |
| 3515 } | 3518 } |
| 3516 if (array->IsDictionary()) return array; | 3519 if (array->IsDictionary()) return array; |
| 3517 | 3520 |
| 3518 ASSERT(HasFastElements() || | 3521 ASSERT(HasFastElements() || |
| 3519 HasFastSmiOnlyElements() || | 3522 HasFastSmiOnlyElements() || |
| 3520 HasFastDoubleElements() || | 3523 HasFastDoubleElements() || |
| 3521 HasFastArgumentsElements()); | 3524 HasFastArgumentsElements()); |
| 3522 // Compute the effective length and allocate a new backing store. | 3525 // Compute the effective length and allocate a new backing store. |
| 3523 int length = IsJSArray() | 3526 int length = IsJSArray() |
| 3524 ? Smi::cast(JSArray::cast(this)->length())->value() | 3527 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 3525 : array->length(); | 3528 : array->length(); |
| 3526 int old_capacity = 0; | 3529 int old_capacity = 0; |
| 3527 int used_elements = 0; | 3530 int used_elements = 0; |
| 3528 GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 3531 GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
| 3529 NumberDictionary* dictionary = NULL; | 3532 SeededNumberDictionary* dictionary = NULL; |
| 3530 { Object* object; | 3533 { Object* object; |
| 3531 MaybeObject* maybe = NumberDictionary::Allocate(used_elements); | 3534 MaybeObject* maybe = SeededNumberDictionary::Allocate(used_elements); |
| 3532 if (!maybe->ToObject(&object)) return maybe; | 3535 if (!maybe->ToObject(&object)) return maybe; |
| 3533 dictionary = NumberDictionary::cast(object); | 3536 dictionary = SeededNumberDictionary::cast(object); |
| 3534 } | 3537 } |
| 3535 | 3538 |
| 3536 // Copy the elements to the new backing store. | 3539 // Copy the elements to the new backing store. |
| 3537 bool has_double_elements = array->IsFixedDoubleArray(); | 3540 bool has_double_elements = array->IsFixedDoubleArray(); |
| 3538 for (int i = 0; i < length; i++) { | 3541 for (int i = 0; i < length; i++) { |
| 3539 Object* value = NULL; | 3542 Object* value = NULL; |
| 3540 if (has_double_elements) { | 3543 if (has_double_elements) { |
| 3541 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); | 3544 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); |
| 3542 if (double_array->is_the_hole(i)) { | 3545 if (double_array->is_the_hole(i)) { |
| 3543 value = GetIsolate()->heap()->the_hole_value(); | 3546 value = GetIsolate()->heap()->the_hole_value(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3554 ASSERT(old_map->has_fast_elements() || | 3557 ASSERT(old_map->has_fast_elements() || |
| 3555 old_map->has_fast_smi_only_elements()); | 3558 old_map->has_fast_smi_only_elements()); |
| 3556 value = FixedArray::cast(array)->get(i); | 3559 value = FixedArray::cast(array)->get(i); |
| 3557 } | 3560 } |
| 3558 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 3561 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
| 3559 if (!value->IsTheHole()) { | 3562 if (!value->IsTheHole()) { |
| 3560 Object* result; | 3563 Object* result; |
| 3561 MaybeObject* maybe_result = | 3564 MaybeObject* maybe_result = |
| 3562 dictionary->AddNumberEntry(i, value, details); | 3565 dictionary->AddNumberEntry(i, value, details); |
| 3563 if (!maybe_result->ToObject(&result)) return maybe_result; | 3566 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3564 dictionary = NumberDictionary::cast(result); | 3567 dictionary = SeededNumberDictionary::cast(result); |
| 3565 } | 3568 } |
| 3566 } | 3569 } |
| 3567 | 3570 |
| 3568 // Switch to using the dictionary as the backing storage for elements. | 3571 // Switch to using the dictionary as the backing storage for elements. |
| 3569 if (is_arguments) { | 3572 if (is_arguments) { |
| 3570 FixedArray::cast(elements())->set(1, dictionary); | 3573 FixedArray::cast(elements())->set(1, dictionary); |
| 3571 } else { | 3574 } else { |
| 3572 // Set the new map first to satify the elements type assert in | 3575 // Set the new map first to satify the elements type assert in |
| 3573 // set_elements(). | 3576 // set_elements(). |
| 3574 Object* new_map; | 3577 Object* new_map; |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4038 kind == DICTIONARY_ELEMENTS); | 4041 kind == DICTIONARY_ELEMENTS); |
| 4039 if (kind == FAST_ELEMENTS) { | 4042 if (kind == FAST_ELEMENTS) { |
| 4040 int length = IsJSArray() | 4043 int length = IsJSArray() |
| 4041 ? Smi::cast(JSArray::cast(this)->length())->value() | 4044 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 4042 : elements->length(); | 4045 : elements->length(); |
| 4043 for (int i = 0; i < length; ++i) { | 4046 for (int i = 0; i < length; ++i) { |
| 4044 Object* element = elements->get(i); | 4047 Object* element = elements->get(i); |
| 4045 if (!element->IsTheHole() && element == object) return true; | 4048 if (!element->IsTheHole() && element == object) return true; |
| 4046 } | 4049 } |
| 4047 } else { | 4050 } else { |
| 4048 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); | 4051 Object* key = |
| 4052 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object); |
| 4049 if (!key->IsUndefined()) return true; | 4053 if (!key->IsUndefined()) return true; |
| 4050 } | 4054 } |
| 4051 return false; | 4055 return false; |
| 4052 } | 4056 } |
| 4053 | 4057 |
| 4054 | 4058 |
| 4055 // Check whether this object references another object. | 4059 // Check whether this object references another object. |
| 4056 bool JSObject::ReferencesObject(Object* obj) { | 4060 bool JSObject::ReferencesObject(Object* obj) { |
| 4057 Map* map_of_this = map(); | 4061 Map* map_of_this = map(); |
| 4058 Heap* heap = GetHeap(); | 4062 Heap* heap = GetHeap(); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4184 HandleScope scope(isolate); | 4188 HandleScope scope(isolate); |
| 4185 Handle<Object> object(this); | 4189 Handle<Object> object(this); |
| 4186 Handle<Object> error = | 4190 Handle<Object> error = |
| 4187 isolate->factory()->NewTypeError( | 4191 isolate->factory()->NewTypeError( |
| 4188 "cant_prevent_ext_external_array_elements", | 4192 "cant_prevent_ext_external_array_elements", |
| 4189 HandleVector(&object, 1)); | 4193 HandleVector(&object, 1)); |
| 4190 return isolate->Throw(*error); | 4194 return isolate->Throw(*error); |
| 4191 } | 4195 } |
| 4192 | 4196 |
| 4193 // If there are fast elements we normalize. | 4197 // If there are fast elements we normalize. |
| 4194 NumberDictionary* dictionary = NULL; | 4198 SeededNumberDictionary* dictionary = NULL; |
| 4195 { MaybeObject* maybe = NormalizeElements(); | 4199 { MaybeObject* maybe = NormalizeElements(); |
| 4196 if (!maybe->To<NumberDictionary>(&dictionary)) return maybe; | 4200 if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe; |
| 4197 } | 4201 } |
| 4198 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 4202 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 4199 // Make sure that we never go back to fast case. | 4203 // Make sure that we never go back to fast case. |
| 4200 dictionary->set_requires_slow_elements(); | 4204 dictionary->set_requires_slow_elements(); |
| 4201 | 4205 |
| 4202 // Do a map transition, other objects with this map may still | 4206 // Do a map transition, other objects with this map may still |
| 4203 // be extensible. | 4207 // be extensible. |
| 4204 Map* new_map; | 4208 Map* new_map; |
| 4205 { MaybeObject* maybe = map()->CopyDropTransitions(); | 4209 { MaybeObject* maybe = map()->CopyDropTransitions(); |
| 4206 if (!maybe->To<Map>(&new_map)) return maybe; | 4210 if (!maybe->To<Map>(&new_map)) return maybe; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4349 if (result->IsProperty() && result->type() == CALLBACKS) return; | 4353 if (result->IsProperty() && result->type() == CALLBACKS) return; |
| 4350 } | 4354 } |
| 4351 result->NotFound(); | 4355 result->NotFound(); |
| 4352 } | 4356 } |
| 4353 | 4357 |
| 4354 | 4358 |
| 4355 // Search for a getter or setter in an elements dictionary and update its | 4359 // Search for a getter or setter in an elements dictionary and update its |
| 4356 // attributes. Returns either undefined if the element is non-deletable, or the | 4360 // attributes. Returns either undefined if the element is non-deletable, or the |
| 4357 // getter/setter pair if there is an existing one, or the hole value if the | 4361 // getter/setter pair if there is an existing one, or the hole value if the |
| 4358 // element does not exist or is a normal non-getter/setter data element. | 4362 // element does not exist or is a normal non-getter/setter data element. |
| 4359 static Object* UpdateGetterSetterInDictionary(NumberDictionary* dictionary, | 4363 static Object* UpdateGetterSetterInDictionary( |
| 4360 uint32_t index, | 4364 SeededNumberDictionary* dictionary, |
| 4361 PropertyAttributes attributes, | 4365 uint32_t index, |
| 4362 Heap* heap) { | 4366 PropertyAttributes attributes, |
| 4367 Heap* heap) { |
| 4363 int entry = dictionary->FindEntry(index); | 4368 int entry = dictionary->FindEntry(index); |
| 4364 if (entry != NumberDictionary::kNotFound) { | 4369 if (entry != SeededNumberDictionary::kNotFound) { |
| 4365 Object* result = dictionary->ValueAt(entry); | 4370 Object* result = dictionary->ValueAt(entry); |
| 4366 PropertyDetails details = dictionary->DetailsAt(entry); | 4371 PropertyDetails details = dictionary->DetailsAt(entry); |
| 4367 // TODO(mstarzinger): We should check for details.IsDontDelete() here once | 4372 // TODO(mstarzinger): We should check for details.IsDontDelete() here once |
| 4368 // we only call into the runtime once to set both getter and setter. | 4373 // we only call into the runtime once to set both getter and setter. |
| 4369 if (details.type() == CALLBACKS && result->IsAccessorPair()) { | 4374 if (details.type() == CALLBACKS && result->IsAccessorPair()) { |
| 4370 if (details.attributes() != attributes) { | 4375 if (details.attributes() != attributes) { |
| 4371 dictionary->DetailsAtPut(entry, | 4376 dictionary->DetailsAtPut(entry, |
| 4372 PropertyDetails(attributes, CALLBACKS, index)); | 4377 PropertyDetails(attributes, CALLBACKS, index)); |
| 4373 } | 4378 } |
| 4374 return result; | 4379 return result; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4426 // Ascertain whether we have read-only properties or an existing | 4431 // Ascertain whether we have read-only properties or an existing |
| 4427 // getter/setter pair in an arguments elements dictionary backing | 4432 // getter/setter pair in an arguments elements dictionary backing |
| 4428 // store. | 4433 // store. |
| 4429 FixedArray* parameter_map = FixedArray::cast(elements()); | 4434 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 4430 uint32_t length = parameter_map->length(); | 4435 uint32_t length = parameter_map->length(); |
| 4431 Object* probe = | 4436 Object* probe = |
| 4432 index < (length - 2) ? parameter_map->get(index + 2) : NULL; | 4437 index < (length - 2) ? parameter_map->get(index + 2) : NULL; |
| 4433 if (probe == NULL || probe->IsTheHole()) { | 4438 if (probe == NULL || probe->IsTheHole()) { |
| 4434 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 4439 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 4435 if (arguments->IsDictionary()) { | 4440 if (arguments->IsDictionary()) { |
| 4436 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | 4441 SeededNumberDictionary* dictionary = |
| 4442 SeededNumberDictionary::cast(arguments); |
| 4437 probe = UpdateGetterSetterInDictionary(dictionary, | 4443 probe = UpdateGetterSetterInDictionary(dictionary, |
| 4438 index, | 4444 index, |
| 4439 attributes, | 4445 attributes, |
| 4440 heap); | 4446 heap); |
| 4441 if (!probe->IsTheHole()) return probe; | 4447 if (!probe->IsTheHole()) return probe; |
| 4442 } | 4448 } |
| 4443 } | 4449 } |
| 4444 break; | 4450 break; |
| 4445 } | 4451 } |
| 4446 } | 4452 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4498 return true; | 4504 return true; |
| 4499 } | 4505 } |
| 4500 | 4506 |
| 4501 | 4507 |
| 4502 MaybeObject* JSObject::SetElementCallback(uint32_t index, | 4508 MaybeObject* JSObject::SetElementCallback(uint32_t index, |
| 4503 Object* structure, | 4509 Object* structure, |
| 4504 PropertyAttributes attributes) { | 4510 PropertyAttributes attributes) { |
| 4505 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 4511 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
| 4506 | 4512 |
| 4507 // Normalize elements to make this operation simple. | 4513 // Normalize elements to make this operation simple. |
| 4508 NumberDictionary* dictionary = NULL; | 4514 SeededNumberDictionary* dictionary = NULL; |
| 4509 { Object* result; | 4515 { Object* result; |
| 4510 MaybeObject* maybe = NormalizeElements(); | 4516 MaybeObject* maybe = NormalizeElements(); |
| 4511 if (!maybe->ToObject(&result)) return maybe; | 4517 if (!maybe->ToObject(&result)) return maybe; |
| 4512 dictionary = NumberDictionary::cast(result); | 4518 dictionary = SeededNumberDictionary::cast(result); |
| 4513 } | 4519 } |
| 4514 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 4520 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 4515 | 4521 |
| 4516 // Update the dictionary with the new CALLBACKS property. | 4522 // Update the dictionary with the new CALLBACKS property. |
| 4517 { Object* result; | 4523 { Object* result; |
| 4518 MaybeObject* maybe = dictionary->Set(index, structure, details); | 4524 MaybeObject* maybe = dictionary->Set(index, structure, details); |
| 4519 if (!maybe->ToObject(&result)) return maybe; | 4525 if (!maybe->ToObject(&result)) return maybe; |
| 4520 dictionary = NumberDictionary::cast(result); | 4526 dictionary = SeededNumberDictionary::cast(result); |
| 4521 } | 4527 } |
| 4522 | 4528 |
| 4523 dictionary->set_requires_slow_elements(); | 4529 dictionary->set_requires_slow_elements(); |
| 4524 // Update the dictionary backing store on the object. | 4530 // Update the dictionary backing store on the object. |
| 4525 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { | 4531 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { |
| 4526 // Also delete any parameter alias. | 4532 // Also delete any parameter alias. |
| 4527 // | 4533 // |
| 4528 // TODO(kmillikin): when deleting the last parameter alias we could | 4534 // TODO(kmillikin): when deleting the last parameter alias we could |
| 4529 // switch to a direct backing store without the parameter map. This | 4535 // switch to a direct backing store without the parameter map. This |
| 4530 // would allow GC of the context. | 4536 // would allow GC of the context. |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4719 } | 4725 } |
| 4720 | 4726 |
| 4721 // Make the lookup and include prototypes. | 4727 // Make the lookup and include prototypes. |
| 4722 uint32_t index = 0; | 4728 uint32_t index = 0; |
| 4723 if (name->AsArrayIndex(&index)) { | 4729 if (name->AsArrayIndex(&index)) { |
| 4724 for (Object* obj = this; | 4730 for (Object* obj = this; |
| 4725 obj != heap->null_value(); | 4731 obj != heap->null_value(); |
| 4726 obj = JSObject::cast(obj)->GetPrototype()) { | 4732 obj = JSObject::cast(obj)->GetPrototype()) { |
| 4727 JSObject* js_object = JSObject::cast(obj); | 4733 JSObject* js_object = JSObject::cast(obj); |
| 4728 if (js_object->HasDictionaryElements()) { | 4734 if (js_object->HasDictionaryElements()) { |
| 4729 NumberDictionary* dictionary = js_object->element_dictionary(); | 4735 SeededNumberDictionary* dictionary = js_object->element_dictionary(); |
| 4730 int entry = dictionary->FindEntry(index); | 4736 int entry = dictionary->FindEntry(index); |
| 4731 if (entry != NumberDictionary::kNotFound) { | 4737 if (entry != SeededNumberDictionary::kNotFound) { |
| 4732 Object* element = dictionary->ValueAt(entry); | 4738 Object* element = dictionary->ValueAt(entry); |
| 4733 PropertyDetails details = dictionary->DetailsAt(entry); | 4739 PropertyDetails details = dictionary->DetailsAt(entry); |
| 4734 if (details.type() == CALLBACKS) { | 4740 if (details.type() == CALLBACKS) { |
| 4735 if (element->IsAccessorPair()) { | 4741 if (element->IsAccessorPair()) { |
| 4736 AccessorPair* accessors = AccessorPair::cast(element); | 4742 AccessorPair* accessors = AccessorPair::cast(element); |
| 4737 return is_getter ? accessors->getter() : accessors->setter(); | 4743 return is_getter ? accessors->getter() : accessors->setter(); |
| 4738 } | 4744 } |
| 4739 } | 4745 } |
| 4740 } | 4746 } |
| 4741 } | 4747 } |
| (...skipping 3517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8259 reinterpret_cast<void*>(from), | 8265 reinterpret_cast<void*>(from), |
| 8260 kPointerSize * copy_size); | 8266 kPointerSize * copy_size); |
| 8261 } else { | 8267 } else { |
| 8262 for (int i = 0; i < copy_size; ++i) { | 8268 for (int i = 0; i < copy_size; ++i) { |
| 8263 destination->set(i, source->get(i), mode); | 8269 destination->set(i, source->get(i), mode); |
| 8264 } | 8270 } |
| 8265 } | 8271 } |
| 8266 } | 8272 } |
| 8267 | 8273 |
| 8268 | 8274 |
| 8269 static void CopySlowElementsToFast(NumberDictionary* source, | 8275 static void CopySlowElementsToFast(SeededNumberDictionary* source, |
| 8270 FixedArray* destination, | 8276 FixedArray* destination, |
| 8271 WriteBarrierMode mode) { | 8277 WriteBarrierMode mode) { |
| 8272 int destination_length = destination->length(); | 8278 int destination_length = destination->length(); |
| 8273 for (int i = 0; i < source->Capacity(); ++i) { | 8279 for (int i = 0; i < source->Capacity(); ++i) { |
| 8274 Object* key = source->KeyAt(i); | 8280 Object* key = source->KeyAt(i); |
| 8275 if (key->IsNumber()) { | 8281 if (key->IsNumber()) { |
| 8276 uint32_t entry = static_cast<uint32_t>(key->Number()); | 8282 uint32_t entry = static_cast<uint32_t>(key->Number()); |
| 8277 if (entry < static_cast<uint32_t>(destination_length)) { | 8283 if (entry < static_cast<uint32_t>(destination_length)) { |
| 8278 destination->set(entry, source->ValueAt(i), mode); | 8284 destination->set(entry, source->ValueAt(i), mode); |
| 8279 } | 8285 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8325 AssertNoAllocation no_gc; | 8331 AssertNoAllocation no_gc; |
| 8326 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); | 8332 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); |
| 8327 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), | 8333 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), |
| 8328 new_elements, mode); | 8334 new_elements, mode); |
| 8329 set_map_and_elements(new_map, new_elements); | 8335 set_map_and_elements(new_map, new_elements); |
| 8330 break; | 8336 break; |
| 8331 } | 8337 } |
| 8332 case DICTIONARY_ELEMENTS: { | 8338 case DICTIONARY_ELEMENTS: { |
| 8333 AssertNoAllocation no_gc; | 8339 AssertNoAllocation no_gc; |
| 8334 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | 8340 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
| 8335 CopySlowElementsToFast(NumberDictionary::cast(old_elements_raw), | 8341 CopySlowElementsToFast(SeededNumberDictionary::cast(old_elements_raw), |
| 8336 new_elements, | 8342 new_elements, |
| 8337 mode); | 8343 mode); |
| 8338 set_map_and_elements(new_map, new_elements); | 8344 set_map_and_elements(new_map, new_elements); |
| 8339 break; | 8345 break; |
| 8340 } | 8346 } |
| 8341 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 8347 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 8342 AssertNoAllocation no_gc; | 8348 AssertNoAllocation no_gc; |
| 8343 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | 8349 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
| 8344 // The object's map and the parameter map are unchanged, the unaliased | 8350 // The object's map and the parameter map are unchanged, the unaliased |
| 8345 // arguments are copied to the new backing store. | 8351 // arguments are copied to the new backing store. |
| 8346 FixedArray* parameter_map = FixedArray::cast(old_elements_raw); | 8352 FixedArray* parameter_map = FixedArray::cast(old_elements_raw); |
| 8347 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 8353 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 8348 if (arguments->IsDictionary()) { | 8354 if (arguments->IsDictionary()) { |
| 8349 CopySlowElementsToFast(NumberDictionary::cast(arguments), | 8355 CopySlowElementsToFast(SeededNumberDictionary::cast(arguments), |
| 8350 new_elements, | 8356 new_elements, |
| 8351 mode); | 8357 mode); |
| 8352 } else { | 8358 } else { |
| 8353 CopyFastElementsToFast(arguments, new_elements, mode); | 8359 CopyFastElementsToFast(arguments, new_elements, mode); |
| 8354 } | 8360 } |
| 8355 parameter_map->set(1, new_elements); | 8361 parameter_map->set(1, new_elements); |
| 8356 break; | 8362 break; |
| 8357 } | 8363 } |
| 8358 case FAST_DOUBLE_ELEMENTS: { | 8364 case FAST_DOUBLE_ELEMENTS: { |
| 8359 FixedDoubleArray* old_elements = FixedDoubleArray::cast(old_elements_raw); | 8365 FixedDoubleArray* old_elements = FixedDoubleArray::cast(old_elements_raw); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8435 case FAST_SMI_ONLY_ELEMENTS: | 8441 case FAST_SMI_ONLY_ELEMENTS: |
| 8436 case FAST_ELEMENTS: { | 8442 case FAST_ELEMENTS: { |
| 8437 elems->Initialize(FixedArray::cast(old_elements)); | 8443 elems->Initialize(FixedArray::cast(old_elements)); |
| 8438 break; | 8444 break; |
| 8439 } | 8445 } |
| 8440 case FAST_DOUBLE_ELEMENTS: { | 8446 case FAST_DOUBLE_ELEMENTS: { |
| 8441 elems->Initialize(FixedDoubleArray::cast(old_elements)); | 8447 elems->Initialize(FixedDoubleArray::cast(old_elements)); |
| 8442 break; | 8448 break; |
| 8443 } | 8449 } |
| 8444 case DICTIONARY_ELEMENTS: { | 8450 case DICTIONARY_ELEMENTS: { |
| 8445 elems->Initialize(NumberDictionary::cast(old_elements)); | 8451 elems->Initialize(SeededNumberDictionary::cast(old_elements)); |
| 8446 break; | 8452 break; |
| 8447 } | 8453 } |
| 8448 default: | 8454 default: |
| 8449 UNREACHABLE(); | 8455 UNREACHABLE(); |
| 8450 break; | 8456 break; |
| 8451 } | 8457 } |
| 8452 | 8458 |
| 8453 if (FLAG_trace_elements_transitions) { | 8459 if (FLAG_trace_elements_transitions) { |
| 8454 PrintElementsTransition(stdout, elements_kind, old_elements, | 8460 PrintElementsTransition(stdout, elements_kind, old_elements, |
| 8455 FAST_DOUBLE_ELEMENTS, elems); | 8461 FAST_DOUBLE_ELEMENTS, elems); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8695 case EXTERNAL_FLOAT_ELEMENTS: | 8701 case EXTERNAL_FLOAT_ELEMENTS: |
| 8696 case EXTERNAL_DOUBLE_ELEMENTS: { | 8702 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 8697 ExternalArray* array = ExternalArray::cast(elements()); | 8703 ExternalArray* array = ExternalArray::cast(elements()); |
| 8698 if (index < static_cast<uint32_t>(array->length())) { | 8704 if (index < static_cast<uint32_t>(array->length())) { |
| 8699 return true; | 8705 return true; |
| 8700 } | 8706 } |
| 8701 break; | 8707 break; |
| 8702 } | 8708 } |
| 8703 case DICTIONARY_ELEMENTS: { | 8709 case DICTIONARY_ELEMENTS: { |
| 8704 if (element_dictionary()->FindEntry(index) | 8710 if (element_dictionary()->FindEntry(index) |
| 8705 != NumberDictionary::kNotFound) { | 8711 != SeededNumberDictionary::kNotFound) { |
| 8706 return true; | 8712 return true; |
| 8707 } | 8713 } |
| 8708 break; | 8714 break; |
| 8709 } | 8715 } |
| 8710 case NON_STRICT_ARGUMENTS_ELEMENTS: | 8716 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 8711 UNREACHABLE(); | 8717 UNREACHABLE(); |
| 8712 break; | 8718 break; |
| 8713 } | 8719 } |
| 8714 | 8720 |
| 8715 // Handle [] on String objects. | 8721 // Handle [] on String objects. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8833 case EXTERNAL_INT_ELEMENTS: | 8839 case EXTERNAL_INT_ELEMENTS: |
| 8834 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 8840 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 8835 case EXTERNAL_FLOAT_ELEMENTS: | 8841 case EXTERNAL_FLOAT_ELEMENTS: |
| 8836 case EXTERNAL_DOUBLE_ELEMENTS: { | 8842 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 8837 ExternalArray* array = ExternalArray::cast(elements()); | 8843 ExternalArray* array = ExternalArray::cast(elements()); |
| 8838 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; | 8844 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; |
| 8839 break; | 8845 break; |
| 8840 } | 8846 } |
| 8841 case DICTIONARY_ELEMENTS: { | 8847 case DICTIONARY_ELEMENTS: { |
| 8842 if (element_dictionary()->FindEntry(index) != | 8848 if (element_dictionary()->FindEntry(index) != |
| 8843 NumberDictionary::kNotFound) { | 8849 SeededNumberDictionary::kNotFound) { |
| 8844 return DICTIONARY_ELEMENT; | 8850 return DICTIONARY_ELEMENT; |
| 8845 } | 8851 } |
| 8846 break; | 8852 break; |
| 8847 } | 8853 } |
| 8848 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 8854 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 8849 // Aliased parameters and non-aliased elements in a fast backing store | 8855 // Aliased parameters and non-aliased elements in a fast backing store |
| 8850 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary | 8856 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary |
| 8851 // backing store behave as DICTIONARY_ELEMENT. | 8857 // backing store behave as DICTIONARY_ELEMENT. |
| 8852 FixedArray* parameter_map = FixedArray::cast(elements()); | 8858 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 8853 uint32_t length = parameter_map->length(); | 8859 uint32_t length = parameter_map->length(); |
| 8854 Object* probe = | 8860 Object* probe = |
| 8855 index < (length - 2) ? parameter_map->get(index + 2) : NULL; | 8861 index < (length - 2) ? parameter_map->get(index + 2) : NULL; |
| 8856 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; | 8862 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; |
| 8857 // If not aliased, check the arguments. | 8863 // If not aliased, check the arguments. |
| 8858 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 8864 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 8859 if (arguments->IsDictionary()) { | 8865 if (arguments->IsDictionary()) { |
| 8860 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | 8866 SeededNumberDictionary* dictionary = |
| 8861 if (dictionary->FindEntry(index) != NumberDictionary::kNotFound) { | 8867 SeededNumberDictionary::cast(arguments); |
| 8868 if (dictionary->FindEntry(index) != SeededNumberDictionary::kNotFound) { |
| 8862 return DICTIONARY_ELEMENT; | 8869 return DICTIONARY_ELEMENT; |
| 8863 } | 8870 } |
| 8864 } else { | 8871 } else { |
| 8865 length = arguments->length(); | 8872 length = arguments->length(); |
| 8866 probe = (index < length) ? arguments->get(index) : NULL; | 8873 probe = (index < length) ? arguments->get(index) : NULL; |
| 8867 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; | 8874 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; |
| 8868 } | 8875 } |
| 8869 break; | 8876 break; |
| 8870 } | 8877 } |
| 8871 } | 8878 } |
| 8872 | 8879 |
| 8873 return UNDEFINED_ELEMENT; | 8880 return UNDEFINED_ELEMENT; |
| 8874 } | 8881 } |
| 8875 | 8882 |
| 8876 | 8883 |
| 8877 bool JSObject::HasElementInElements(FixedArray* elements, | 8884 bool JSObject::HasElementInElements(FixedArray* elements, |
| 8878 ElementsKind kind, | 8885 ElementsKind kind, |
| 8879 uint32_t index) { | 8886 uint32_t index) { |
| 8880 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); | 8887 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); |
| 8881 if (kind == FAST_ELEMENTS) { | 8888 if (kind == FAST_ELEMENTS) { |
| 8882 int length = IsJSArray() | 8889 int length = IsJSArray() |
| 8883 ? Smi::cast(JSArray::cast(this)->length())->value() | 8890 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 8884 : elements->length(); | 8891 : elements->length(); |
| 8885 if (index < static_cast<uint32_t>(length) && | 8892 if (index < static_cast<uint32_t>(length) && |
| 8886 !elements->get(index)->IsTheHole()) { | 8893 !elements->get(index)->IsTheHole()) { |
| 8887 return true; | 8894 return true; |
| 8888 } | 8895 } |
| 8889 } else { | 8896 } else { |
| 8890 if (NumberDictionary::cast(elements)->FindEntry(index) != | 8897 if (SeededNumberDictionary::cast(elements)->FindEntry(index) != |
| 8891 NumberDictionary::kNotFound) { | 8898 SeededNumberDictionary::kNotFound) { |
| 8892 return true; | 8899 return true; |
| 8893 } | 8900 } |
| 8894 } | 8901 } |
| 8895 return false; | 8902 return false; |
| 8896 } | 8903 } |
| 8897 | 8904 |
| 8898 | 8905 |
| 8899 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { | 8906 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { |
| 8900 // Check access rights if needed. | 8907 // Check access rights if needed. |
| 8901 if (IsAccessCheckNeeded()) { | 8908 if (IsAccessCheckNeeded()) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8948 case EXTERNAL_FLOAT_ELEMENTS: | 8955 case EXTERNAL_FLOAT_ELEMENTS: |
| 8949 case EXTERNAL_DOUBLE_ELEMENTS: { | 8956 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 8950 ExternalArray* array = ExternalArray::cast(elements()); | 8957 ExternalArray* array = ExternalArray::cast(elements()); |
| 8951 if (index < static_cast<uint32_t>(array->length())) { | 8958 if (index < static_cast<uint32_t>(array->length())) { |
| 8952 return true; | 8959 return true; |
| 8953 } | 8960 } |
| 8954 break; | 8961 break; |
| 8955 } | 8962 } |
| 8956 case DICTIONARY_ELEMENTS: { | 8963 case DICTIONARY_ELEMENTS: { |
| 8957 if (element_dictionary()->FindEntry(index) | 8964 if (element_dictionary()->FindEntry(index) |
| 8958 != NumberDictionary::kNotFound) { | 8965 != SeededNumberDictionary::kNotFound) { |
| 8959 return true; | 8966 return true; |
| 8960 } | 8967 } |
| 8961 break; | 8968 break; |
| 8962 } | 8969 } |
| 8963 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 8970 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 8964 FixedArray* parameter_map = FixedArray::cast(elements()); | 8971 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 8965 uint32_t length = parameter_map->length(); | 8972 uint32_t length = parameter_map->length(); |
| 8966 Object* probe = | 8973 Object* probe = |
| 8967 (index < length - 2) ? parameter_map->get(index + 2) : NULL; | 8974 (index < length - 2) ? parameter_map->get(index + 2) : NULL; |
| 8968 if (probe != NULL && !probe->IsTheHole()) return true; | 8975 if (probe != NULL && !probe->IsTheHole()) return true; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9271 StrictModeFlag strict_mode, | 9278 StrictModeFlag strict_mode, |
| 9272 bool check_prototype) { | 9279 bool check_prototype) { |
| 9273 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 9280 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 9274 Isolate* isolate = GetIsolate(); | 9281 Isolate* isolate = GetIsolate(); |
| 9275 Heap* heap = isolate->heap(); | 9282 Heap* heap = isolate->heap(); |
| 9276 | 9283 |
| 9277 // Insert element in the dictionary. | 9284 // Insert element in the dictionary. |
| 9278 FixedArray* elements = FixedArray::cast(this->elements()); | 9285 FixedArray* elements = FixedArray::cast(this->elements()); |
| 9279 bool is_arguments = | 9286 bool is_arguments = |
| 9280 (elements->map() == heap->non_strict_arguments_elements_map()); | 9287 (elements->map() == heap->non_strict_arguments_elements_map()); |
| 9281 NumberDictionary* dictionary = NULL; | 9288 SeededNumberDictionary* dictionary = NULL; |
| 9282 if (is_arguments) { | 9289 if (is_arguments) { |
| 9283 dictionary = NumberDictionary::cast(elements->get(1)); | 9290 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
| 9284 } else { | 9291 } else { |
| 9285 dictionary = NumberDictionary::cast(elements); | 9292 dictionary = SeededNumberDictionary::cast(elements); |
| 9286 } | 9293 } |
| 9287 | 9294 |
| 9288 int entry = dictionary->FindEntry(index); | 9295 int entry = dictionary->FindEntry(index); |
| 9289 if (entry != NumberDictionary::kNotFound) { | 9296 if (entry != SeededNumberDictionary::kNotFound) { |
| 9290 Object* element = dictionary->ValueAt(entry); | 9297 Object* element = dictionary->ValueAt(entry); |
| 9291 PropertyDetails details = dictionary->DetailsAt(entry); | 9298 PropertyDetails details = dictionary->DetailsAt(entry); |
| 9292 if (details.type() == CALLBACKS) { | 9299 if (details.type() == CALLBACKS) { |
| 9293 return SetElementWithCallback(element, index, value, this, strict_mode); | 9300 return SetElementWithCallback(element, index, value, this, strict_mode); |
| 9294 } else { | 9301 } else { |
| 9295 dictionary->UpdateMaxNumberKey(index); | 9302 dictionary->UpdateMaxNumberKey(index); |
| 9296 // If put fails in strict mode, throw an exception. | 9303 // If put fails in strict mode, throw an exception. |
| 9297 if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) { | 9304 if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) { |
| 9298 Handle<Object> holder(this); | 9305 Handle<Object> holder(this); |
| 9299 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 9306 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 9324 Handle<Object> args[1] = { name }; | 9331 Handle<Object> args[1] = { name }; |
| 9325 Handle<Object> error = | 9332 Handle<Object> error = |
| 9326 isolate->factory()->NewTypeError("object_not_extensible", | 9333 isolate->factory()->NewTypeError("object_not_extensible", |
| 9327 HandleVector(args, 1)); | 9334 HandleVector(args, 1)); |
| 9328 return isolate->Throw(*error); | 9335 return isolate->Throw(*error); |
| 9329 } | 9336 } |
| 9330 } | 9337 } |
| 9331 FixedArrayBase* new_dictionary; | 9338 FixedArrayBase* new_dictionary; |
| 9332 MaybeObject* maybe = dictionary->AtNumberPut(index, value); | 9339 MaybeObject* maybe = dictionary->AtNumberPut(index, value); |
| 9333 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; | 9340 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; |
| 9334 if (dictionary != NumberDictionary::cast(new_dictionary)) { | 9341 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { |
| 9335 if (is_arguments) { | 9342 if (is_arguments) { |
| 9336 elements->set(1, new_dictionary); | 9343 elements->set(1, new_dictionary); |
| 9337 } else { | 9344 } else { |
| 9338 set_elements(new_dictionary); | 9345 set_elements(new_dictionary); |
| 9339 } | 9346 } |
| 9340 dictionary = NumberDictionary::cast(new_dictionary); | 9347 dictionary = SeededNumberDictionary::cast(new_dictionary); |
| 9341 } | 9348 } |
| 9342 } | 9349 } |
| 9343 | 9350 |
| 9344 // Update the array length if this JSObject is an array. | 9351 // Update the array length if this JSObject is an array. |
| 9345 if (IsJSArray()) { | 9352 if (IsJSArray()) { |
| 9346 MaybeObject* result = | 9353 MaybeObject* result = |
| 9347 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); | 9354 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); |
| 9348 if (result->IsFailure()) return result; | 9355 if (result->IsFailure()) return result; |
| 9349 } | 9356 } |
| 9350 | 9357 |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9778 *used = 0; | 9785 *used = 0; |
| 9779 | 9786 |
| 9780 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); | 9787 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); |
| 9781 FixedArray* backing_store = NULL; | 9788 FixedArray* backing_store = NULL; |
| 9782 switch (GetElementsKind()) { | 9789 switch (GetElementsKind()) { |
| 9783 case NON_STRICT_ARGUMENTS_ELEMENTS: | 9790 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 9784 backing_store_base = | 9791 backing_store_base = |
| 9785 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); | 9792 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); |
| 9786 backing_store = FixedArray::cast(backing_store_base); | 9793 backing_store = FixedArray::cast(backing_store_base); |
| 9787 if (backing_store->IsDictionary()) { | 9794 if (backing_store->IsDictionary()) { |
| 9788 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); | 9795 SeededNumberDictionary* dictionary = |
| 9796 SeededNumberDictionary::cast(backing_store); |
| 9789 *capacity = dictionary->Capacity(); | 9797 *capacity = dictionary->Capacity(); |
| 9790 *used = dictionary->NumberOfElements(); | 9798 *used = dictionary->NumberOfElements(); |
| 9791 break; | 9799 break; |
| 9792 } | 9800 } |
| 9793 // Fall through. | 9801 // Fall through. |
| 9794 case FAST_SMI_ONLY_ELEMENTS: | 9802 case FAST_SMI_ONLY_ELEMENTS: |
| 9795 case FAST_ELEMENTS: | 9803 case FAST_ELEMENTS: |
| 9796 backing_store = FixedArray::cast(backing_store_base); | 9804 backing_store = FixedArray::cast(backing_store_base); |
| 9797 *capacity = backing_store->length(); | 9805 *capacity = backing_store->length(); |
| 9798 for (int i = 0; i < *capacity; ++i) { | 9806 for (int i = 0; i < *capacity; ++i) { |
| 9799 if (!backing_store->get(i)->IsTheHole()) ++(*used); | 9807 if (!backing_store->get(i)->IsTheHole()) ++(*used); |
| 9800 } | 9808 } |
| 9801 break; | 9809 break; |
| 9802 case DICTIONARY_ELEMENTS: { | 9810 case DICTIONARY_ELEMENTS: { |
| 9803 NumberDictionary* dictionary = | 9811 SeededNumberDictionary* dictionary = |
| 9804 NumberDictionary::cast(FixedArray::cast(elements())); | 9812 SeededNumberDictionary::cast(FixedArray::cast(elements())); |
| 9805 *capacity = dictionary->Capacity(); | 9813 *capacity = dictionary->Capacity(); |
| 9806 *used = dictionary->NumberOfElements(); | 9814 *used = dictionary->NumberOfElements(); |
| 9807 break; | 9815 break; |
| 9808 } | 9816 } |
| 9809 case FAST_DOUBLE_ELEMENTS: { | 9817 case FAST_DOUBLE_ELEMENTS: { |
| 9810 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); | 9818 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
| 9811 *capacity = elms->length(); | 9819 *capacity = elms->length(); |
| 9812 for (int i = 0; i < *capacity; i++) { | 9820 for (int i = 0; i < *capacity; i++) { |
| 9813 if (!elms->is_the_hole(i)) ++(*used); | 9821 if (!elms->is_the_hole(i)) ++(*used); |
| 9814 } | 9822 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 9839 (new_capacity <= kMaxUncheckedFastElementsLength && | 9847 (new_capacity <= kMaxUncheckedFastElementsLength && |
| 9840 GetHeap()->InNewSpace(this))) { | 9848 GetHeap()->InNewSpace(this))) { |
| 9841 return false; | 9849 return false; |
| 9842 } | 9850 } |
| 9843 // If the fast-case backing storage takes up roughly three times as | 9851 // If the fast-case backing storage takes up roughly three times as |
| 9844 // much space (in machine words) as a dictionary backing storage | 9852 // much space (in machine words) as a dictionary backing storage |
| 9845 // would, the object should have slow elements. | 9853 // would, the object should have slow elements. |
| 9846 int old_capacity = 0; | 9854 int old_capacity = 0; |
| 9847 int used_elements = 0; | 9855 int used_elements = 0; |
| 9848 GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 9856 GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
| 9849 int dictionary_size = NumberDictionary::ComputeCapacity(used_elements) * | 9857 int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) * |
| 9850 NumberDictionary::kEntrySize; | 9858 SeededNumberDictionary::kEntrySize; |
| 9851 return 3 * dictionary_size <= new_capacity; | 9859 return 3 * dictionary_size <= new_capacity; |
| 9852 } | 9860 } |
| 9853 | 9861 |
| 9854 | 9862 |
| 9855 bool JSObject::ShouldConvertToFastElements() { | 9863 bool JSObject::ShouldConvertToFastElements() { |
| 9856 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 9864 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 9857 // If the elements are sparse, we should not go back to fast case. | 9865 // If the elements are sparse, we should not go back to fast case. |
| 9858 if (!HasDenseElements()) return false; | 9866 if (!HasDenseElements()) return false; |
| 9859 // An object requiring access checks is never allowed to have fast | 9867 // An object requiring access checks is never allowed to have fast |
| 9860 // elements. If it had fast elements we would skip security checks. | 9868 // elements. If it had fast elements we would skip security checks. |
| 9861 if (IsAccessCheckNeeded()) return false; | 9869 if (IsAccessCheckNeeded()) return false; |
| 9862 | 9870 |
| 9863 FixedArray* elements = FixedArray::cast(this->elements()); | 9871 FixedArray* elements = FixedArray::cast(this->elements()); |
| 9864 NumberDictionary* dictionary = NULL; | 9872 SeededNumberDictionary* dictionary = NULL; |
| 9865 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { | 9873 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { |
| 9866 dictionary = NumberDictionary::cast(elements->get(1)); | 9874 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
| 9867 } else { | 9875 } else { |
| 9868 dictionary = NumberDictionary::cast(elements); | 9876 dictionary = SeededNumberDictionary::cast(elements); |
| 9869 } | 9877 } |
| 9870 // If an element has been added at a very high index in the elements | 9878 // If an element has been added at a very high index in the elements |
| 9871 // dictionary, we cannot go back to fast case. | 9879 // dictionary, we cannot go back to fast case. |
| 9872 if (dictionary->requires_slow_elements()) return false; | 9880 if (dictionary->requires_slow_elements()) return false; |
| 9873 // If the dictionary backing storage takes up roughly half as much | 9881 // If the dictionary backing storage takes up roughly half as much |
| 9874 // space (in machine words) as a fast-case backing storage would, | 9882 // space (in machine words) as a fast-case backing storage would, |
| 9875 // the object should have fast elements. | 9883 // the object should have fast elements. |
| 9876 uint32_t array_size = 0; | 9884 uint32_t array_size = 0; |
| 9877 if (IsJSArray()) { | 9885 if (IsJSArray()) { |
| 9878 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size)); | 9886 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size)); |
| 9879 } else { | 9887 } else { |
| 9880 array_size = dictionary->max_number_key(); | 9888 array_size = dictionary->max_number_key(); |
| 9881 } | 9889 } |
| 9882 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) * | 9890 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) * |
| 9883 NumberDictionary::kEntrySize; | 9891 SeededNumberDictionary::kEntrySize; |
| 9884 return 2 * dictionary_size >= array_size; | 9892 return 2 * dictionary_size >= array_size; |
| 9885 } | 9893 } |
| 9886 | 9894 |
| 9887 | 9895 |
| 9888 bool JSObject::ShouldConvertToFastDoubleElements( | 9896 bool JSObject::ShouldConvertToFastDoubleElements( |
| 9889 bool* has_smi_only_elements) { | 9897 bool* has_smi_only_elements) { |
| 9890 *has_smi_only_elements = false; | 9898 *has_smi_only_elements = false; |
| 9891 if (FLAG_unbox_double_arrays) { | 9899 if (FLAG_unbox_double_arrays) { |
| 9892 ASSERT(HasDictionaryElements()); | 9900 ASSERT(HasDictionaryElements()); |
| 9893 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 9901 SeededNumberDictionary* dictionary = |
| 9902 SeededNumberDictionary::cast(elements()); |
| 9894 bool found_double = false; | 9903 bool found_double = false; |
| 9895 for (int i = 0; i < dictionary->Capacity(); i++) { | 9904 for (int i = 0; i < dictionary->Capacity(); i++) { |
| 9896 Object* key = dictionary->KeyAt(i); | 9905 Object* key = dictionary->KeyAt(i); |
| 9897 if (key->IsNumber()) { | 9906 if (key->IsNumber()) { |
| 9898 Object* value = dictionary->ValueAt(i); | 9907 Object* value = dictionary->ValueAt(i); |
| 9899 if (!value->IsNumber()) return false; | 9908 if (!value->IsNumber()) return false; |
| 9900 if (!value->IsSmi()) { | 9909 if (!value->IsSmi()) { |
| 9901 found_double = true; | 9910 found_double = true; |
| 9902 } | 9911 } |
| 9903 } | 9912 } |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10103 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 10112 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 10104 case EXTERNAL_INT_ELEMENTS: | 10113 case EXTERNAL_INT_ELEMENTS: |
| 10105 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 10114 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 10106 case EXTERNAL_FLOAT_ELEMENTS: | 10115 case EXTERNAL_FLOAT_ELEMENTS: |
| 10107 case EXTERNAL_DOUBLE_ELEMENTS: { | 10116 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 10108 ExternalArray* array = ExternalArray::cast(elements()); | 10117 ExternalArray* array = ExternalArray::cast(elements()); |
| 10109 return index < static_cast<uint32_t>(array->length()); | 10118 return index < static_cast<uint32_t>(array->length()); |
| 10110 } | 10119 } |
| 10111 case DICTIONARY_ELEMENTS: { | 10120 case DICTIONARY_ELEMENTS: { |
| 10112 return element_dictionary()->FindEntry(index) | 10121 return element_dictionary()->FindEntry(index) |
| 10113 != NumberDictionary::kNotFound; | 10122 != SeededNumberDictionary::kNotFound; |
| 10114 } | 10123 } |
| 10115 case NON_STRICT_ARGUMENTS_ELEMENTS: | 10124 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 10116 UNIMPLEMENTED(); | 10125 UNIMPLEMENTED(); |
| 10117 break; | 10126 break; |
| 10118 } | 10127 } |
| 10119 // All possibilities have been handled above already. | 10128 // All possibilities have been handled above already. |
| 10120 UNREACHABLE(); | 10129 UNREACHABLE(); |
| 10121 return GetHeap()->null_value(); | 10130 return GetHeap()->null_value(); |
| 10122 } | 10131 } |
| 10123 | 10132 |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10372 } | 10381 } |
| 10373 counter++; | 10382 counter++; |
| 10374 } | 10383 } |
| 10375 ASSERT(!storage || storage->length() >= counter); | 10384 ASSERT(!storage || storage->length() >= counter); |
| 10376 break; | 10385 break; |
| 10377 } | 10386 } |
| 10378 case DICTIONARY_ELEMENTS: { | 10387 case DICTIONARY_ELEMENTS: { |
| 10379 if (storage != NULL) { | 10388 if (storage != NULL) { |
| 10380 element_dictionary()->CopyKeysTo(storage, | 10389 element_dictionary()->CopyKeysTo(storage, |
| 10381 filter, | 10390 filter, |
| 10382 NumberDictionary::SORTED); | 10391 SeededNumberDictionary::SORTED); |
| 10383 } | 10392 } |
| 10384 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); | 10393 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 10385 break; | 10394 break; |
| 10386 } | 10395 } |
| 10387 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 10396 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 10388 FixedArray* parameter_map = FixedArray::cast(elements()); | 10397 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 10389 int mapped_length = parameter_map->length() - 2; | 10398 int mapped_length = parameter_map->length() - 2; |
| 10390 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 10399 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 10391 if (arguments->IsDictionary()) { | 10400 if (arguments->IsDictionary()) { |
| 10392 // Copy the keys from arguments first, because Dictionary::CopyKeysTo | 10401 // Copy the keys from arguments first, because Dictionary::CopyKeysTo |
| 10393 // will insert in storage starting at index 0. | 10402 // will insert in storage starting at index 0. |
| 10394 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | 10403 SeededNumberDictionary* dictionary = |
| 10404 SeededNumberDictionary::cast(arguments); |
| 10395 if (storage != NULL) { | 10405 if (storage != NULL) { |
| 10396 dictionary->CopyKeysTo(storage, filter, NumberDictionary::UNSORTED); | 10406 dictionary->CopyKeysTo( |
| 10407 storage, filter, SeededNumberDictionary::UNSORTED); |
| 10397 } | 10408 } |
| 10398 counter += dictionary->NumberOfElementsFilterAttributes(filter); | 10409 counter += dictionary->NumberOfElementsFilterAttributes(filter); |
| 10399 for (int i = 0; i < mapped_length; ++i) { | 10410 for (int i = 0; i < mapped_length; ++i) { |
| 10400 if (!parameter_map->get(i + 2)->IsTheHole()) { | 10411 if (!parameter_map->get(i + 2)->IsTheHole()) { |
| 10401 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); | 10412 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); |
| 10402 ++counter; | 10413 ++counter; |
| 10403 } | 10414 } |
| 10404 } | 10415 } |
| 10405 if (storage != NULL) storage->SortPairs(storage, counter); | 10416 if (storage != NULL) storage->SortPairs(storage, counter); |
| 10406 | 10417 |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11017 template class HashTable<CompilationCacheShape, HashTableKey*>; | 11028 template class HashTable<CompilationCacheShape, HashTableKey*>; |
| 11018 | 11029 |
| 11019 template class HashTable<MapCacheShape, HashTableKey*>; | 11030 template class HashTable<MapCacheShape, HashTableKey*>; |
| 11020 | 11031 |
| 11021 template class HashTable<ObjectHashTableShape<1>, Object*>; | 11032 template class HashTable<ObjectHashTableShape<1>, Object*>; |
| 11022 | 11033 |
| 11023 template class HashTable<ObjectHashTableShape<2>, Object*>; | 11034 template class HashTable<ObjectHashTableShape<2>, Object*>; |
| 11024 | 11035 |
| 11025 template class Dictionary<StringDictionaryShape, String*>; | 11036 template class Dictionary<StringDictionaryShape, String*>; |
| 11026 | 11037 |
| 11027 template class Dictionary<NumberDictionaryShape, uint32_t>; | 11038 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; |
| 11028 | 11039 |
| 11029 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( | 11040 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; |
| 11030 int); | 11041 |
| 11042 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11043 Allocate(int at_least_space_for); |
| 11044 |
| 11045 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11046 Allocate(int at_least_space_for); |
| 11031 | 11047 |
| 11032 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( | 11048 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( |
| 11033 int); | 11049 int); |
| 11034 | 11050 |
| 11035 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( | 11051 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( |
| 11036 uint32_t, Object*); | 11052 uint32_t, Object*); |
| 11037 | 11053 |
| 11038 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( | 11054 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11039 Object*); | 11055 AtPut(uint32_t, Object*); |
| 11056 |
| 11057 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11058 SlowReverseLookup(Object* value); |
| 11040 | 11059 |
| 11041 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( | 11060 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( |
| 11042 Object*); | 11061 Object*); |
| 11043 | 11062 |
| 11044 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( | 11063 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( |
| 11045 FixedArray*, | 11064 FixedArray*, |
| 11046 PropertyAttributes, | 11065 PropertyAttributes, |
| 11047 Dictionary<NumberDictionaryShape, uint32_t>::SortMode); | 11066 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); |
| 11048 | 11067 |
| 11049 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( | 11068 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( |
| 11050 int, JSObject::DeleteMode); | 11069 int, JSObject::DeleteMode); |
| 11051 | 11070 |
| 11052 template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty( | 11071 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11053 int, JSObject::DeleteMode); | 11072 DeleteProperty(int, JSObject::DeleteMode); |
| 11054 | 11073 |
| 11055 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( | 11074 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( |
| 11056 String*); | 11075 String*); |
| 11057 | 11076 |
| 11058 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink( | 11077 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( |
| 11059 uint32_t); | 11078 uint32_t); |
| 11060 | 11079 |
| 11061 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( | 11080 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( |
| 11062 FixedArray*, | 11081 FixedArray*, |
| 11063 int, | 11082 int, |
| 11064 Dictionary<StringDictionaryShape, String*>::SortMode); | 11083 Dictionary<StringDictionaryShape, String*>::SortMode); |
| 11065 | 11084 |
| 11066 template int | 11085 template int |
| 11067 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( | 11086 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( |
| 11068 PropertyAttributes); | 11087 PropertyAttributes); |
| 11069 | 11088 |
| 11070 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( | 11089 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( |
| 11071 String*, Object*, PropertyDetails); | 11090 String*, Object*, PropertyDetails); |
| 11072 | 11091 |
| 11073 template MaybeObject* | 11092 template MaybeObject* |
| 11074 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); | 11093 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); |
| 11075 | 11094 |
| 11076 template int | 11095 template int |
| 11077 Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes( | 11096 Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11078 PropertyAttributes); | 11097 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 11079 | 11098 |
| 11080 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add( | 11099 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( |
| 11081 uint32_t, Object*, PropertyDetails); | 11100 uint32_t, Object*, PropertyDetails); |
| 11082 | 11101 |
| 11083 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>:: | 11102 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( |
| 11103 uint32_t, Object*, PropertyDetails); |
| 11104 |
| 11105 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11106 EnsureCapacity(int, uint32_t); |
| 11107 |
| 11108 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11084 EnsureCapacity(int, uint32_t); | 11109 EnsureCapacity(int, uint32_t); |
| 11085 | 11110 |
| 11086 template MaybeObject* Dictionary<StringDictionaryShape, String*>:: | 11111 template MaybeObject* Dictionary<StringDictionaryShape, String*>:: |
| 11087 EnsureCapacity(int, String*); | 11112 EnsureCapacity(int, String*); |
| 11088 | 11113 |
| 11089 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry( | 11114 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11090 uint32_t, Object*, PropertyDetails, uint32_t); | 11115 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 11116 |
| 11117 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11118 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 11091 | 11119 |
| 11092 template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry( | 11120 template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry( |
| 11093 String*, Object*, PropertyDetails, uint32_t); | 11121 String*, Object*, PropertyDetails, uint32_t); |
| 11094 | 11122 |
| 11095 template | 11123 template |
| 11096 int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements(); | 11124 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); |
| 11097 | 11125 |
| 11098 template | 11126 template |
| 11099 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); | 11127 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); |
| 11100 | 11128 |
| 11101 template | 11129 template |
| 11102 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 11130 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
| 11103 | 11131 |
| 11104 | 11132 |
| 11105 // Collates undefined and unexisting elements below limit from position | 11133 // Collates undefined and unexisting elements below limit from position |
| 11106 // zero of the elements. The object stays in Dictionary mode. | 11134 // zero of the elements. The object stays in Dictionary mode. |
| 11107 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { | 11135 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
| 11108 ASSERT(HasDictionaryElements()); | 11136 ASSERT(HasDictionaryElements()); |
| 11109 // Must stay in dictionary mode, either because of requires_slow_elements, | 11137 // Must stay in dictionary mode, either because of requires_slow_elements, |
| 11110 // or because we are not going to sort (and therefore compact) all of the | 11138 // or because we are not going to sort (and therefore compact) all of the |
| 11111 // elements. | 11139 // elements. |
| 11112 NumberDictionary* dict = element_dictionary(); | 11140 SeededNumberDictionary* dict = element_dictionary(); |
| 11113 HeapNumber* result_double = NULL; | 11141 HeapNumber* result_double = NULL; |
| 11114 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 11142 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 11115 // Allocate space for result before we start mutating the object. | 11143 // Allocate space for result before we start mutating the object. |
| 11116 Object* new_double; | 11144 Object* new_double; |
| 11117 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0); | 11145 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0); |
| 11118 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; | 11146 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
| 11119 } | 11147 } |
| 11120 result_double = HeapNumber::cast(new_double); | 11148 result_double = HeapNumber::cast(new_double); |
| 11121 } | 11149 } |
| 11122 | 11150 |
| 11123 Object* obj; | 11151 Object* obj; |
| 11124 { MaybeObject* maybe_obj = | 11152 { MaybeObject* maybe_obj = |
| 11125 NumberDictionary::Allocate(dict->NumberOfElements()); | 11153 SeededNumberDictionary::Allocate(dict->NumberOfElements()); |
| 11126 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 11154 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 11127 } | 11155 } |
| 11128 NumberDictionary* new_dict = NumberDictionary::cast(obj); | 11156 SeededNumberDictionary* new_dict = SeededNumberDictionary::cast(obj); |
| 11129 | 11157 |
| 11130 AssertNoAllocation no_alloc; | 11158 AssertNoAllocation no_alloc; |
| 11131 | 11159 |
| 11132 uint32_t pos = 0; | 11160 uint32_t pos = 0; |
| 11133 uint32_t undefs = 0; | 11161 uint32_t undefs = 0; |
| 11134 int capacity = dict->Capacity(); | 11162 int capacity = dict->Capacity(); |
| 11135 for (int i = 0; i < capacity; i++) { | 11163 for (int i = 0; i < capacity; i++) { |
| 11136 Object* k = dict->KeyAt(i); | 11164 Object* k = dict->KeyAt(i); |
| 11137 if (dict->IsKey(k)) { | 11165 if (dict->IsKey(k)) { |
| 11138 ASSERT(k->IsNumber()); | 11166 ASSERT(k->IsNumber()); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11202 // Collects all defined (non-hole) and non-undefined (array) elements at | 11230 // Collects all defined (non-hole) and non-undefined (array) elements at |
| 11203 // the start of the elements array. | 11231 // the start of the elements array. |
| 11204 // If the object is in dictionary mode, it is converted to fast elements | 11232 // If the object is in dictionary mode, it is converted to fast elements |
| 11205 // mode. | 11233 // mode. |
| 11206 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { | 11234 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { |
| 11207 Heap* heap = GetHeap(); | 11235 Heap* heap = GetHeap(); |
| 11208 | 11236 |
| 11209 if (HasDictionaryElements()) { | 11237 if (HasDictionaryElements()) { |
| 11210 // Convert to fast elements containing only the existing properties. | 11238 // Convert to fast elements containing only the existing properties. |
| 11211 // Ordering is irrelevant, since we are going to sort anyway. | 11239 // Ordering is irrelevant, since we are going to sort anyway. |
| 11212 NumberDictionary* dict = element_dictionary(); | 11240 SeededNumberDictionary* dict = element_dictionary(); |
| 11213 if (IsJSArray() || dict->requires_slow_elements() || | 11241 if (IsJSArray() || dict->requires_slow_elements() || |
| 11214 dict->max_number_key() >= limit) { | 11242 dict->max_number_key() >= limit) { |
| 11215 return PrepareSlowElementsForSort(limit); | 11243 return PrepareSlowElementsForSort(limit); |
| 11216 } | 11244 } |
| 11217 // Convert to fast elements. | 11245 // Convert to fast elements. |
| 11218 | 11246 |
| 11219 Object* obj; | 11247 Object* obj; |
| 11220 { MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); | 11248 { MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); |
| 11221 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 11249 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 11222 } | 11250 } |
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12057 SetNextEnumerationIndex(index + 1); | 12085 SetNextEnumerationIndex(index + 1); |
| 12058 } | 12086 } |
| 12059 SetEntry(entry, k, value, details); | 12087 SetEntry(entry, k, value, details); |
| 12060 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() | 12088 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() |
| 12061 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); | 12089 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); |
| 12062 HashTable<Shape, Key>::ElementAdded(); | 12090 HashTable<Shape, Key>::ElementAdded(); |
| 12063 return this; | 12091 return this; |
| 12064 } | 12092 } |
| 12065 | 12093 |
| 12066 | 12094 |
| 12067 void NumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 12095 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
| 12068 // If the dictionary requires slow elements an element has already | 12096 // If the dictionary requires slow elements an element has already |
| 12069 // been added at a high index. | 12097 // been added at a high index. |
| 12070 if (requires_slow_elements()) return; | 12098 if (requires_slow_elements()) return; |
| 12071 // Check if this index is high enough that we should require slow | 12099 // Check if this index is high enough that we should require slow |
| 12072 // elements. | 12100 // elements. |
| 12073 if (key > kRequiresSlowElementsLimit) { | 12101 if (key > kRequiresSlowElementsLimit) { |
| 12074 set_requires_slow_elements(); | 12102 set_requires_slow_elements(); |
| 12075 return; | 12103 return; |
| 12076 } | 12104 } |
| 12077 // Update max key value. | 12105 // Update max key value. |
| 12078 Object* max_index_object = get(kMaxNumberKeyIndex); | 12106 Object* max_index_object = get(kMaxNumberKeyIndex); |
| 12079 if (!max_index_object->IsSmi() || max_number_key() < key) { | 12107 if (!max_index_object->IsSmi() || max_number_key() < key) { |
| 12080 FixedArray::set(kMaxNumberKeyIndex, | 12108 FixedArray::set(kMaxNumberKeyIndex, |
| 12081 Smi::FromInt(key << kRequiresSlowElementsTagSize)); | 12109 Smi::FromInt(key << kRequiresSlowElementsTagSize)); |
| 12082 } | 12110 } |
| 12083 } | 12111 } |
| 12084 | 12112 |
| 12085 | 12113 |
| 12086 MaybeObject* NumberDictionary::AddNumberEntry(uint32_t key, | 12114 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, |
| 12087 Object* value, | 12115 Object* value, |
| 12088 PropertyDetails details) { | 12116 PropertyDetails details) { |
| 12089 UpdateMaxNumberKey(key); | 12117 UpdateMaxNumberKey(key); |
| 12090 SLOW_ASSERT(this->FindEntry(key) == kNotFound); | 12118 SLOW_ASSERT(this->FindEntry(key) == kNotFound); |
| 12091 return Add(key, value, details); | 12119 return Add(key, value, details); |
| 12092 } | 12120 } |
| 12093 | 12121 |
| 12094 | 12122 |
| 12095 MaybeObject* NumberDictionary::AtNumberPut(uint32_t key, Object* value) { | 12123 MaybeObject* UnseededNumberDictionary::AddNumberEntry(uint32_t key, |
| 12124 Object* value) { |
| 12125 SLOW_ASSERT(this->FindEntry(key) == kNotFound); |
| 12126 return Add(key, value, PropertyDetails(NONE, NORMAL)); |
| 12127 } |
| 12128 |
| 12129 |
| 12130 MaybeObject* SeededNumberDictionary::AtNumberPut(uint32_t key, Object* value) { |
| 12096 UpdateMaxNumberKey(key); | 12131 UpdateMaxNumberKey(key); |
| 12097 return AtPut(key, value); | 12132 return AtPut(key, value); |
| 12098 } | 12133 } |
| 12099 | 12134 |
| 12100 | 12135 |
| 12101 Handle<NumberDictionary> NumberDictionary::Set( | 12136 MaybeObject* UnseededNumberDictionary::AtNumberPut(uint32_t key, |
| 12102 Handle<NumberDictionary> dictionary, | 12137 Object* value) { |
| 12138 return AtPut(key, value); |
| 12139 } |
| 12140 |
| 12141 |
| 12142 Handle<SeededNumberDictionary> SeededNumberDictionary::Set( |
| 12143 Handle<SeededNumberDictionary> dictionary, |
| 12103 uint32_t index, | 12144 uint32_t index, |
| 12104 Handle<Object> value, | 12145 Handle<Object> value, |
| 12105 PropertyDetails details) { | 12146 PropertyDetails details) { |
| 12106 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | 12147 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 12107 dictionary->Set(index, *value, details), | 12148 dictionary->Set(index, *value, details), |
| 12108 NumberDictionary); | 12149 SeededNumberDictionary); |
| 12109 } | 12150 } |
| 12110 | 12151 |
| 12111 | 12152 |
| 12112 MaybeObject* NumberDictionary::Set(uint32_t key, | 12153 Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set( |
| 12113 Object* value, | 12154 Handle<UnseededNumberDictionary> dictionary, |
| 12114 PropertyDetails details) { | 12155 uint32_t index, |
| 12156 Handle<Object> value) { |
| 12157 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 12158 dictionary->Set(index, *value), |
| 12159 UnseededNumberDictionary); |
| 12160 } |
| 12161 |
| 12162 |
| 12163 MaybeObject* SeededNumberDictionary::Set(uint32_t key, |
| 12164 Object* value, |
| 12165 PropertyDetails details) { |
| 12115 int entry = FindEntry(key); | 12166 int entry = FindEntry(key); |
| 12116 if (entry == kNotFound) return AddNumberEntry(key, value, details); | 12167 if (entry == kNotFound) return AddNumberEntry(key, value, details); |
| 12117 // Preserve enumeration index. | 12168 // Preserve enumeration index. |
| 12118 details = PropertyDetails(details.attributes(), | 12169 details = PropertyDetails(details.attributes(), |
| 12119 details.type(), | 12170 details.type(), |
| 12120 DetailsAt(entry).index()); | 12171 DetailsAt(entry).index()); |
| 12121 MaybeObject* maybe_object_key = NumberDictionaryShape::AsObject(key); | 12172 MaybeObject* maybe_object_key = SeededNumberDictionaryShape::AsObject(key); |
| 12122 Object* object_key; | 12173 Object* object_key; |
| 12123 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; | 12174 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
| 12124 SetEntry(entry, object_key, value, details); | 12175 SetEntry(entry, object_key, value, details); |
| 12125 return this; | 12176 return this; |
| 12126 } | 12177 } |
| 12127 | 12178 |
| 12128 | 12179 |
| 12180 MaybeObject* UnseededNumberDictionary::Set(uint32_t key, |
| 12181 Object* value) { |
| 12182 int entry = FindEntry(key); |
| 12183 if (entry == kNotFound) return AddNumberEntry(key, value); |
| 12184 MaybeObject* maybe_object_key = UnseededNumberDictionaryShape::AsObject(key); |
| 12185 Object* object_key; |
| 12186 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
| 12187 SetEntry(entry, object_key, value); |
| 12188 return this; |
| 12189 } |
| 12190 |
| 12191 |
| 12129 | 12192 |
| 12130 template<typename Shape, typename Key> | 12193 template<typename Shape, typename Key> |
| 12131 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 12194 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( |
| 12132 PropertyAttributes filter) { | 12195 PropertyAttributes filter) { |
| 12133 int capacity = HashTable<Shape, Key>::Capacity(); | 12196 int capacity = HashTable<Shape, Key>::Capacity(); |
| 12134 int result = 0; | 12197 int result = 0; |
| 12135 for (int i = 0; i < capacity; i++) { | 12198 for (int i = 0; i < capacity; i++) { |
| 12136 Object* k = HashTable<Shape, Key>::KeyAt(i); | 12199 Object* k = HashTable<Shape, Key>::KeyAt(i); |
| 12137 if (HashTable<Shape, Key>::IsKey(k)) { | 12200 if (HashTable<Shape, Key>::IsKey(k)) { |
| 12138 PropertyDetails details = DetailsAt(i); | 12201 PropertyDetails details = DetailsAt(i); |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12743 if (break_point_objects()->IsUndefined()) return 0; | 12806 if (break_point_objects()->IsUndefined()) return 0; |
| 12744 // Single break point. | 12807 // Single break point. |
| 12745 if (!break_point_objects()->IsFixedArray()) return 1; | 12808 if (!break_point_objects()->IsFixedArray()) return 1; |
| 12746 // Multiple break points. | 12809 // Multiple break points. |
| 12747 return FixedArray::cast(break_point_objects())->length(); | 12810 return FixedArray::cast(break_point_objects())->length(); |
| 12748 } | 12811 } |
| 12749 #endif // ENABLE_DEBUGGER_SUPPORT | 12812 #endif // ENABLE_DEBUGGER_SUPPORT |
| 12750 | 12813 |
| 12751 | 12814 |
| 12752 } } // namespace v8::internal | 12815 } } // namespace v8::internal |
| OLD | NEW |