OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |