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 |