| 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 |