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

Side by Side Diff: src/objects.cc

Issue 9174023: Split NumberDictionary into a randomly seeded and an unseeded (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698