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

Side by Side Diff: src/objects.cc

Issue 9190001: Backport @10366 to 3.6 Base URL: http://v8.googlecode.com/svn/branches/3.6/
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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1933 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 Object* value, 1944 Object* value,
1945 bool* found, 1945 bool* found,
1946 StrictModeFlag strict_mode) { 1946 StrictModeFlag strict_mode) {
1947 Heap* heap = GetHeap(); 1947 Heap* heap = GetHeap();
1948 for (Object* pt = GetPrototype(); 1948 for (Object* pt = GetPrototype();
1949 pt != heap->null_value(); 1949 pt != heap->null_value();
1950 pt = pt->GetPrototype()) { 1950 pt = pt->GetPrototype()) {
1951 if (!JSObject::cast(pt)->HasDictionaryElements()) { 1951 if (!JSObject::cast(pt)->HasDictionaryElements()) {
1952 continue; 1952 continue;
1953 } 1953 }
1954 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); 1954 SeededNumberDictionary* dictionary =
1955 JSObject::cast(pt)->element_dictionary();
1955 int entry = dictionary->FindEntry(index); 1956 int entry = dictionary->FindEntry(index);
1956 if (entry != NumberDictionary::kNotFound) { 1957 if (entry != SeededNumberDictionary::kNotFound) {
1957 PropertyDetails details = dictionary->DetailsAt(entry); 1958 PropertyDetails details = dictionary->DetailsAt(entry);
1958 if (details.type() == CALLBACKS) { 1959 if (details.type() == CALLBACKS) {
1959 *found = true; 1960 *found = true;
1960 return SetElementWithCallback(dictionary->ValueAt(entry), 1961 return SetElementWithCallback(dictionary->ValueAt(entry),
1961 index, 1962 index,
1962 value, 1963 value,
1963 JSObject::cast(pt), 1964 JSObject::cast(pt),
1964 strict_mode); 1965 strict_mode);
1965 } 1966 }
1966 } 1967 }
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
2921 ASSERT(HasFastElements() || 2922 ASSERT(HasFastElements() ||
2922 HasFastDoubleElements() || 2923 HasFastDoubleElements() ||
2923 HasFastArgumentsElements()); 2924 HasFastArgumentsElements());
2924 // Compute the effective length and allocate a new backing store. 2925 // Compute the effective length and allocate a new backing store.
2925 int length = IsJSArray() 2926 int length = IsJSArray()
2926 ? Smi::cast(JSArray::cast(this)->length())->value() 2927 ? Smi::cast(JSArray::cast(this)->length())->value()
2927 : array->length(); 2928 : array->length();
2928 int old_capacity = 0; 2929 int old_capacity = 0;
2929 int used_elements = 0; 2930 int used_elements = 0;
2930 GetElementsCapacityAndUsage(&old_capacity, &used_elements); 2931 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
2931 NumberDictionary* dictionary = NULL; 2932 SeededNumberDictionary* dictionary = NULL;
2932 { Object* object; 2933 { Object* object;
2933 MaybeObject* maybe = NumberDictionary::Allocate(used_elements); 2934 MaybeObject* maybe = SeededNumberDictionary::Allocate(used_elements);
2934 if (!maybe->ToObject(&object)) return maybe; 2935 if (!maybe->ToObject(&object)) return maybe;
2935 dictionary = NumberDictionary::cast(object); 2936 dictionary = SeededNumberDictionary::cast(object);
2936 } 2937 }
2937 2938
2938 // Copy the elements to the new backing store. 2939 // Copy the elements to the new backing store.
2939 bool has_double_elements = array->IsFixedDoubleArray(); 2940 bool has_double_elements = array->IsFixedDoubleArray();
2940 for (int i = 0; i < length; i++) { 2941 for (int i = 0; i < length; i++) {
2941 Object* value = NULL; 2942 Object* value = NULL;
2942 if (has_double_elements) { 2943 if (has_double_elements) {
2943 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); 2944 FixedDoubleArray* double_array = FixedDoubleArray::cast(array);
2944 if (double_array->is_the_hole(i)) { 2945 if (double_array->is_the_hole(i)) {
2945 value = GetIsolate()->heap()->the_hole_value(); 2946 value = GetIsolate()->heap()->the_hole_value();
2946 } else { 2947 } else {
2947 // Objects must be allocated in the old object space, since the 2948 // Objects must be allocated in the old object space, since the
2948 // overall number of HeapNumbers needed for the conversion might 2949 // overall number of HeapNumbers needed for the conversion might
2949 // exceed the capacity of new space, and we would fail repeatedly 2950 // exceed the capacity of new space, and we would fail repeatedly
2950 // trying to convert the FixedDoubleArray. 2951 // trying to convert the FixedDoubleArray.
2951 MaybeObject* maybe_value_object = 2952 MaybeObject* maybe_value_object =
2952 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED); 2953 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED);
2953 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 2954 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
2954 } 2955 }
2955 } else { 2956 } else {
2956 ASSERT(old_map->has_fast_elements()); 2957 ASSERT(old_map->has_fast_elements());
2957 value = FixedArray::cast(array)->get(i); 2958 value = FixedArray::cast(array)->get(i);
2958 } 2959 }
2959 PropertyDetails details = PropertyDetails(NONE, NORMAL); 2960 PropertyDetails details = PropertyDetails(NONE, NORMAL);
2960 if (!value->IsTheHole()) { 2961 if (!value->IsTheHole()) {
2961 Object* result; 2962 Object* result;
2962 MaybeObject* maybe_result = 2963 MaybeObject* maybe_result =
2963 dictionary->AddNumberEntry(i, value, details); 2964 dictionary->AddNumberEntry(i, value, details);
2964 if (!maybe_result->ToObject(&result)) return maybe_result; 2965 if (!maybe_result->ToObject(&result)) return maybe_result;
2965 dictionary = NumberDictionary::cast(result); 2966 dictionary = SeededNumberDictionary::cast(result);
2966 } 2967 }
2967 } 2968 }
2968 2969
2969 // Switch to using the dictionary as the backing storage for elements. 2970 // Switch to using the dictionary as the backing storage for elements.
2970 if (is_arguments) { 2971 if (is_arguments) {
2971 FixedArray::cast(elements())->set(1, dictionary); 2972 FixedArray::cast(elements())->set(1, dictionary);
2972 } else { 2973 } else {
2973 // Set the new map first to satify the elements type assert in 2974 // Set the new map first to satify the elements type assert in
2974 // set_elements(). 2975 // set_elements().
2975 Object* new_map; 2976 Object* new_map;
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
3270 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); 3271 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
3271 if (kind == FAST_ELEMENTS) { 3272 if (kind == FAST_ELEMENTS) {
3272 int length = IsJSArray() 3273 int length = IsJSArray()
3273 ? Smi::cast(JSArray::cast(this)->length())->value() 3274 ? Smi::cast(JSArray::cast(this)->length())->value()
3274 : elements->length(); 3275 : elements->length();
3275 for (int i = 0; i < length; ++i) { 3276 for (int i = 0; i < length; ++i) {
3276 Object* element = elements->get(i); 3277 Object* element = elements->get(i);
3277 if (!element->IsTheHole() && element == object) return true; 3278 if (!element->IsTheHole() && element == object) return true;
3278 } 3279 }
3279 } else { 3280 } else {
3280 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); 3281 Object* key =
3282 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
3281 if (!key->IsUndefined()) return true; 3283 if (!key->IsUndefined()) return true;
3282 } 3284 }
3283 return false; 3285 return false;
3284 } 3286 }
3285 3287
3286 3288
3287 // Check whether this object references another object. 3289 // Check whether this object references another object.
3288 bool JSObject::ReferencesObject(Object* obj) { 3290 bool JSObject::ReferencesObject(Object* obj) {
3289 Map* map_of_this = map(); 3291 Map* map_of_this = map();
3290 Heap* heap = map_of_this->heap(); 3292 Heap* heap = map_of_this->heap();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3409 HandleScope scope(isolate); 3411 HandleScope scope(isolate);
3410 Handle<Object> object(this); 3412 Handle<Object> object(this);
3411 Handle<Object> error = 3413 Handle<Object> error =
3412 isolate->factory()->NewTypeError( 3414 isolate->factory()->NewTypeError(
3413 "cant_prevent_ext_external_array_elements", 3415 "cant_prevent_ext_external_array_elements",
3414 HandleVector(&object, 1)); 3416 HandleVector(&object, 1));
3415 return isolate->Throw(*error); 3417 return isolate->Throw(*error);
3416 } 3418 }
3417 3419
3418 // If there are fast elements we normalize. 3420 // If there are fast elements we normalize.
3419 NumberDictionary* dictionary = NULL; 3421 SeededNumberDictionary* dictionary = NULL;
3420 { MaybeObject* maybe = NormalizeElements(); 3422 { MaybeObject* maybe = NormalizeElements();
3421 if (!maybe->To<NumberDictionary>(&dictionary)) return maybe; 3423 if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe;
3422 } 3424 }
3423 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 3425 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
3424 // Make sure that we never go back to fast case. 3426 // Make sure that we never go back to fast case.
3425 dictionary->set_requires_slow_elements(); 3427 dictionary->set_requires_slow_elements();
3426 3428
3427 // Do a map transition, other objects with this map may still 3429 // Do a map transition, other objects with this map may still
3428 // be extensible. 3430 // be extensible.
3429 Map* new_map; 3431 Map* new_map;
3430 { MaybeObject* maybe = map()->CopyDropTransitions(); 3432 { MaybeObject* maybe = map()->CopyDropTransitions();
3431 if (!maybe->To<Map>(&new_map)) return maybe; 3433 if (!maybe->To<Map>(&new_map)) return maybe;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
3574 if (result->IsProperty() && result->type() == CALLBACKS) return; 3576 if (result->IsProperty() && result->type() == CALLBACKS) return;
3575 } 3577 }
3576 result->NotFound(); 3578 result->NotFound();
3577 } 3579 }
3578 3580
3579 3581
3580 // Search for a getter or setter in an elements dictionary. Returns either 3582 // Search for a getter or setter in an elements dictionary. Returns either
3581 // undefined if the element is read-only, or the getter/setter pair (fixed 3583 // undefined if the element is read-only, or the getter/setter pair (fixed
3582 // array) if there is an existing one, or the hole value if the element does 3584 // array) if there is an existing one, or the hole value if the element does
3583 // not exist or is a normal non-getter/setter data element. 3585 // not exist or is a normal non-getter/setter data element.
3584 static Object* FindGetterSetterInDictionary(NumberDictionary* dictionary, 3586 static Object* FindGetterSetterInDictionary(SeededNumberDictionary* dictionary,
3585 uint32_t index, 3587 uint32_t index,
3586 Heap* heap) { 3588 Heap* heap) {
3587 int entry = dictionary->FindEntry(index); 3589 int entry = dictionary->FindEntry(index);
3588 if (entry != NumberDictionary::kNotFound) { 3590 if (entry != SeededNumberDictionary::kNotFound) {
3589 Object* result = dictionary->ValueAt(entry); 3591 Object* result = dictionary->ValueAt(entry);
3590 PropertyDetails details = dictionary->DetailsAt(entry); 3592 PropertyDetails details = dictionary->DetailsAt(entry);
3591 if (details.IsReadOnly()) return heap->undefined_value(); 3593 if (details.IsReadOnly()) return heap->undefined_value();
3592 if (details.type() == CALLBACKS && result->IsFixedArray()) return result; 3594 if (details.type() == CALLBACKS && result->IsFixedArray()) return result;
3593 } 3595 }
3594 return heap->the_hole_value(); 3596 return heap->the_hole_value();
3595 } 3597 }
3596 3598
3597 3599
3598 MaybeObject* JSObject::DefineGetterSetter(String* name, 3600 MaybeObject* JSObject::DefineGetterSetter(String* name,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3640 // Ascertain whether we have read-only properties or an existing 3642 // Ascertain whether we have read-only properties or an existing
3641 // getter/setter pair in an arguments elements dictionary backing 3643 // getter/setter pair in an arguments elements dictionary backing
3642 // store. 3644 // store.
3643 FixedArray* parameter_map = FixedArray::cast(elements()); 3645 FixedArray* parameter_map = FixedArray::cast(elements());
3644 uint32_t length = parameter_map->length(); 3646 uint32_t length = parameter_map->length();
3645 Object* probe = 3647 Object* probe =
3646 index < (length - 2) ? parameter_map->get(index + 2) : NULL; 3648 index < (length - 2) ? parameter_map->get(index + 2) : NULL;
3647 if (probe == NULL || probe->IsTheHole()) { 3649 if (probe == NULL || probe->IsTheHole()) {
3648 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 3650 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
3649 if (arguments->IsDictionary()) { 3651 if (arguments->IsDictionary()) {
3650 NumberDictionary* dictionary = NumberDictionary::cast(arguments); 3652 SeededNumberDictionary* dictionary =
3653 SeededNumberDictionary::cast(arguments);
3651 probe = FindGetterSetterInDictionary(dictionary, index, heap); 3654 probe = FindGetterSetterInDictionary(dictionary, index, heap);
3652 if (!probe->IsTheHole()) return probe; 3655 if (!probe->IsTheHole()) return probe;
3653 } 3656 }
3654 } 3657 }
3655 break; 3658 break;
3656 } 3659 }
3657 } 3660 }
3658 } else { 3661 } else {
3659 // Lookup the name. 3662 // Lookup the name.
3660 LookupResult result; 3663 LookupResult result;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3709 return true; 3712 return true;
3710 } 3713 }
3711 3714
3712 3715
3713 MaybeObject* JSObject::SetElementCallback(uint32_t index, 3716 MaybeObject* JSObject::SetElementCallback(uint32_t index,
3714 Object* structure, 3717 Object* structure,
3715 PropertyAttributes attributes) { 3718 PropertyAttributes attributes) {
3716 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); 3719 PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
3717 3720
3718 // Normalize elements to make this operation simple. 3721 // Normalize elements to make this operation simple.
3719 NumberDictionary* dictionary = NULL; 3722 SeededNumberDictionary* dictionary = NULL;
3720 { Object* result; 3723 { Object* result;
3721 MaybeObject* maybe = NormalizeElements(); 3724 MaybeObject* maybe = NormalizeElements();
3722 if (!maybe->ToObject(&result)) return maybe; 3725 if (!maybe->ToObject(&result)) return maybe;
3723 dictionary = NumberDictionary::cast(result); 3726 dictionary = SeededNumberDictionary::cast(result);
3724 } 3727 }
3725 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 3728 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
3726 3729
3727 // Update the dictionary with the new CALLBACKS property. 3730 // Update the dictionary with the new CALLBACKS property.
3728 { Object* result; 3731 { Object* result;
3729 MaybeObject* maybe = dictionary->Set(index, structure, details); 3732 MaybeObject* maybe = dictionary->Set(index, structure, details);
3730 if (!maybe->ToObject(&result)) return maybe; 3733 if (!maybe->ToObject(&result)) return maybe;
3731 dictionary = NumberDictionary::cast(result); 3734 dictionary = SeededNumberDictionary::cast(result);
3732 } 3735 }
3733 3736
3734 dictionary->set_requires_slow_elements(); 3737 dictionary->set_requires_slow_elements();
3735 // Update the dictionary backing store on the object. 3738 // Update the dictionary backing store on the object.
3736 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { 3739 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) {
3737 // Also delete any parameter alias. 3740 // Also delete any parameter alias.
3738 // 3741 //
3739 // TODO(kmillikin): when deleting the last parameter alias we could 3742 // TODO(kmillikin): when deleting the last parameter alias we could
3740 // switch to a direct backing store without the parameter map. This 3743 // switch to a direct backing store without the parameter map. This
3741 // would allow GC of the context. 3744 // would allow GC of the context.
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
3926 3929
3927 // Make the lookup and include prototypes. 3930 // Make the lookup and include prototypes.
3928 int accessor_index = is_getter ? kGetterIndex : kSetterIndex; 3931 int accessor_index = is_getter ? kGetterIndex : kSetterIndex;
3929 uint32_t index = 0; 3932 uint32_t index = 0;
3930 if (name->AsArrayIndex(&index)) { 3933 if (name->AsArrayIndex(&index)) {
3931 for (Object* obj = this; 3934 for (Object* obj = this;
3932 obj != heap->null_value(); 3935 obj != heap->null_value();
3933 obj = JSObject::cast(obj)->GetPrototype()) { 3936 obj = JSObject::cast(obj)->GetPrototype()) {
3934 JSObject* js_object = JSObject::cast(obj); 3937 JSObject* js_object = JSObject::cast(obj);
3935 if (js_object->HasDictionaryElements()) { 3938 if (js_object->HasDictionaryElements()) {
3936 NumberDictionary* dictionary = js_object->element_dictionary(); 3939 SeededNumberDictionary* dictionary = js_object->element_dictionary();
3937 int entry = dictionary->FindEntry(index); 3940 int entry = dictionary->FindEntry(index);
3938 if (entry != NumberDictionary::kNotFound) { 3941 if (entry != SeededNumberDictionary::kNotFound) {
3939 Object* element = dictionary->ValueAt(entry); 3942 Object* element = dictionary->ValueAt(entry);
3940 PropertyDetails details = dictionary->DetailsAt(entry); 3943 PropertyDetails details = dictionary->DetailsAt(entry);
3941 if (details.type() == CALLBACKS) { 3944 if (details.type() == CALLBACKS) {
3942 if (element->IsFixedArray()) { 3945 if (element->IsFixedArray()) {
3943 return FixedArray::cast(element)->get(accessor_index); 3946 return FixedArray::cast(element)->get(accessor_index);
3944 } 3947 }
3945 } 3948 }
3946 } 3949 }
3947 } 3950 }
3948 } 3951 }
(...skipping 2121 matching lines...) Expand 10 before | Expand all | Expand 10 after
6070 // Should only be called if hash code has not yet been computed. 6073 // Should only be called if hash code has not yet been computed.
6071 ASSERT(!HasHashCode()); 6074 ASSERT(!HasHashCode());
6072 6075
6073 const int len = length(); 6076 const int len = length();
6074 6077
6075 // Compute the hash code. 6078 // Compute the hash code.
6076 uint32_t field = 0; 6079 uint32_t field = 0;
6077 if (StringShape(this).IsSequentialAscii()) { 6080 if (StringShape(this).IsSequentialAscii()) {
6078 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), 6081 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(),
6079 len, 6082 len,
6080 GetHeap()->StringHashSeed()); 6083 GetHeap()->HashSeed());
6081 } else if (StringShape(this).IsSequentialTwoByte()) { 6084 } else if (StringShape(this).IsSequentialTwoByte()) {
6082 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), 6085 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(),
6083 len, 6086 len,
6084 GetHeap()->StringHashSeed()); 6087 GetHeap()->HashSeed());
6085 } else { 6088 } else {
6086 StringInputBuffer buffer(this); 6089 StringInputBuffer buffer(this);
6087 field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed()); 6090 field = ComputeHashField(&buffer, len, GetHeap()->HashSeed());
6088 } 6091 }
6089 6092
6090 // Store the hash code in the object. 6093 // Store the hash code in the object.
6091 set_hash_field(field); 6094 set_hash_field(field);
6092 6095
6093 // Check the hash code is there. 6096 // Check the hash code is there.
6094 ASSERT(HasHashCode()); 6097 ASSERT(HasHashCode());
6095 uint32_t result = field >> kHashShift; 6098 uint32_t result = field >> kHashShift;
6096 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. 6099 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
6097 return result; 6100 return result;
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
7269 static void CopyFastElementsToFast(FixedArray* source, 7272 static void CopyFastElementsToFast(FixedArray* source,
7270 FixedArray* destination, 7273 FixedArray* destination,
7271 WriteBarrierMode mode) { 7274 WriteBarrierMode mode) {
7272 uint32_t count = static_cast<uint32_t>(source->length()); 7275 uint32_t count = static_cast<uint32_t>(source->length());
7273 for (uint32_t i = 0; i < count; ++i) { 7276 for (uint32_t i = 0; i < count; ++i) {
7274 destination->set(i, source->get(i), mode); 7277 destination->set(i, source->get(i), mode);
7275 } 7278 }
7276 } 7279 }
7277 7280
7278 7281
7279 static void CopySlowElementsToFast(NumberDictionary* source, 7282 static void CopySlowElementsToFast(SeededNumberDictionary* source,
7280 FixedArray* destination, 7283 FixedArray* destination,
7281 WriteBarrierMode mode) { 7284 WriteBarrierMode mode) {
7282 for (int i = 0; i < source->Capacity(); ++i) { 7285 for (int i = 0; i < source->Capacity(); ++i) {
7283 Object* key = source->KeyAt(i); 7286 Object* key = source->KeyAt(i);
7284 if (key->IsNumber()) { 7287 if (key->IsNumber()) {
7285 uint32_t entry = static_cast<uint32_t>(key->Number()); 7288 uint32_t entry = static_cast<uint32_t>(key->Number());
7286 destination->set(entry, source->ValueAt(i), mode); 7289 destination->set(entry, source->ValueAt(i), mode);
7287 } 7290 }
7288 } 7291 }
7289 } 7292 }
(...skipping 27 matching lines...) Expand all
7317 AssertNoAllocation no_gc; 7320 AssertNoAllocation no_gc;
7318 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 7321 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7319 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); 7322 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode);
7320 set_map(new_map); 7323 set_map(new_map);
7321 set_elements(new_elements); 7324 set_elements(new_elements);
7322 break; 7325 break;
7323 } 7326 }
7324 case DICTIONARY_ELEMENTS: { 7327 case DICTIONARY_ELEMENTS: {
7325 AssertNoAllocation no_gc; 7328 AssertNoAllocation no_gc;
7326 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 7329 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7327 CopySlowElementsToFast(NumberDictionary::cast(elements()), 7330 CopySlowElementsToFast(SeededNumberDictionary::cast(elements()),
7328 new_elements, 7331 new_elements,
7329 mode); 7332 mode);
7330 set_map(new_map); 7333 set_map(new_map);
7331 set_elements(new_elements); 7334 set_elements(new_elements);
7332 break; 7335 break;
7333 } 7336 }
7334 case NON_STRICT_ARGUMENTS_ELEMENTS: { 7337 case NON_STRICT_ARGUMENTS_ELEMENTS: {
7335 AssertNoAllocation no_gc; 7338 AssertNoAllocation no_gc;
7336 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 7339 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7337 // The object's map and the parameter map are unchanged, the unaliased 7340 // The object's map and the parameter map are unchanged, the unaliased
7338 // arguments are copied to the new backing store. 7341 // arguments are copied to the new backing store.
7339 FixedArray* parameter_map = FixedArray::cast(elements()); 7342 FixedArray* parameter_map = FixedArray::cast(elements());
7340 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 7343 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
7341 if (arguments->IsDictionary()) { 7344 if (arguments->IsDictionary()) {
7342 CopySlowElementsToFast(NumberDictionary::cast(arguments), 7345 CopySlowElementsToFast(SeededNumberDictionary::cast(arguments),
7343 new_elements, 7346 new_elements,
7344 mode); 7347 mode);
7345 } else { 7348 } else {
7346 CopyFastElementsToFast(arguments, new_elements, mode); 7349 CopyFastElementsToFast(arguments, new_elements, mode);
7347 } 7350 }
7348 parameter_map->set(1, new_elements); 7351 parameter_map->set(1, new_elements);
7349 break; 7352 break;
7350 } 7353 }
7351 case FAST_DOUBLE_ELEMENTS: { 7354 case FAST_DOUBLE_ELEMENTS: {
7352 FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements()); 7355 FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
7419 switch (GetElementsKind()) { 7422 switch (GetElementsKind()) {
7420 case FAST_ELEMENTS: { 7423 case FAST_ELEMENTS: {
7421 elems->Initialize(FixedArray::cast(elements())); 7424 elems->Initialize(FixedArray::cast(elements()));
7422 break; 7425 break;
7423 } 7426 }
7424 case FAST_DOUBLE_ELEMENTS: { 7427 case FAST_DOUBLE_ELEMENTS: {
7425 elems->Initialize(FixedDoubleArray::cast(elements())); 7428 elems->Initialize(FixedDoubleArray::cast(elements()));
7426 break; 7429 break;
7427 } 7430 }
7428 case DICTIONARY_ELEMENTS: { 7431 case DICTIONARY_ELEMENTS: {
7429 elems->Initialize(NumberDictionary::cast(elements())); 7432 elems->Initialize(SeededNumberDictionary::cast(elements()));
7430 break; 7433 break;
7431 } 7434 }
7432 default: 7435 default:
7433 UNREACHABLE(); 7436 UNREACHABLE();
7434 break; 7437 break;
7435 } 7438 }
7436 7439
7437 ASSERT(new_map->has_fast_double_elements()); 7440 ASSERT(new_map->has_fast_double_elements());
7438 set_map(new_map); 7441 set_map(new_map);
7439 ASSERT(elems->IsFixedDoubleArray()); 7442 ASSERT(elems->IsFixedDoubleArray());
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
7854 case EXTERNAL_FLOAT_ELEMENTS: 7857 case EXTERNAL_FLOAT_ELEMENTS:
7855 case EXTERNAL_DOUBLE_ELEMENTS: { 7858 case EXTERNAL_DOUBLE_ELEMENTS: {
7856 ExternalArray* array = ExternalArray::cast(elements()); 7859 ExternalArray* array = ExternalArray::cast(elements());
7857 if (index < static_cast<uint32_t>(array->length())) { 7860 if (index < static_cast<uint32_t>(array->length())) {
7858 return true; 7861 return true;
7859 } 7862 }
7860 break; 7863 break;
7861 } 7864 }
7862 case DICTIONARY_ELEMENTS: { 7865 case DICTIONARY_ELEMENTS: {
7863 if (element_dictionary()->FindEntry(index) 7866 if (element_dictionary()->FindEntry(index)
7864 != NumberDictionary::kNotFound) { 7867 != SeededNumberDictionary::kNotFound) {
7865 return true; 7868 return true;
7866 } 7869 }
7867 break; 7870 break;
7868 } 7871 }
7869 case NON_STRICT_ARGUMENTS_ELEMENTS: 7872 case NON_STRICT_ARGUMENTS_ELEMENTS:
7870 UNREACHABLE(); 7873 UNREACHABLE();
7871 break; 7874 break;
7872 } 7875 }
7873 7876
7874 // Handle [] on String objects. 7877 // Handle [] on String objects.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
7986 case EXTERNAL_INT_ELEMENTS: 7989 case EXTERNAL_INT_ELEMENTS:
7987 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7990 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7988 case EXTERNAL_FLOAT_ELEMENTS: 7991 case EXTERNAL_FLOAT_ELEMENTS:
7989 case EXTERNAL_DOUBLE_ELEMENTS: { 7992 case EXTERNAL_DOUBLE_ELEMENTS: {
7990 ExternalArray* array = ExternalArray::cast(elements()); 7993 ExternalArray* array = ExternalArray::cast(elements());
7991 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; 7994 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT;
7992 break; 7995 break;
7993 } 7996 }
7994 case DICTIONARY_ELEMENTS: { 7997 case DICTIONARY_ELEMENTS: {
7995 if (element_dictionary()->FindEntry(index) != 7998 if (element_dictionary()->FindEntry(index) !=
7996 NumberDictionary::kNotFound) { 7999 SeededNumberDictionary::kNotFound) {
7997 return DICTIONARY_ELEMENT; 8000 return DICTIONARY_ELEMENT;
7998 } 8001 }
7999 break; 8002 break;
8000 } 8003 }
8001 case NON_STRICT_ARGUMENTS_ELEMENTS: { 8004 case NON_STRICT_ARGUMENTS_ELEMENTS: {
8002 // Aliased parameters and non-aliased elements in a fast backing store 8005 // Aliased parameters and non-aliased elements in a fast backing store
8003 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary 8006 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary
8004 // backing store behave as DICTIONARY_ELEMENT. 8007 // backing store behave as DICTIONARY_ELEMENT.
8005 FixedArray* parameter_map = FixedArray::cast(elements()); 8008 FixedArray* parameter_map = FixedArray::cast(elements());
8006 uint32_t length = parameter_map->length(); 8009 uint32_t length = parameter_map->length();
8007 Object* probe = 8010 Object* probe =
8008 index < (length - 2) ? parameter_map->get(index + 2) : NULL; 8011 index < (length - 2) ? parameter_map->get(index + 2) : NULL;
8009 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; 8012 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT;
8010 // If not aliased, check the arguments. 8013 // If not aliased, check the arguments.
8011 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 8014 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
8012 if (arguments->IsDictionary()) { 8015 if (arguments->IsDictionary()) {
8013 NumberDictionary* dictionary = NumberDictionary::cast(arguments); 8016 SeededNumberDictionary* dictionary =
8014 if (dictionary->FindEntry(index) != NumberDictionary::kNotFound) { 8017 SeededNumberDictionary::cast(arguments);
8018 if (dictionary->FindEntry(index) != SeededNumberDictionary::kNotFound) {
8015 return DICTIONARY_ELEMENT; 8019 return DICTIONARY_ELEMENT;
8016 } 8020 }
8017 } else { 8021 } else {
8018 length = arguments->length(); 8022 length = arguments->length();
8019 probe = (index < length) ? arguments->get(index) : NULL; 8023 probe = (index < length) ? arguments->get(index) : NULL;
8020 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; 8024 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT;
8021 } 8025 }
8022 break; 8026 break;
8023 } 8027 }
8024 } 8028 }
8025 8029
8026 return UNDEFINED_ELEMENT; 8030 return UNDEFINED_ELEMENT;
8027 } 8031 }
8028 8032
8029 8033
8030 bool JSObject::HasElementInElements(FixedArray* elements, 8034 bool JSObject::HasElementInElements(FixedArray* elements,
8031 ElementsKind kind, 8035 ElementsKind kind,
8032 uint32_t index) { 8036 uint32_t index) {
8033 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); 8037 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
8034 if (kind == FAST_ELEMENTS) { 8038 if (kind == FAST_ELEMENTS) {
8035 int length = IsJSArray() 8039 int length = IsJSArray()
8036 ? Smi::cast(JSArray::cast(this)->length())->value() 8040 ? Smi::cast(JSArray::cast(this)->length())->value()
8037 : elements->length(); 8041 : elements->length();
8038 if (index < static_cast<uint32_t>(length) && 8042 if (index < static_cast<uint32_t>(length) &&
8039 !elements->get(index)->IsTheHole()) { 8043 !elements->get(index)->IsTheHole()) {
8040 return true; 8044 return true;
8041 } 8045 }
8042 } else { 8046 } else {
8043 if (NumberDictionary::cast(elements)->FindEntry(index) != 8047 if (SeededNumberDictionary::cast(elements)->FindEntry(index) !=
8044 NumberDictionary::kNotFound) { 8048 SeededNumberDictionary::kNotFound) {
8045 return true; 8049 return true;
8046 } 8050 }
8047 } 8051 }
8048 return false; 8052 return false;
8049 } 8053 }
8050 8054
8051 8055
8052 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { 8056 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
8053 // Check access rights if needed. 8057 // Check access rights if needed.
8054 if (IsAccessCheckNeeded()) { 8058 if (IsAccessCheckNeeded()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
8100 case EXTERNAL_FLOAT_ELEMENTS: 8104 case EXTERNAL_FLOAT_ELEMENTS:
8101 case EXTERNAL_DOUBLE_ELEMENTS: { 8105 case EXTERNAL_DOUBLE_ELEMENTS: {
8102 ExternalArray* array = ExternalArray::cast(elements()); 8106 ExternalArray* array = ExternalArray::cast(elements());
8103 if (index < static_cast<uint32_t>(array->length())) { 8107 if (index < static_cast<uint32_t>(array->length())) {
8104 return true; 8108 return true;
8105 } 8109 }
8106 break; 8110 break;
8107 } 8111 }
8108 case DICTIONARY_ELEMENTS: { 8112 case DICTIONARY_ELEMENTS: {
8109 if (element_dictionary()->FindEntry(index) 8113 if (element_dictionary()->FindEntry(index)
8110 != NumberDictionary::kNotFound) { 8114 != SeededNumberDictionary::kNotFound) {
8111 return true; 8115 return true;
8112 } 8116 }
8113 break; 8117 break;
8114 } 8118 }
8115 case NON_STRICT_ARGUMENTS_ELEMENTS: { 8119 case NON_STRICT_ARGUMENTS_ELEMENTS: {
8116 FixedArray* parameter_map = FixedArray::cast(elements()); 8120 FixedArray* parameter_map = FixedArray::cast(elements());
8117 uint32_t length = parameter_map->length(); 8121 uint32_t length = parameter_map->length();
8118 Object* probe = 8122 Object* probe =
8119 (index < length - 2) ? parameter_map->get(index + 2) : NULL; 8123 (index < length - 2) ? parameter_map->get(index + 2) : NULL;
8120 if (probe != NULL && !probe->IsTheHole()) return true; 8124 if (probe != NULL && !probe->IsTheHole()) return true;
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
8380 StrictModeFlag strict_mode, 8384 StrictModeFlag strict_mode,
8381 bool check_prototype) { 8385 bool check_prototype) {
8382 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 8386 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
8383 Isolate* isolate = GetIsolate(); 8387 Isolate* isolate = GetIsolate();
8384 Heap* heap = isolate->heap(); 8388 Heap* heap = isolate->heap();
8385 8389
8386 // Insert element in the dictionary. 8390 // Insert element in the dictionary.
8387 FixedArray* elements = FixedArray::cast(this->elements()); 8391 FixedArray* elements = FixedArray::cast(this->elements());
8388 bool is_arguments = 8392 bool is_arguments =
8389 (elements->map() == heap->non_strict_arguments_elements_map()); 8393 (elements->map() == heap->non_strict_arguments_elements_map());
8390 NumberDictionary* dictionary = NULL; 8394 SeededNumberDictionary* dictionary = NULL;
8391 if (is_arguments) { 8395 if (is_arguments) {
8392 dictionary = NumberDictionary::cast(elements->get(1)); 8396 dictionary = SeededNumberDictionary::cast(elements->get(1));
8393 } else { 8397 } else {
8394 dictionary = NumberDictionary::cast(elements); 8398 dictionary = SeededNumberDictionary::cast(elements);
8395 } 8399 }
8396 8400
8397 int entry = dictionary->FindEntry(index); 8401 int entry = dictionary->FindEntry(index);
8398 if (entry != NumberDictionary::kNotFound) { 8402 if (entry != SeededNumberDictionary::kNotFound) {
8399 Object* element = dictionary->ValueAt(entry); 8403 Object* element = dictionary->ValueAt(entry);
8400 PropertyDetails details = dictionary->DetailsAt(entry); 8404 PropertyDetails details = dictionary->DetailsAt(entry);
8401 if (details.type() == CALLBACKS) { 8405 if (details.type() == CALLBACKS) {
8402 return SetElementWithCallback(element, index, value, this, strict_mode); 8406 return SetElementWithCallback(element, index, value, this, strict_mode);
8403 } else { 8407 } else {
8404 dictionary->UpdateMaxNumberKey(index); 8408 dictionary->UpdateMaxNumberKey(index);
8405 // If put fails in strict mode, throw an exception. 8409 // If put fails in strict mode, throw an exception.
8406 if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) { 8410 if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) {
8407 Handle<Object> holder(this); 8411 Handle<Object> holder(this);
8408 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 8412 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
(...skipping 24 matching lines...) Expand all
8433 Handle<Object> args[1] = { name }; 8437 Handle<Object> args[1] = { name };
8434 Handle<Object> error = 8438 Handle<Object> error =
8435 isolate->factory()->NewTypeError("object_not_extensible", 8439 isolate->factory()->NewTypeError("object_not_extensible",
8436 HandleVector(args, 1)); 8440 HandleVector(args, 1));
8437 return isolate->Throw(*error); 8441 return isolate->Throw(*error);
8438 } 8442 }
8439 } 8443 }
8440 FixedArrayBase* new_dictionary; 8444 FixedArrayBase* new_dictionary;
8441 MaybeObject* maybe = dictionary->AtNumberPut(index, value); 8445 MaybeObject* maybe = dictionary->AtNumberPut(index, value);
8442 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; 8446 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe;
8443 if (dictionary != NumberDictionary::cast(new_dictionary)) { 8447 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) {
8444 if (is_arguments) { 8448 if (is_arguments) {
8445 elements->set(1, new_dictionary); 8449 elements->set(1, new_dictionary);
8446 } else { 8450 } else {
8447 set_elements(new_dictionary); 8451 set_elements(new_dictionary);
8448 } 8452 }
8449 dictionary = NumberDictionary::cast(new_dictionary); 8453 dictionary = SeededNumberDictionary::cast(new_dictionary);
8450 } 8454 }
8451 } 8455 }
8452 8456
8453 // Update the array length if this JSObject is an array. 8457 // Update the array length if this JSObject is an array.
8454 if (IsJSArray()) { 8458 if (IsJSArray()) {
8455 MaybeObject* result = 8459 MaybeObject* result =
8456 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); 8460 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value);
8457 if (result->IsFailure()) return result; 8461 if (result->IsFailure()) return result;
8458 } 8462 }
8459 8463
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
8760 *used = 0; 8764 *used = 0;
8761 8765
8762 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); 8766 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
8763 FixedArray* backing_store = NULL; 8767 FixedArray* backing_store = NULL;
8764 switch (GetElementsKind()) { 8768 switch (GetElementsKind()) {
8765 case NON_STRICT_ARGUMENTS_ELEMENTS: 8769 case NON_STRICT_ARGUMENTS_ELEMENTS:
8766 backing_store_base = 8770 backing_store_base =
8767 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); 8771 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
8768 backing_store = FixedArray::cast(backing_store_base); 8772 backing_store = FixedArray::cast(backing_store_base);
8769 if (backing_store->IsDictionary()) { 8773 if (backing_store->IsDictionary()) {
8770 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); 8774 SeededNumberDictionary* dictionary =
8775 SeededNumberDictionary::cast(backing_store);
8771 *capacity = dictionary->Capacity(); 8776 *capacity = dictionary->Capacity();
8772 *used = dictionary->NumberOfElements(); 8777 *used = dictionary->NumberOfElements();
8773 break; 8778 break;
8774 } 8779 }
8775 // Fall through. 8780 // Fall through.
8776 case FAST_ELEMENTS: 8781 case FAST_ELEMENTS:
8777 backing_store = FixedArray::cast(backing_store_base); 8782 backing_store = FixedArray::cast(backing_store_base);
8778 *capacity = backing_store->length(); 8783 *capacity = backing_store->length();
8779 for (int i = 0; i < *capacity; ++i) { 8784 for (int i = 0; i < *capacity; ++i) {
8780 if (!backing_store->get(i)->IsTheHole()) ++(*used); 8785 if (!backing_store->get(i)->IsTheHole()) ++(*used);
8781 } 8786 }
8782 break; 8787 break;
8783 case DICTIONARY_ELEMENTS: { 8788 case DICTIONARY_ELEMENTS: {
8784 NumberDictionary* dictionary = 8789 SeededNumberDictionary* dictionary =
8785 NumberDictionary::cast(FixedArray::cast(elements())); 8790 SeededNumberDictionary::cast(FixedArray::cast(elements()));
8786 *capacity = dictionary->Capacity(); 8791 *capacity = dictionary->Capacity();
8787 *used = dictionary->NumberOfElements(); 8792 *used = dictionary->NumberOfElements();
8788 break; 8793 break;
8789 } 8794 }
8790 case FAST_DOUBLE_ELEMENTS: { 8795 case FAST_DOUBLE_ELEMENTS: {
8791 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); 8796 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
8792 *capacity = elms->length(); 8797 *capacity = elms->length();
8793 for (int i = 0; i < *capacity; i++) { 8798 for (int i = 0; i < *capacity; i++) {
8794 if (!elms->is_the_hole(i)) ++(*used); 8799 if (!elms->is_the_hole(i)) ++(*used);
8795 } 8800 }
(...skipping 24 matching lines...) Expand all
8820 (new_capacity <= kMaxUncheckedFastElementsLength && 8825 (new_capacity <= kMaxUncheckedFastElementsLength &&
8821 GetHeap()->InNewSpace(this))) { 8826 GetHeap()->InNewSpace(this))) {
8822 return false; 8827 return false;
8823 } 8828 }
8824 // If the fast-case backing storage takes up roughly three times as 8829 // If the fast-case backing storage takes up roughly three times as
8825 // much space (in machine words) as a dictionary backing storage 8830 // much space (in machine words) as a dictionary backing storage
8826 // would, the object should have slow elements. 8831 // would, the object should have slow elements.
8827 int old_capacity = 0; 8832 int old_capacity = 0;
8828 int used_elements = 0; 8833 int used_elements = 0;
8829 GetElementsCapacityAndUsage(&old_capacity, &used_elements); 8834 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
8830 int dictionary_size = NumberDictionary::ComputeCapacity(used_elements) * 8835 int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) *
8831 NumberDictionary::kEntrySize; 8836 SeededNumberDictionary::kEntrySize;
8832 return 3 * dictionary_size <= new_capacity; 8837 return 3 * dictionary_size <= new_capacity;
8833 } 8838 }
8834 8839
8835 8840
8836 bool JSObject::ShouldConvertToFastElements() { 8841 bool JSObject::ShouldConvertToFastElements() {
8837 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 8842 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
8838 // If the elements are sparse, we should not go back to fast case. 8843 // If the elements are sparse, we should not go back to fast case.
8839 if (!HasDenseElements()) return false; 8844 if (!HasDenseElements()) return false;
8840 // An object requiring access checks is never allowed to have fast 8845 // An object requiring access checks is never allowed to have fast
8841 // elements. If it had fast elements we would skip security checks. 8846 // elements. If it had fast elements we would skip security checks.
8842 if (IsAccessCheckNeeded()) return false; 8847 if (IsAccessCheckNeeded()) return false;
8843 8848
8844 FixedArray* elements = FixedArray::cast(this->elements()); 8849 FixedArray* elements = FixedArray::cast(this->elements());
8845 NumberDictionary* dictionary = NULL; 8850 SeededNumberDictionary* dictionary = NULL;
8846 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { 8851 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
8847 dictionary = NumberDictionary::cast(elements->get(1)); 8852 dictionary = SeededNumberDictionary::cast(elements->get(1));
8848 } else { 8853 } else {
8849 dictionary = NumberDictionary::cast(elements); 8854 dictionary = SeededNumberDictionary::cast(elements);
8850 } 8855 }
8851 // If an element has been added at a very high index in the elements 8856 // If an element has been added at a very high index in the elements
8852 // dictionary, we cannot go back to fast case. 8857 // dictionary, we cannot go back to fast case.
8853 if (dictionary->requires_slow_elements()) return false; 8858 if (dictionary->requires_slow_elements()) return false;
8854 // If the dictionary backing storage takes up roughly half as much 8859 // If the dictionary backing storage takes up roughly half as much
8855 // space (in machine words) as a fast-case backing storage would, 8860 // space (in machine words) as a fast-case backing storage would,
8856 // the object should have fast elements. 8861 // the object should have fast elements.
8857 uint32_t array_size = 0; 8862 uint32_t array_size = 0;
8858 if (IsJSArray()) { 8863 if (IsJSArray()) {
8859 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size)); 8864 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size));
8860 } else { 8865 } else {
8861 array_size = dictionary->max_number_key(); 8866 array_size = dictionary->max_number_key();
8862 } 8867 }
8863 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) * 8868 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
8864 NumberDictionary::kEntrySize; 8869 SeededNumberDictionary::kEntrySize;
8865 return 2 * dictionary_size >= array_size; 8870 return 2 * dictionary_size >= array_size;
8866 } 8871 }
8867 8872
8868 8873
8869 bool JSObject::CanConvertToFastDoubleElements() { 8874 bool JSObject::CanConvertToFastDoubleElements() {
8870 if (FLAG_unbox_double_arrays) { 8875 if (FLAG_unbox_double_arrays) {
8871 ASSERT(HasDictionaryElements()); 8876 ASSERT(HasDictionaryElements());
8872 NumberDictionary* dictionary = NumberDictionary::cast(elements()); 8877 SeededNumberDictionary* dictionary =
8878 SeededNumberDictionary::cast(elements());
8873 for (int i = 0; i < dictionary->Capacity(); i++) { 8879 for (int i = 0; i < dictionary->Capacity(); i++) {
8874 Object* key = dictionary->KeyAt(i); 8880 Object* key = dictionary->KeyAt(i);
8875 if (key->IsNumber()) { 8881 if (key->IsNumber()) {
8876 if (!dictionary->ValueAt(i)->IsNumber()) return false; 8882 if (!dictionary->ValueAt(i)->IsNumber()) return false;
8877 } 8883 }
8878 } 8884 }
8879 return true; 8885 return true;
8880 } else { 8886 } else {
8881 return false; 8887 return false;
8882 } 8888 }
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
9075 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 9081 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
9076 case EXTERNAL_INT_ELEMENTS: 9082 case EXTERNAL_INT_ELEMENTS:
9077 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 9083 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
9078 case EXTERNAL_FLOAT_ELEMENTS: 9084 case EXTERNAL_FLOAT_ELEMENTS:
9079 case EXTERNAL_DOUBLE_ELEMENTS: { 9085 case EXTERNAL_DOUBLE_ELEMENTS: {
9080 ExternalArray* array = ExternalArray::cast(elements()); 9086 ExternalArray* array = ExternalArray::cast(elements());
9081 return index < static_cast<uint32_t>(array->length()); 9087 return index < static_cast<uint32_t>(array->length());
9082 } 9088 }
9083 case DICTIONARY_ELEMENTS: { 9089 case DICTIONARY_ELEMENTS: {
9084 return element_dictionary()->FindEntry(index) 9090 return element_dictionary()->FindEntry(index)
9085 != NumberDictionary::kNotFound; 9091 != SeededNumberDictionary::kNotFound;
9086 } 9092 }
9087 case NON_STRICT_ARGUMENTS_ELEMENTS: 9093 case NON_STRICT_ARGUMENTS_ELEMENTS:
9088 UNIMPLEMENTED(); 9094 UNIMPLEMENTED();
9089 break; 9095 break;
9090 } 9096 }
9091 // All possibilities have been handled above already. 9097 // All possibilities have been handled above already.
9092 UNREACHABLE(); 9098 UNREACHABLE();
9093 return GetHeap()->null_value(); 9099 return GetHeap()->null_value();
9094 } 9100 }
9095 9101
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
9343 } 9349 }
9344 counter++; 9350 counter++;
9345 } 9351 }
9346 ASSERT(!storage || storage->length() >= counter); 9352 ASSERT(!storage || storage->length() >= counter);
9347 break; 9353 break;
9348 } 9354 }
9349 case DICTIONARY_ELEMENTS: { 9355 case DICTIONARY_ELEMENTS: {
9350 if (storage != NULL) { 9356 if (storage != NULL) {
9351 element_dictionary()->CopyKeysTo(storage, 9357 element_dictionary()->CopyKeysTo(storage,
9352 filter, 9358 filter,
9353 NumberDictionary::SORTED); 9359 SeededNumberDictionary::SORTED);
9354 } 9360 }
9355 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); 9361 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
9356 break; 9362 break;
9357 } 9363 }
9358 case NON_STRICT_ARGUMENTS_ELEMENTS: { 9364 case NON_STRICT_ARGUMENTS_ELEMENTS: {
9359 FixedArray* parameter_map = FixedArray::cast(elements()); 9365 FixedArray* parameter_map = FixedArray::cast(elements());
9360 int mapped_length = parameter_map->length() - 2; 9366 int mapped_length = parameter_map->length() - 2;
9361 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 9367 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
9362 if (arguments->IsDictionary()) { 9368 if (arguments->IsDictionary()) {
9363 // Copy the keys from arguments first, because Dictionary::CopyKeysTo 9369 // Copy the keys from arguments first, because Dictionary::CopyKeysTo
9364 // will insert in storage starting at index 0. 9370 // will insert in storage starting at index 0.
9365 NumberDictionary* dictionary = NumberDictionary::cast(arguments); 9371 SeededNumberDictionary* dictionary =
9372 SeededNumberDictionary::cast(arguments);
9366 if (storage != NULL) { 9373 if (storage != NULL) {
9367 dictionary->CopyKeysTo(storage, filter, NumberDictionary::UNSORTED); 9374 dictionary->CopyKeysTo(
9375 storage, filter, SeededNumberDictionary::UNSORTED);
9368 } 9376 }
9369 counter += dictionary->NumberOfElementsFilterAttributes(filter); 9377 counter += dictionary->NumberOfElementsFilterAttributes(filter);
9370 for (int i = 0; i < mapped_length; ++i) { 9378 for (int i = 0; i < mapped_length; ++i) {
9371 if (!parameter_map->get(i + 2)->IsTheHole()) { 9379 if (!parameter_map->get(i + 2)->IsTheHole()) {
9372 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); 9380 if (storage != NULL) storage->set(counter, Smi::FromInt(i));
9373 ++counter; 9381 ++counter;
9374 } 9382 }
9375 } 9383 }
9376 if (storage != NULL) storage->SortPairs(storage, counter); 9384 if (storage != NULL) storage->SortPairs(storage, counter);
9377 9385
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
9664 public: 9672 public:
9665 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, 9673 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string,
9666 int from, 9674 int from,
9667 int length, 9675 int length,
9668 uint32_t seed) 9676 uint32_t seed)
9669 : string_(string), from_(from), length_(length), seed_(seed) { } 9677 : string_(string), from_(from), length_(length), seed_(seed) { }
9670 9678
9671 uint32_t Hash() { 9679 uint32_t Hash() {
9672 ASSERT(length_ >= 0); 9680 ASSERT(length_ >= 0);
9673 ASSERT(from_ + length_ <= string_->length()); 9681 ASSERT(from_ + length_ <= string_->length());
9674 StringHasher hasher(length_, string_->GetHeap()->StringHashSeed()); 9682 StringHasher hasher(length_, string_->GetHeap()->HashSeed());
9675 9683
9676 // Very long strings have a trivial hash that doesn't inspect the 9684 // Very long strings have a trivial hash that doesn't inspect the
9677 // string contents. 9685 // string contents.
9678 if (hasher.has_trivial_hash()) { 9686 if (hasher.has_trivial_hash()) {
9679 hash_field_ = hasher.GetHashField(); 9687 hash_field_ = hasher.GetHashField();
9680 } else { 9688 } else {
9681 int i = 0; 9689 int i = 0;
9682 // Do the iterative array index computation as long as there is a 9690 // Do the iterative array index computation as long as there is a
9683 // chance this is an array index. 9691 // chance this is an array index.
9684 while (i < length_ && hasher.is_array_index()) { 9692 while (i < length_ && hasher.is_array_index()) {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
9873 i++) { 9881 i++) {
9874 new_table->set(i, get(i), mode); 9882 new_table->set(i, get(i), mode);
9875 } 9883 }
9876 9884
9877 // Rehash the elements. 9885 // Rehash the elements.
9878 int capacity = Capacity(); 9886 int capacity = Capacity();
9879 for (int i = 0; i < capacity; i++) { 9887 for (int i = 0; i < capacity; i++) {
9880 uint32_t from_index = EntryToIndex(i); 9888 uint32_t from_index = EntryToIndex(i);
9881 Object* k = get(from_index); 9889 Object* k = get(from_index);
9882 if (IsKey(k)) { 9890 if (IsKey(k)) {
9883 uint32_t hash = Shape::HashForObject(key, k); 9891 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k);
9884 uint32_t insertion_index = 9892 uint32_t insertion_index =
9885 EntryToIndex(new_table->FindInsertionEntry(hash)); 9893 EntryToIndex(new_table->FindInsertionEntry(hash));
9886 for (int j = 0; j < Shape::kEntrySize; j++) { 9894 for (int j = 0; j < Shape::kEntrySize; j++) {
9887 new_table->set(insertion_index + j, get(from_index + j), mode); 9895 new_table->set(insertion_index + j, get(from_index + j), mode);
9888 } 9896 }
9889 } 9897 }
9890 } 9898 }
9891 new_table->SetNumberOfElements(NumberOfElements()); 9899 new_table->SetNumberOfElements(NumberOfElements());
9892 new_table->SetNumberOfDeletedElements(0); 9900 new_table->SetNumberOfDeletedElements(0);
9893 return new_table; 9901 return new_table;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
9969 template class HashTable<SymbolTableShape, HashTableKey*>; 9977 template class HashTable<SymbolTableShape, HashTableKey*>;
9970 9978
9971 template class HashTable<CompilationCacheShape, HashTableKey*>; 9979 template class HashTable<CompilationCacheShape, HashTableKey*>;
9972 9980
9973 template class HashTable<MapCacheShape, HashTableKey*>; 9981 template class HashTable<MapCacheShape, HashTableKey*>;
9974 9982
9975 template class HashTable<ObjectHashTableShape, JSObject*>; 9983 template class HashTable<ObjectHashTableShape, JSObject*>;
9976 9984
9977 template class Dictionary<StringDictionaryShape, String*>; 9985 template class Dictionary<StringDictionaryShape, String*>;
9978 9986
9979 template class Dictionary<NumberDictionaryShape, uint32_t>; 9987 template class Dictionary<SeededNumberDictionaryShape, uint32_t>;
9980 9988
9981 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( 9989 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>;
9982 int); 9990
9991 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
9992 Allocate(int at_least_space_for);
9993
9994 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
9995 Allocate(int at_least_space_for);
9983 9996
9984 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( 9997 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
9985 int); 9998 int);
9986 9999
9987 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( 10000 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut(
9988 uint32_t, Object*); 10001 uint32_t, Object*);
9989 10002
9990 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( 10003 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
9991 Object*); 10004 AtPut(uint32_t, Object*);
10005
10006 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
10007 SlowReverseLookup(Object* value);
9992 10008
9993 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( 10009 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup(
9994 Object*); 10010 Object*);
9995 10011
9996 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( 10012 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo(
9997 FixedArray*, 10013 FixedArray*,
9998 PropertyAttributes, 10014 PropertyAttributes,
9999 Dictionary<NumberDictionaryShape, uint32_t>::SortMode); 10015 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode);
10000 10016
10001 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( 10017 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty(
10002 int, JSObject::DeleteMode); 10018 int, JSObject::DeleteMode);
10003 10019
10004 template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty( 10020 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>::
10005 int, JSObject::DeleteMode); 10021 DeleteProperty(int, JSObject::DeleteMode);
10006 10022
10007 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( 10023 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink(
10008 String*); 10024 String*);
10009 10025
10010 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink( 10026 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink(
10011 uint32_t); 10027 uint32_t);
10012 10028
10013 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( 10029 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo(
10014 FixedArray*, 10030 FixedArray*,
10015 int, 10031 int,
10016 Dictionary<StringDictionaryShape, String*>::SortMode); 10032 Dictionary<StringDictionaryShape, String*>::SortMode);
10017 10033
10018 template int 10034 template int
10019 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( 10035 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes(
10020 PropertyAttributes); 10036 PropertyAttributes);
10021 10037
10022 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( 10038 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add(
10023 String*, Object*, PropertyDetails); 10039 String*, Object*, PropertyDetails);
10024 10040
10025 template MaybeObject* 10041 template MaybeObject*
10026 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); 10042 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices();
10027 10043
10028 template int 10044 template int
10029 Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes( 10045 Dictionary<SeededNumberDictionaryShape, uint32_t>::
10030 PropertyAttributes); 10046 NumberOfElementsFilterAttributes(PropertyAttributes);
10031 10047
10032 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add( 10048 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add(
10033 uint32_t, Object*, PropertyDetails); 10049 uint32_t, Object*, PropertyDetails);
10034 10050
10035 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>:: 10051 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add(
10052 uint32_t, Object*, PropertyDetails);
10053
10054 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
10055 EnsureCapacity(int, uint32_t);
10056
10057 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
10036 EnsureCapacity(int, uint32_t); 10058 EnsureCapacity(int, uint32_t);
10037 10059
10038 template MaybeObject* Dictionary<StringDictionaryShape, String*>:: 10060 template MaybeObject* Dictionary<StringDictionaryShape, String*>::
10039 EnsureCapacity(int, String*); 10061 EnsureCapacity(int, String*);
10040 10062
10041 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry( 10063 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
10042 uint32_t, Object*, PropertyDetails, uint32_t); 10064 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t);
10065
10066 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
10067 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t);
10043 10068
10044 template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry( 10069 template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry(
10045 String*, Object*, PropertyDetails, uint32_t); 10070 String*, Object*, PropertyDetails, uint32_t);
10046 10071
10047 template 10072 template
10048 int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements(); 10073 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements();
10049 10074
10050 template 10075 template
10051 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); 10076 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements();
10052 10077
10053 template 10078 template
10054 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); 10079 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
10055 10080
10056 10081
10057 // Collates undefined and unexisting elements below limit from position 10082 // Collates undefined and unexisting elements below limit from position
10058 // zero of the elements. The object stays in Dictionary mode. 10083 // zero of the elements. The object stays in Dictionary mode.
10059 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { 10084 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
10060 ASSERT(HasDictionaryElements()); 10085 ASSERT(HasDictionaryElements());
10061 // Must stay in dictionary mode, either because of requires_slow_elements, 10086 // Must stay in dictionary mode, either because of requires_slow_elements,
10062 // or because we are not going to sort (and therefore compact) all of the 10087 // or because we are not going to sort (and therefore compact) all of the
10063 // elements. 10088 // elements.
10064 NumberDictionary* dict = element_dictionary(); 10089 SeededNumberDictionary* dict = element_dictionary();
10065 HeapNumber* result_double = NULL; 10090 HeapNumber* result_double = NULL;
10066 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 10091 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
10067 // Allocate space for result before we start mutating the object. 10092 // Allocate space for result before we start mutating the object.
10068 Object* new_double; 10093 Object* new_double;
10069 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0); 10094 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0);
10070 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; 10095 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
10071 } 10096 }
10072 result_double = HeapNumber::cast(new_double); 10097 result_double = HeapNumber::cast(new_double);
10073 } 10098 }
10074 10099
10075 Object* obj; 10100 Object* obj;
10076 { MaybeObject* maybe_obj = 10101 { MaybeObject* maybe_obj =
10077 NumberDictionary::Allocate(dict->NumberOfElements()); 10102 SeededNumberDictionary::Allocate(dict->NumberOfElements());
10078 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10103 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10079 } 10104 }
10080 NumberDictionary* new_dict = NumberDictionary::cast(obj); 10105 SeededNumberDictionary* new_dict = SeededNumberDictionary::cast(obj);
10081 10106
10082 AssertNoAllocation no_alloc; 10107 AssertNoAllocation no_alloc;
10083 10108
10084 uint32_t pos = 0; 10109 uint32_t pos = 0;
10085 uint32_t undefs = 0; 10110 uint32_t undefs = 0;
10086 int capacity = dict->Capacity(); 10111 int capacity = dict->Capacity();
10087 for (int i = 0; i < capacity; i++) { 10112 for (int i = 0; i < capacity; i++) {
10088 Object* k = dict->KeyAt(i); 10113 Object* k = dict->KeyAt(i);
10089 if (dict->IsKey(k)) { 10114 if (dict->IsKey(k)) {
10090 ASSERT(k->IsNumber()); 10115 ASSERT(k->IsNumber());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
10156 // If the object is in dictionary mode, it is converted to fast elements 10181 // If the object is in dictionary mode, it is converted to fast elements
10157 // mode. 10182 // mode.
10158 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { 10183 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
10159 ASSERT(!HasExternalArrayElements()); 10184 ASSERT(!HasExternalArrayElements());
10160 10185
10161 Heap* heap = GetHeap(); 10186 Heap* heap = GetHeap();
10162 10187
10163 if (HasDictionaryElements()) { 10188 if (HasDictionaryElements()) {
10164 // Convert to fast elements containing only the existing properties. 10189 // Convert to fast elements containing only the existing properties.
10165 // Ordering is irrelevant, since we are going to sort anyway. 10190 // Ordering is irrelevant, since we are going to sort anyway.
10166 NumberDictionary* dict = element_dictionary(); 10191 SeededNumberDictionary* dict = element_dictionary();
10167 if (IsJSArray() || dict->requires_slow_elements() || 10192 if (IsJSArray() || dict->requires_slow_elements() ||
10168 dict->max_number_key() >= limit) { 10193 dict->max_number_key() >= limit) {
10169 return PrepareSlowElementsForSort(limit); 10194 return PrepareSlowElementsForSort(limit);
10170 } 10195 }
10171 // Convert to fast elements. 10196 // Convert to fast elements.
10172 10197
10173 Object* obj; 10198 Object* obj;
10174 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); 10199 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
10175 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10200 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10176 } 10201 }
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
10569 ASSERT(StringShape(result).IsSymbol()); 10594 ASSERT(StringShape(result).IsSymbol());
10570 *symbol = result; 10595 *symbol = result;
10571 return true; 10596 return true;
10572 } 10597 }
10573 } 10598 }
10574 10599
10575 10600
10576 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, 10601 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1,
10577 uint32_t c2, 10602 uint32_t c2,
10578 String** symbol) { 10603 String** symbol) {
10579 TwoCharHashTableKey key(c1, c2, GetHeap()->StringHashSeed()); 10604 TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed());
10580 int entry = FindEntry(&key); 10605 int entry = FindEntry(&key);
10581 if (entry == kNotFound) { 10606 if (entry == kNotFound) {
10582 return false; 10607 return false;
10583 } else { 10608 } else {
10584 String* result = String::cast(KeyAt(entry)); 10609 String* result = String::cast(KeyAt(entry));
10585 ASSERT(StringShape(result).IsSymbol()); 10610 ASSERT(StringShape(result).IsSymbol());
10586 *symbol = result; 10611 *symbol = result;
10587 return true; 10612 return true;
10588 } 10613 }
10589 } 10614 }
10590 10615
10591 10616
10592 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, 10617 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str,
10593 Object** s) { 10618 Object** s) {
10594 Utf8SymbolKey key(str, GetHeap()->StringHashSeed()); 10619 Utf8SymbolKey key(str, GetHeap()->HashSeed());
10595 return LookupKey(&key, s); 10620 return LookupKey(&key, s);
10596 } 10621 }
10597 10622
10598 10623
10599 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, 10624 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str,
10600 Object** s) { 10625 Object** s) {
10601 AsciiSymbolKey key(str, GetHeap()->StringHashSeed()); 10626 AsciiSymbolKey key(str, GetHeap()->HashSeed());
10602 return LookupKey(&key, s); 10627 return LookupKey(&key, s);
10603 } 10628 }
10604 10629
10605 10630
10606 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, 10631 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str,
10607 int from, 10632 int from,
10608 int length, 10633 int length,
10609 Object** s) { 10634 Object** s) {
10610 SubStringAsciiSymbolKey key(str, from, length, GetHeap()->StringHashSeed()); 10635 SubStringAsciiSymbolKey key(str, from, length, GetHeap()->HashSeed());
10611 return LookupKey(&key, s); 10636 return LookupKey(&key, s);
10612 } 10637 }
10613 10638
10614 10639
10615 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, 10640 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str,
10616 Object** s) { 10641 Object** s) {
10617 TwoByteSymbolKey key(str, GetHeap()->StringHashSeed()); 10642 TwoByteSymbolKey key(str, GetHeap()->HashSeed());
10618 return LookupKey(&key, s); 10643 return LookupKey(&key, s);
10619 } 10644 }
10620 10645
10621 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { 10646 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
10622 int entry = FindEntry(key); 10647 int entry = FindEntry(key);
10623 10648
10624 // Symbol already in table. 10649 // Symbol already in table.
10625 if (entry != kNotFound) { 10650 if (entry != kNotFound) {
10626 *s = KeyAt(entry); 10651 *s = KeyAt(entry);
10627 return this; 10652 return this;
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
10898 // If not, we generate new indices for the properties. 10923 // If not, we generate new indices for the properties.
10899 Object* result; 10924 Object* result;
10900 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); 10925 { MaybeObject* maybe_result = GenerateNewEnumerationIndices();
10901 if (!maybe_result->ToObject(&result)) return maybe_result; 10926 if (!maybe_result->ToObject(&result)) return maybe_result;
10902 } 10927 }
10903 } 10928 }
10904 return HashTable<Shape, Key>::EnsureCapacity(n, key); 10929 return HashTable<Shape, Key>::EnsureCapacity(n, key);
10905 } 10930 }
10906 10931
10907 10932
10908 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { 10933 void SeededNumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) {
10909 // Do nothing if the interval [from, to) is empty. 10934 // Do nothing if the interval [from, to) is empty.
10910 if (from >= to) return; 10935 if (from >= to) return;
10911 10936
10912 Heap* heap = GetHeap(); 10937 Heap* heap = GetHeap();
10913 int removed_entries = 0; 10938 int removed_entries = 0;
10914 Object* sentinel = heap->null_value(); 10939 Object* sentinel = heap->null_value();
10915 int capacity = Capacity(); 10940 int capacity = Capacity();
10916 for (int i = 0; i < capacity; i++) { 10941 for (int i = 0; i < capacity; i++) {
10917 Object* key = KeyAt(i); 10942 Object* key = KeyAt(i);
10918 if (key->IsNumber()) { 10943 if (key->IsNumber()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
10964 Object* obj; 10989 Object* obj;
10965 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 10990 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
10966 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10991 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10967 } 10992 }
10968 10993
10969 Object* k; 10994 Object* k;
10970 { MaybeObject* maybe_k = Shape::AsObject(key); 10995 { MaybeObject* maybe_k = Shape::AsObject(key);
10971 if (!maybe_k->ToObject(&k)) return maybe_k; 10996 if (!maybe_k->ToObject(&k)) return maybe_k;
10972 } 10997 }
10973 PropertyDetails details = PropertyDetails(NONE, NORMAL); 10998 PropertyDetails details = PropertyDetails(NONE, NORMAL);
10974 return Dictionary<Shape, Key>::cast(obj)-> 10999
10975 AddEntry(key, value, details, Shape::Hash(key)); 11000 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details,
11001 Dictionary<Shape, Key>::Hash(key));
10976 } 11002 }
10977 11003
10978 11004
10979 template<typename Shape, typename Key> 11005 template<typename Shape, typename Key>
10980 MaybeObject* Dictionary<Shape, Key>::Add(Key key, 11006 MaybeObject* Dictionary<Shape, Key>::Add(Key key,
10981 Object* value, 11007 Object* value,
10982 PropertyDetails details) { 11008 PropertyDetails details) {
10983 // Valdate key is absent. 11009 // Valdate key is absent.
10984 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); 11010 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound));
10985 // Check whether the dictionary should be extended. 11011 // Check whether the dictionary should be extended.
10986 Object* obj; 11012 Object* obj;
10987 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 11013 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
10988 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 11014 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10989 } 11015 }
10990 return Dictionary<Shape, Key>::cast(obj)-> 11016
10991 AddEntry(key, value, details, Shape::Hash(key)); 11017 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details,
11018 Dictionary<Shape, Key>::Hash(key));
10992 } 11019 }
10993 11020
10994 11021
10995 // Add a key, value pair to the dictionary. 11022 // Add a key, value pair to the dictionary.
10996 template<typename Shape, typename Key> 11023 template<typename Shape, typename Key>
10997 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, 11024 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key,
10998 Object* value, 11025 Object* value,
10999 PropertyDetails details, 11026 PropertyDetails details,
11000 uint32_t hash) { 11027 uint32_t hash) {
11001 // Compute the key object. 11028 // Compute the key object.
(...skipping 12 matching lines...) Expand all
11014 SetNextEnumerationIndex(index + 1); 11041 SetNextEnumerationIndex(index + 1);
11015 } 11042 }
11016 SetEntry(entry, k, value, details); 11043 SetEntry(entry, k, value, details);
11017 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() 11044 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber()
11018 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); 11045 || Dictionary<Shape, Key>::KeyAt(entry)->IsString()));
11019 HashTable<Shape, Key>::ElementAdded(); 11046 HashTable<Shape, Key>::ElementAdded();
11020 return this; 11047 return this;
11021 } 11048 }
11022 11049
11023 11050
11024 void NumberDictionary::UpdateMaxNumberKey(uint32_t key) { 11051 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
11025 // If the dictionary requires slow elements an element has already 11052 // If the dictionary requires slow elements an element has already
11026 // been added at a high index. 11053 // been added at a high index.
11027 if (requires_slow_elements()) return; 11054 if (requires_slow_elements()) return;
11028 // Check if this index is high enough that we should require slow 11055 // Check if this index is high enough that we should require slow
11029 // elements. 11056 // elements.
11030 if (key > kRequiresSlowElementsLimit) { 11057 if (key > kRequiresSlowElementsLimit) {
11031 set_requires_slow_elements(); 11058 set_requires_slow_elements();
11032 return; 11059 return;
11033 } 11060 }
11034 // Update max key value. 11061 // Update max key value.
11035 Object* max_index_object = get(kMaxNumberKeyIndex); 11062 Object* max_index_object = get(kMaxNumberKeyIndex);
11036 if (!max_index_object->IsSmi() || max_number_key() < key) { 11063 if (!max_index_object->IsSmi() || max_number_key() < key) {
11037 FixedArray::set(kMaxNumberKeyIndex, 11064 FixedArray::set(kMaxNumberKeyIndex,
11038 Smi::FromInt(key << kRequiresSlowElementsTagSize)); 11065 Smi::FromInt(key << kRequiresSlowElementsTagSize));
11039 } 11066 }
11040 } 11067 }
11041 11068
11042 11069
11043 MaybeObject* NumberDictionary::AddNumberEntry(uint32_t key, 11070 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key,
11044 Object* value, 11071 Object* value,
11045 PropertyDetails details) { 11072 PropertyDetails details) {
11046 UpdateMaxNumberKey(key); 11073 UpdateMaxNumberKey(key);
11047 SLOW_ASSERT(this->FindEntry(key) == kNotFound); 11074 SLOW_ASSERT(this->FindEntry(key) == kNotFound);
11048 return Add(key, value, details); 11075 return Add(key, value, details);
11049 } 11076 }
11050 11077
11051 11078
11052 MaybeObject* NumberDictionary::AtNumberPut(uint32_t key, Object* value) { 11079 MaybeObject* UnseededNumberDictionary::AddNumberEntry(uint32_t key,
11080 Object* value) {
11081 SLOW_ASSERT(this->FindEntry(key) == kNotFound);
11082 return Add(key, value, PropertyDetails(NONE, NORMAL));
11083 }
11084
11085
11086 MaybeObject* SeededNumberDictionary::AtNumberPut(uint32_t key, Object* value) {
11053 UpdateMaxNumberKey(key); 11087 UpdateMaxNumberKey(key);
11054 return AtPut(key, value); 11088 return AtPut(key, value);
11055 } 11089 }
11056 11090
11057 11091
11058 MaybeObject* NumberDictionary::Set(uint32_t key, 11092 MaybeObject* UnseededNumberDictionary::AtNumberPut(uint32_t key,
11059 Object* value, 11093 Object* value) {
11060 PropertyDetails details) { 11094 return AtPut(key, value);
11095 }
11096
11097
11098 MaybeObject* SeededNumberDictionary::Set(uint32_t key,
11099 Object* value,
11100 PropertyDetails details) {
11061 int entry = FindEntry(key); 11101 int entry = FindEntry(key);
11062 if (entry == kNotFound) return AddNumberEntry(key, value, details); 11102 if (entry == kNotFound) return AddNumberEntry(key, value, details);
11063 // Preserve enumeration index. 11103 // Preserve enumeration index.
11064 details = PropertyDetails(details.attributes(), 11104 details = PropertyDetails(details.attributes(),
11065 details.type(), 11105 details.type(),
11066 DetailsAt(entry).index()); 11106 DetailsAt(entry).index());
11067 MaybeObject* maybe_object_key = NumberDictionaryShape::AsObject(key); 11107 MaybeObject* maybe_object_key = SeededNumberDictionaryShape::AsObject(key);
11068 Object* object_key; 11108 Object* object_key;
11069 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; 11109 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
11070 SetEntry(entry, object_key, value, details); 11110 SetEntry(entry, object_key, value, details);
11071 return this; 11111 return this;
11072 } 11112 }
11073 11113
11074 11114
11115 MaybeObject* UnseededNumberDictionary::Set(uint32_t key,
11116 Object* value) {
11117 int entry = FindEntry(key);
11118 if (entry == kNotFound) return AddNumberEntry(key, value);
11119 MaybeObject* maybe_object_key = UnseededNumberDictionaryShape::AsObject(key);
11120 Object* object_key;
11121 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
11122 SetEntry(entry, object_key, value);
11123 return this;
11124 }
11125
11126
11075 11127
11076 template<typename Shape, typename Key> 11128 template<typename Shape, typename Key>
11077 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( 11129 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes(
11078 PropertyAttributes filter) { 11130 PropertyAttributes filter) {
11079 int capacity = HashTable<Shape, Key>::Capacity(); 11131 int capacity = HashTable<Shape, Key>::Capacity();
11080 int result = 0; 11132 int result = 0;
11081 for (int i = 0; i < capacity; i++) { 11133 for (int i = 0; i < capacity; i++) {
11082 Object* k = HashTable<Shape, Key>::KeyAt(i); 11134 Object* k = HashTable<Shape, Key>::KeyAt(i);
11083 if (HashTable<Shape, Key>::IsKey(k)) { 11135 if (HashTable<Shape, Key>::IsKey(k)) {
11084 PropertyDetails details = DetailsAt(i); 11136 PropertyDetails details = DetailsAt(i);
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
11624 if (break_point_objects()->IsUndefined()) return 0; 11676 if (break_point_objects()->IsUndefined()) return 0;
11625 // Single break point. 11677 // Single break point.
11626 if (!break_point_objects()->IsFixedArray()) return 1; 11678 if (!break_point_objects()->IsFixedArray()) return 1;
11627 // Multiple break points. 11679 // Multiple break points.
11628 return FixedArray::cast(break_point_objects())->length(); 11680 return FixedArray::cast(break_point_objects())->length();
11629 } 11681 }
11630 #endif 11682 #endif
11631 11683
11632 11684
11633 } } // namespace v8::internal 11685 } } // namespace v8::internal
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698