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 2896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2907 FixedArrayBase* array = FixedArrayBase::cast(elements()); | 2907 FixedArrayBase* array = FixedArrayBase::cast(elements()); |
2908 Map* old_map = array->map(); | 2908 Map* old_map = array->map(); |
2909 bool is_arguments = | 2909 bool is_arguments = |
2910 (old_map == old_map->heap()->non_strict_arguments_elements_map()); | 2910 (old_map == old_map->heap()->non_strict_arguments_elements_map()); |
2911 if (is_arguments) { | 2911 if (is_arguments) { |
2912 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); | 2912 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); |
2913 } | 2913 } |
2914 if (array->IsDictionary()) return array; | 2914 if (array->IsDictionary()) return array; |
2915 | 2915 |
2916 ASSERT(HasFastElements() || | 2916 ASSERT(HasFastElements() || |
2917 HasFastSmiOnlyElements() || | |
2917 HasFastDoubleElements() || | 2918 HasFastDoubleElements() || |
2918 HasFastArgumentsElements()); | 2919 HasFastArgumentsElements()); |
2919 // Compute the effective length and allocate a new backing store. | 2920 // Compute the effective length and allocate a new backing store. |
2920 int length = IsJSArray() | 2921 int length = IsJSArray() |
2921 ? Smi::cast(JSArray::cast(this)->length())->value() | 2922 ? Smi::cast(JSArray::cast(this)->length())->value() |
2922 : array->length(); | 2923 : array->length(); |
2923 int old_capacity = 0; | 2924 int old_capacity = 0; |
2924 int used_elements = 0; | 2925 int used_elements = 0; |
2925 GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 2926 GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
2926 NumberDictionary* dictionary = NULL; | 2927 NumberDictionary* dictionary = NULL; |
(...skipping 14 matching lines...) Expand all Loading... | |
2941 } else { | 2942 } else { |
2942 // Objects must be allocated in the old object space, since the | 2943 // Objects must be allocated in the old object space, since the |
2943 // overall number of HeapNumbers needed for the conversion might | 2944 // overall number of HeapNumbers needed for the conversion might |
2944 // exceed the capacity of new space, and we would fail repeatedly | 2945 // exceed the capacity of new space, and we would fail repeatedly |
2945 // trying to convert the FixedDoubleArray. | 2946 // trying to convert the FixedDoubleArray. |
2946 MaybeObject* maybe_value_object = | 2947 MaybeObject* maybe_value_object = |
2947 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED); | 2948 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED); |
2948 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; | 2949 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; |
2949 } | 2950 } |
2950 } else { | 2951 } else { |
2951 ASSERT(old_map->has_fast_elements()); | 2952 ASSERT(old_map->has_fast_elements() || |
2953 old_map->has_fast_smi_only_elements()); | |
2952 value = FixedArray::cast(array)->get(i); | 2954 value = FixedArray::cast(array)->get(i); |
2953 } | 2955 } |
2954 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 2956 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
2955 if (!value->IsTheHole()) { | 2957 if (!value->IsTheHole()) { |
2956 Object* result; | 2958 Object* result; |
2957 MaybeObject* maybe_result = | 2959 MaybeObject* maybe_result = |
2958 dictionary->AddNumberEntry(i, value, details); | 2960 dictionary->AddNumberEntry(i, value, details); |
2959 if (!maybe_result->ToObject(&result)) return maybe_result; | 2961 if (!maybe_result->ToObject(&result)) return maybe_result; |
2960 dictionary = NumberDictionary::cast(result); | 2962 dictionary = NumberDictionary::cast(result); |
2961 } | 2963 } |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3248 } | 3250 } |
3249 // Make sure the properties are normalized before removing the entry. | 3251 // Make sure the properties are normalized before removing the entry. |
3250 return DeleteNormalizedProperty(name, mode); | 3252 return DeleteNormalizedProperty(name, mode); |
3251 } | 3253 } |
3252 } | 3254 } |
3253 | 3255 |
3254 | 3256 |
3255 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 3257 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
3256 ElementsKind kind, | 3258 ElementsKind kind, |
3257 Object* object) { | 3259 Object* object) { |
3258 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); | 3260 ASSERT(kind == FAST_ELEMENTS || |
3261 kind == FAST_SMI_ONLY_ELEMENTS || | |
3262 kind == DICTIONARY_ELEMENTS); | |
3259 if (kind == FAST_ELEMENTS) { | 3263 if (kind == FAST_ELEMENTS) { |
3260 int length = IsJSArray() | 3264 int length = IsJSArray() |
3261 ? Smi::cast(JSArray::cast(this)->length())->value() | 3265 ? Smi::cast(JSArray::cast(this)->length())->value() |
3262 : elements->length(); | 3266 : elements->length(); |
3263 for (int i = 0; i < length; ++i) { | 3267 for (int i = 0; i < length; ++i) { |
3264 Object* element = elements->get(i); | 3268 Object* element = elements->get(i); |
3265 if (!element->IsTheHole() && element == object) return true; | 3269 if (!element->IsTheHole() && element == object) return true; |
3266 } | 3270 } |
3267 } else { | 3271 } else if (kind != FAST_SMI_ONLY_ELEMENTS) { |
Rico
2011/09/16 09:40:10
kind == DICTIONARY_ELEMENTS
seems much more readab
danno
2011/09/21 14:32:04
Done.
| |
3268 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); | 3272 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); |
3269 if (!key->IsUndefined()) return true; | 3273 if (!key->IsUndefined()) return true; |
3270 } | 3274 } |
3271 return false; | 3275 return false; |
3272 } | 3276 } |
3273 | 3277 |
3274 | 3278 |
3275 // Check whether this object references another object. | 3279 // Check whether this object references another object. |
3276 bool JSObject::ReferencesObject(Object* obj) { | 3280 bool JSObject::ReferencesObject(Object* obj) { |
3277 Map* map_of_this = map(); | 3281 Map* map_of_this = map(); |
(...skipping 25 matching lines...) Expand all Loading... | |
3303 case EXTERNAL_SHORT_ELEMENTS: | 3307 case EXTERNAL_SHORT_ELEMENTS: |
3304 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3308 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3305 case EXTERNAL_INT_ELEMENTS: | 3309 case EXTERNAL_INT_ELEMENTS: |
3306 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3310 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3307 case EXTERNAL_FLOAT_ELEMENTS: | 3311 case EXTERNAL_FLOAT_ELEMENTS: |
3308 case EXTERNAL_DOUBLE_ELEMENTS: | 3312 case EXTERNAL_DOUBLE_ELEMENTS: |
3309 case FAST_DOUBLE_ELEMENTS: | 3313 case FAST_DOUBLE_ELEMENTS: |
3310 // Raw pixels and external arrays do not reference other | 3314 // Raw pixels and external arrays do not reference other |
3311 // objects. | 3315 // objects. |
3312 break; | 3316 break; |
3317 case FAST_SMI_ONLY_ELEMENTS: | |
Rico
2011/09/16 09:40:10
Why not just break here and remove the new extra k
danno
2011/09/21 14:32:04
Done.
| |
3313 case FAST_ELEMENTS: | 3318 case FAST_ELEMENTS: |
3314 case DICTIONARY_ELEMENTS: { | 3319 case DICTIONARY_ELEMENTS: { |
3315 FixedArray* elements = FixedArray::cast(this->elements()); | 3320 FixedArray* elements = FixedArray::cast(this->elements()); |
3316 if (ReferencesObjectFromElements(elements, kind, obj)) return true; | 3321 if (ReferencesObjectFromElements(elements, kind, obj)) return true; |
3317 break; | 3322 break; |
3318 } | 3323 } |
3319 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 3324 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
3320 FixedArray* parameter_map = FixedArray::cast(elements()); | 3325 FixedArray* parameter_map = FixedArray::cast(elements()); |
3321 // Check the mapped parameters. | 3326 // Check the mapped parameters. |
3322 int length = parameter_map->length(); | 3327 int length = parameter_map->length(); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3595 | 3600 |
3596 if (!CanSetCallback(name)) { | 3601 if (!CanSetCallback(name)) { |
3597 return heap->undefined_value(); | 3602 return heap->undefined_value(); |
3598 } | 3603 } |
3599 | 3604 |
3600 uint32_t index = 0; | 3605 uint32_t index = 0; |
3601 bool is_element = name->AsArrayIndex(&index); | 3606 bool is_element = name->AsArrayIndex(&index); |
3602 | 3607 |
3603 if (is_element) { | 3608 if (is_element) { |
3604 switch (GetElementsKind()) { | 3609 switch (GetElementsKind()) { |
3610 case FAST_SMI_ONLY_ELEMENTS: | |
3605 case FAST_ELEMENTS: | 3611 case FAST_ELEMENTS: |
3606 case FAST_DOUBLE_ELEMENTS: | 3612 case FAST_DOUBLE_ELEMENTS: |
3607 break; | 3613 break; |
3608 case EXTERNAL_PIXEL_ELEMENTS: | 3614 case EXTERNAL_PIXEL_ELEMENTS: |
3609 case EXTERNAL_BYTE_ELEMENTS: | 3615 case EXTERNAL_BYTE_ELEMENTS: |
3610 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3616 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3611 case EXTERNAL_SHORT_ELEMENTS: | 3617 case EXTERNAL_SHORT_ELEMENTS: |
3612 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3618 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3613 case EXTERNAL_INT_ELEMENTS: | 3619 case EXTERNAL_INT_ELEMENTS: |
3614 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3620 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3844 } | 3850 } |
3845 | 3851 |
3846 uint32_t index = 0; | 3852 uint32_t index = 0; |
3847 bool is_element = name->AsArrayIndex(&index); | 3853 bool is_element = name->AsArrayIndex(&index); |
3848 | 3854 |
3849 if (is_element) { | 3855 if (is_element) { |
3850 if (IsJSArray()) return isolate->heap()->undefined_value(); | 3856 if (IsJSArray()) return isolate->heap()->undefined_value(); |
3851 | 3857 |
3852 // Accessors overwrite previous callbacks (cf. with getters/setters). | 3858 // Accessors overwrite previous callbacks (cf. with getters/setters). |
3853 switch (GetElementsKind()) { | 3859 switch (GetElementsKind()) { |
3860 case FAST_SMI_ONLY_ELEMENTS: | |
3854 case FAST_ELEMENTS: | 3861 case FAST_ELEMENTS: |
3855 case FAST_DOUBLE_ELEMENTS: | 3862 case FAST_DOUBLE_ELEMENTS: |
3856 break; | 3863 break; |
3857 case EXTERNAL_PIXEL_ELEMENTS: | 3864 case EXTERNAL_PIXEL_ELEMENTS: |
3858 case EXTERNAL_BYTE_ELEMENTS: | 3865 case EXTERNAL_BYTE_ELEMENTS: |
3859 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3866 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3860 case EXTERNAL_SHORT_ELEMENTS: | 3867 case EXTERNAL_SHORT_ELEMENTS: |
3861 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3868 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3862 case EXTERNAL_INT_ELEMENTS: | 3869 case EXTERNAL_INT_ELEMENTS: |
3863 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3870 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
(...skipping 3388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7252 for (int i = 0; i < source->Capacity(); ++i) { | 7259 for (int i = 0; i < source->Capacity(); ++i) { |
7253 Object* key = source->KeyAt(i); | 7260 Object* key = source->KeyAt(i); |
7254 if (key->IsNumber()) { | 7261 if (key->IsNumber()) { |
7255 uint32_t entry = static_cast<uint32_t>(key->Number()); | 7262 uint32_t entry = static_cast<uint32_t>(key->Number()); |
7256 destination->set(entry, source->ValueAt(i), mode); | 7263 destination->set(entry, source->ValueAt(i), mode); |
7257 } | 7264 } |
7258 } | 7265 } |
7259 } | 7266 } |
7260 | 7267 |
7261 | 7268 |
7262 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, | 7269 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
7263 int length) { | 7270 int capacity, |
7271 int length, | |
7272 SetFastElementsCapacityMode set_capacity_mode) { | |
7264 Heap* heap = GetHeap(); | 7273 Heap* heap = GetHeap(); |
7265 // We should never end in here with a pixel or external array. | 7274 // We should never end in here with a pixel or external array. |
7266 ASSERT(!HasExternalArrayElements()); | 7275 ASSERT(!HasExternalArrayElements()); |
7267 | 7276 |
7268 // Allocate a new fast elements backing store. | 7277 // Allocate a new fast elements backing store. |
7269 FixedArray* new_elements = NULL; | 7278 FixedArray* new_elements = NULL; |
7270 { Object* object; | 7279 { Object* object; |
7271 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); | 7280 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); |
7272 if (!maybe->ToObject(&object)) return maybe; | 7281 if (!maybe->ToObject(&object)) return maybe; |
7273 new_elements = FixedArray::cast(object); | 7282 new_elements = FixedArray::cast(object); |
7274 } | 7283 } |
7275 | 7284 |
7276 // Find the new map to use for this object if there is a map change. | 7285 // Find the new map to use for this object if there is a map change. |
7277 Map* new_map = NULL; | 7286 Map* new_map = NULL; |
7278 if (elements()->map() != heap->non_strict_arguments_elements_map()) { | 7287 if (elements()->map() != heap->non_strict_arguments_elements_map()) { |
7279 Object* object; | 7288 Object* object; |
7280 MaybeObject* maybe = GetElementsTransitionMap(FAST_ELEMENTS); | 7289 bool has_fast_smi_only_elements = |
7290 FLAG_smi_only_arrays && | |
7291 (set_capacity_mode == kAllowSmiOnlyElements) && | |
7292 (elements()->map()->has_fast_smi_only_elements() || | |
7293 elements() == heap->empty_fixed_array()); | |
7294 ElementsKind elements_kind = has_fast_smi_only_elements | |
7295 ? FAST_SMI_ONLY_ELEMENTS | |
7296 : FAST_ELEMENTS; | |
7297 MaybeObject* maybe = GetElementsTransitionMap(elements_kind); | |
7281 if (!maybe->ToObject(&object)) return maybe; | 7298 if (!maybe->ToObject(&object)) return maybe; |
7282 new_map = Map::cast(object); | 7299 new_map = Map::cast(object); |
7283 } | 7300 } |
7284 | 7301 |
7285 switch (GetElementsKind()) { | 7302 ElementsKind elements_kind = GetElementsKind(); |
7303 switch (elements_kind) { | |
7304 case FAST_SMI_ONLY_ELEMENTS: | |
7286 case FAST_ELEMENTS: { | 7305 case FAST_ELEMENTS: { |
7287 AssertNoAllocation no_gc; | 7306 AssertNoAllocation no_gc; |
7288 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | 7307 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); |
7289 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); | 7308 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); |
7290 set_map(new_map); | 7309 set_map(new_map); |
7291 set_elements(new_elements); | 7310 set_elements(new_elements); |
7292 break; | 7311 break; |
7293 } | 7312 } |
7294 case DICTIONARY_ELEMENTS: { | 7313 case DICTIONARY_ELEMENTS: { |
7295 AssertNoAllocation no_gc; | 7314 AssertNoAllocation no_gc; |
7296 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | 7315 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
7297 CopySlowElementsToFast(NumberDictionary::cast(elements()), | 7316 CopySlowElementsToFast(NumberDictionary::cast(elements()), |
7298 new_elements, | 7317 new_elements, |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7381 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); | 7400 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); |
7382 | 7401 |
7383 { MaybeObject* maybe_obj = | 7402 { MaybeObject* maybe_obj = |
7384 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS); | 7403 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS); |
7385 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7404 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7386 } | 7405 } |
7387 Map* new_map = Map::cast(obj); | 7406 Map* new_map = Map::cast(obj); |
7388 | 7407 |
7389 AssertNoAllocation no_gc; | 7408 AssertNoAllocation no_gc; |
7390 switch (GetElementsKind()) { | 7409 switch (GetElementsKind()) { |
7410 case FAST_SMI_ONLY_ELEMENTS: | |
7391 case FAST_ELEMENTS: { | 7411 case FAST_ELEMENTS: { |
7392 elems->Initialize(FixedArray::cast(elements())); | 7412 elems->Initialize(FixedArray::cast(elements())); |
7393 break; | 7413 break; |
7394 } | 7414 } |
7395 case FAST_DOUBLE_ELEMENTS: { | 7415 case FAST_DOUBLE_ELEMENTS: { |
7396 elems->Initialize(FixedDoubleArray::cast(elements())); | 7416 elems->Initialize(FixedDoubleArray::cast(elements())); |
7397 break; | 7417 break; |
7398 } | 7418 } |
7399 case DICTIONARY_ELEMENTS: { | 7419 case DICTIONARY_ELEMENTS: { |
7400 elems->Initialize(NumberDictionary::cast(elements())); | 7420 elems->Initialize(NumberDictionary::cast(elements())); |
(...skipping 17 matching lines...) Expand all Loading... | |
7418 } | 7438 } |
7419 | 7439 |
7420 | 7440 |
7421 MaybeObject* JSObject::SetSlowElements(Object* len) { | 7441 MaybeObject* JSObject::SetSlowElements(Object* len) { |
7422 // We should never end in here with a pixel or external array. | 7442 // We should never end in here with a pixel or external array. |
7423 ASSERT(!HasExternalArrayElements()); | 7443 ASSERT(!HasExternalArrayElements()); |
7424 | 7444 |
7425 uint32_t new_length = static_cast<uint32_t>(len->Number()); | 7445 uint32_t new_length = static_cast<uint32_t>(len->Number()); |
7426 | 7446 |
7427 switch (GetElementsKind()) { | 7447 switch (GetElementsKind()) { |
7428 case FAST_ELEMENTS: { | 7448 case FAST_SMI_ONLY_ELEMENTS: |
7429 case FAST_DOUBLE_ELEMENTS: | 7449 case FAST_ELEMENTS: |
7450 case FAST_DOUBLE_ELEMENTS: { | |
7430 // Make sure we never try to shrink dense arrays into sparse arrays. | 7451 // Make sure we never try to shrink dense arrays into sparse arrays. |
7431 ASSERT(static_cast<uint32_t>( | 7452 ASSERT(static_cast<uint32_t>( |
7432 FixedArrayBase::cast(elements())->length()) <= new_length); | 7453 FixedArrayBase::cast(elements())->length()) <= new_length); |
7433 MaybeObject* result = NormalizeElements(); | 7454 MaybeObject* result = NormalizeElements(); |
7434 if (result->IsFailure()) return result; | 7455 if (result->IsFailure()) return result; |
7435 | 7456 |
7436 // Update length for JSArrays. | 7457 // Update length for JSArrays. |
7437 if (IsJSArray()) JSArray::cast(this)->set_length(len); | 7458 if (IsJSArray()) JSArray::cast(this)->set_length(len); |
7438 break; | 7459 break; |
7439 } | 7460 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7485 | 7506 |
7486 | 7507 |
7487 void JSArray::Expand(int required_size) { | 7508 void JSArray::Expand(int required_size) { |
7488 Handle<JSArray> self(this); | 7509 Handle<JSArray> self(this); |
7489 Handle<FixedArray> old_backing(FixedArray::cast(elements())); | 7510 Handle<FixedArray> old_backing(FixedArray::cast(elements())); |
7490 int old_size = old_backing->length(); | 7511 int old_size = old_backing->length(); |
7491 int new_size = required_size > old_size ? required_size : old_size; | 7512 int new_size = required_size > old_size ? required_size : old_size; |
7492 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); | 7513 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); |
7493 // Can't use this any more now because we may have had a GC! | 7514 // Can't use this any more now because we may have had a GC! |
7494 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); | 7515 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); |
7495 self->SetContent(*new_backing); | 7516 GetIsolate()->factory()->SetContent(self, new_backing); |
7496 } | 7517 } |
7497 | 7518 |
7498 | 7519 |
7499 static Failure* ArrayLengthRangeError(Heap* heap) { | 7520 static Failure* ArrayLengthRangeError(Heap* heap) { |
7500 HandleScope scope(heap->isolate()); | 7521 HandleScope scope(heap->isolate()); |
7501 return heap->isolate()->Throw( | 7522 return heap->isolate()->Throw( |
7502 *FACTORY->NewRangeError("invalid_array_length", | 7523 *FACTORY->NewRangeError("invalid_array_length", |
7503 HandleVector<Object>(NULL, 0))); | 7524 HandleVector<Object>(NULL, 0))); |
7504 } | 7525 } |
7505 | 7526 |
7506 | 7527 |
7507 MaybeObject* JSObject::SetElementsLength(Object* len) { | 7528 MaybeObject* JSObject::SetElementsLength(Object* len) { |
7508 // We should never end in here with a pixel or external array. | 7529 // We should never end in here with a pixel or external array. |
7509 ASSERT(AllowsSetElementsLength()); | 7530 ASSERT(AllowsSetElementsLength()); |
7510 | 7531 |
7511 MaybeObject* maybe_smi_length = len->ToSmi(); | 7532 MaybeObject* maybe_smi_length = len->ToSmi(); |
7512 Object* smi_length = Smi::FromInt(0); | 7533 Object* smi_length = Smi::FromInt(0); |
7513 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { | 7534 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { |
7514 const int value = Smi::cast(smi_length)->value(); | 7535 const int value = Smi::cast(smi_length)->value(); |
7515 if (value < 0) return ArrayLengthRangeError(GetHeap()); | 7536 if (value < 0) return ArrayLengthRangeError(GetHeap()); |
7516 ElementsKind elements_kind = GetElementsKind(); | 7537 ElementsKind elements_kind = GetElementsKind(); |
7517 switch (elements_kind) { | 7538 switch (elements_kind) { |
7539 case FAST_SMI_ONLY_ELEMENTS: | |
7518 case FAST_ELEMENTS: | 7540 case FAST_ELEMENTS: |
7519 case FAST_DOUBLE_ELEMENTS: { | 7541 case FAST_DOUBLE_ELEMENTS: { |
7520 int old_capacity = FixedArrayBase::cast(elements())->length(); | 7542 int old_capacity = FixedArrayBase::cast(elements())->length(); |
7521 if (value <= old_capacity) { | 7543 if (value <= old_capacity) { |
7522 if (IsJSArray()) { | 7544 if (IsJSArray()) { |
7523 Object* obj; | 7545 Object* obj; |
7524 if (elements_kind == FAST_ELEMENTS) { | 7546 if (elements_kind != FAST_DOUBLE_ELEMENTS) { |
7547 ASSERT(elements_kind == FAST_ELEMENTS || | |
7548 elements_kind == FAST_SMI_ONLY_ELEMENTS); | |
7525 MaybeObject* maybe_obj = EnsureWritableFastElements(); | 7549 MaybeObject* maybe_obj = EnsureWritableFastElements(); |
7526 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7550 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7527 } | 7551 } |
7528 if (2 * value <= old_capacity) { | 7552 if (2 * value <= old_capacity) { |
7529 // If more than half the elements won't be used, trim the array. | 7553 // If more than half the elements won't be used, trim the array. |
7530 if (value == 0) { | 7554 if (value == 0) { |
7531 initialize_elements(); | 7555 initialize_elements(); |
7532 } else { | 7556 } else { |
7533 Address filler_start; | 7557 Address filler_start; |
7534 int filler_size; | 7558 int filler_size; |
7535 if (GetElementsKind() == FAST_ELEMENTS) { | 7559 if (elements_kind == FAST_ELEMENTS || |
7560 elements_kind == FAST_SMI_ONLY_ELEMENTS) { | |
7536 FixedArray* fast_elements = FixedArray::cast(elements()); | 7561 FixedArray* fast_elements = FixedArray::cast(elements()); |
7537 fast_elements->set_length(value); | 7562 fast_elements->set_length(value); |
7538 filler_start = fast_elements->address() + | 7563 filler_start = fast_elements->address() + |
7539 FixedArray::OffsetOfElementAt(value); | 7564 FixedArray::OffsetOfElementAt(value); |
7540 filler_size = (old_capacity - value) * kPointerSize; | 7565 filler_size = (old_capacity - value) * kPointerSize; |
7541 } else { | 7566 } else { |
7542 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); | 7567 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); |
7543 FixedDoubleArray* fast_double_elements = | 7568 FixedDoubleArray* fast_double_elements = |
7544 FixedDoubleArray::cast(elements()); | 7569 FixedDoubleArray::cast(elements()); |
7545 fast_double_elements->set_length(value); | 7570 fast_double_elements->set_length(value); |
7546 filler_start = fast_double_elements->address() + | 7571 filler_start = fast_double_elements->address() + |
7547 FixedDoubleArray::OffsetOfElementAt(value); | 7572 FixedDoubleArray::OffsetOfElementAt(value); |
7548 filler_size = (old_capacity - value) * kDoubleSize; | 7573 filler_size = (old_capacity - value) * kDoubleSize; |
7549 } | 7574 } |
7550 GetHeap()->CreateFillerObjectAt(filler_start, filler_size); | 7575 GetHeap()->CreateFillerObjectAt(filler_start, filler_size); |
7551 } | 7576 } |
7552 } else { | 7577 } else { |
7553 // Otherwise, fill the unused tail with holes. | 7578 // Otherwise, fill the unused tail with holes. |
7554 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); | 7579 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); |
7555 if (GetElementsKind() == FAST_ELEMENTS) { | 7580 if (elements_kind == FAST_ELEMENTS || |
7581 elements_kind == FAST_SMI_ONLY_ELEMENTS) { | |
7556 FixedArray* fast_elements = FixedArray::cast(elements()); | 7582 FixedArray* fast_elements = FixedArray::cast(elements()); |
7557 for (int i = value; i < old_length; i++) { | 7583 for (int i = value; i < old_length; i++) { |
7558 fast_elements->set_the_hole(i); | 7584 fast_elements->set_the_hole(i); |
7559 } | 7585 } |
7560 } else { | 7586 } else { |
7561 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); | 7587 ASSERT(elements_kind == FAST_DOUBLE_ELEMENTS); |
7562 FixedDoubleArray* fast_double_elements = | 7588 FixedDoubleArray* fast_double_elements = |
7563 FixedDoubleArray::cast(elements()); | 7589 FixedDoubleArray::cast(elements()); |
7564 for (int i = value; i < old_length; i++) { | 7590 for (int i = value; i < old_length; i++) { |
7565 fast_double_elements->set_the_hole(i); | 7591 fast_double_elements->set_the_hole(i); |
7566 } | 7592 } |
7567 } | 7593 } |
7568 } | 7594 } |
7569 JSArray::cast(this)->set_length(Smi::cast(smi_length)); | 7595 JSArray::cast(this)->set_length(Smi::cast(smi_length)); |
7570 } | 7596 } |
7571 return this; | 7597 return this; |
7572 } | 7598 } |
7573 int min = NewElementsCapacity(old_capacity); | 7599 int min = NewElementsCapacity(old_capacity); |
7574 int new_capacity = value > min ? value : min; | 7600 int new_capacity = value > min ? value : min; |
7575 if (!ShouldConvertToSlowElements(new_capacity)) { | 7601 if (!ShouldConvertToSlowElements(new_capacity)) { |
7576 MaybeObject* result; | 7602 MaybeObject* result; |
7577 if (GetElementsKind() == FAST_ELEMENTS) { | 7603 if (elements_kind == FAST_ELEMENTS || |
7578 result = SetFastElementsCapacityAndLength(new_capacity, value); | 7604 elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
7605 SetFastElementsCapacityMode set_capacity_mode = | |
7606 elements_kind == FAST_SMI_ONLY_ELEMENTS | |
7607 ? kAllowSmiOnlyElements | |
7608 : kDontAllowSmiOnlyElements; | |
7609 result = SetFastElementsCapacityAndLength(new_capacity, | |
7610 value, | |
7611 set_capacity_mode); | |
7579 } else { | 7612 } else { |
7580 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); | 7613 ASSERT(elements_kind == FAST_DOUBLE_ELEMENTS); |
7581 result = SetFastDoubleElementsCapacityAndLength(new_capacity, | 7614 result = SetFastDoubleElementsCapacityAndLength(new_capacity, |
7582 value); | 7615 value); |
7583 } | 7616 } |
7584 if (result->IsFailure()) return result; | 7617 if (result->IsFailure()) return result; |
7585 return this; | 7618 return this; |
7586 } | 7619 } |
7587 break; | 7620 break; |
7588 } | 7621 } |
7589 case DICTIONARY_ELEMENTS: { | 7622 case DICTIONARY_ELEMENTS: { |
7590 if (IsJSArray()) { | 7623 if (IsJSArray()) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7627 if (len->ToArrayIndex(&length)) { | 7660 if (len->ToArrayIndex(&length)) { |
7628 return SetSlowElements(len); | 7661 return SetSlowElements(len); |
7629 } else { | 7662 } else { |
7630 return ArrayLengthRangeError(GetHeap()); | 7663 return ArrayLengthRangeError(GetHeap()); |
7631 } | 7664 } |
7632 } | 7665 } |
7633 | 7666 |
7634 // len is not a number so make the array size one and | 7667 // len is not a number so make the array size one and |
7635 // set only element to len. | 7668 // set only element to len. |
7636 Object* obj; | 7669 Object* obj; |
7637 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1); | 7670 MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1); |
7638 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7671 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7639 } | |
7640 FixedArray::cast(obj)->set(0, len); | 7672 FixedArray::cast(obj)->set(0, len); |
7673 | |
7674 maybe_obj = EnsureCanContainElements(&len, 1); | |
7675 if (maybe_obj->IsFailure()) return maybe_obj; | |
7676 | |
7641 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); | 7677 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); |
7642 set_elements(FixedArray::cast(obj)); | 7678 set_elements(FixedArray::cast(obj)); |
7643 return this; | 7679 return this; |
7644 } | 7680 } |
7645 | 7681 |
7646 | 7682 |
7647 Object* Map::GetPrototypeTransition(Object* prototype) { | 7683 Object* Map::GetPrototypeTransition(Object* prototype) { |
7648 FixedArray* cache = prototype_transitions(); | 7684 FixedArray* cache = prototype_transitions(); |
7649 int number_of_transitions = NumberOfProtoTransitions(); | 7685 int number_of_transitions = NumberOfProtoTransitions(); |
7650 const int proto_offset = | 7686 const int proto_offset = |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7778 } | 7814 } |
7779 ASSERT(Map::cast(new_map)->prototype() == value); | 7815 ASSERT(Map::cast(new_map)->prototype() == value); |
7780 real_receiver->set_map(Map::cast(new_map)); | 7816 real_receiver->set_map(Map::cast(new_map)); |
7781 | 7817 |
7782 heap->ClearInstanceofCache(); | 7818 heap->ClearInstanceofCache(); |
7783 ASSERT(size == Size()); | 7819 ASSERT(size == Size()); |
7784 return value; | 7820 return value; |
7785 } | 7821 } |
7786 | 7822 |
7787 | 7823 |
7824 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args, | |
7825 uint32_t first_arg, | |
7826 uint32_t arg_count) { | |
7827 return EnsureCanContainElements(args->arguments() - first_arg, arg_count); | |
7828 } | |
7829 | |
7830 | |
7788 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { | 7831 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { |
7789 switch (GetElementsKind()) { | 7832 switch (GetElementsKind()) { |
7833 case FAST_SMI_ONLY_ELEMENTS: | |
7790 case FAST_ELEMENTS: { | 7834 case FAST_ELEMENTS: { |
7791 uint32_t length = IsJSArray() ? | 7835 uint32_t length = IsJSArray() ? |
7792 static_cast<uint32_t> | 7836 static_cast<uint32_t> |
7793 (Smi::cast(JSArray::cast(this)->length())->value()) : | 7837 (Smi::cast(JSArray::cast(this)->length())->value()) : |
7794 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 7838 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
7795 if ((index < length) && | 7839 if ((index < length) && |
7796 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | 7840 !FixedArray::cast(elements())->get(index)->IsTheHole()) { |
7797 return true; | 7841 return true; |
7798 } | 7842 } |
7799 break; | 7843 break; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7916 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT | 7960 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT |
7917 : UNDEFINED_ELEMENT; | 7961 : UNDEFINED_ELEMENT; |
7918 } | 7962 } |
7919 | 7963 |
7920 // Handle [] on String objects. | 7964 // Handle [] on String objects. |
7921 if (this->IsStringObjectWithCharacterAt(index)) { | 7965 if (this->IsStringObjectWithCharacterAt(index)) { |
7922 return STRING_CHARACTER_ELEMENT; | 7966 return STRING_CHARACTER_ELEMENT; |
7923 } | 7967 } |
7924 | 7968 |
7925 switch (GetElementsKind()) { | 7969 switch (GetElementsKind()) { |
7970 case FAST_SMI_ONLY_ELEMENTS: | |
7926 case FAST_ELEMENTS: { | 7971 case FAST_ELEMENTS: { |
7927 uint32_t length = IsJSArray() ? | 7972 uint32_t length = IsJSArray() ? |
7928 static_cast<uint32_t> | 7973 static_cast<uint32_t> |
7929 (Smi::cast(JSArray::cast(this)->length())->value()) : | 7974 (Smi::cast(JSArray::cast(this)->length())->value()) : |
7930 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 7975 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
7931 if ((index < length) && | 7976 if ((index < length) && |
7932 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | 7977 !FixedArray::cast(elements())->get(index)->IsTheHole()) { |
7933 return FAST_ELEMENT; | 7978 return FAST_ELEMENT; |
7934 } | 7979 } |
7935 break; | 7980 break; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8030 } | 8075 } |
8031 } | 8076 } |
8032 | 8077 |
8033 // Check for lookup interceptor | 8078 // Check for lookup interceptor |
8034 if (HasIndexedInterceptor()) { | 8079 if (HasIndexedInterceptor()) { |
8035 return HasElementWithInterceptor(receiver, index); | 8080 return HasElementWithInterceptor(receiver, index); |
8036 } | 8081 } |
8037 | 8082 |
8038 ElementsKind kind = GetElementsKind(); | 8083 ElementsKind kind = GetElementsKind(); |
8039 switch (kind) { | 8084 switch (kind) { |
8085 case FAST_SMI_ONLY_ELEMENTS: | |
8040 case FAST_ELEMENTS: { | 8086 case FAST_ELEMENTS: { |
8041 uint32_t length = IsJSArray() ? | 8087 uint32_t length = IsJSArray() ? |
8042 static_cast<uint32_t> | 8088 static_cast<uint32_t> |
8043 (Smi::cast(JSArray::cast(this)->length())->value()) : | 8089 (Smi::cast(JSArray::cast(this)->length())->value()) : |
8044 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 8090 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
8045 if ((index < length) && | 8091 if ((index < length) && |
8046 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; | 8092 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; |
8047 break; | 8093 break; |
8048 } | 8094 } |
8049 case FAST_DOUBLE_ELEMENTS: { | 8095 case FAST_DOUBLE_ELEMENTS: { |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8276 return false; | 8322 return false; |
8277 } | 8323 } |
8278 FixedArray* arguments = FixedArray::cast(elements->get(1)); | 8324 FixedArray* arguments = FixedArray::cast(elements->get(1)); |
8279 return arguments->IsDictionary(); | 8325 return arguments->IsDictionary(); |
8280 } | 8326 } |
8281 | 8327 |
8282 | 8328 |
8283 // Adding n elements in fast case is O(n*n). | 8329 // Adding n elements in fast case is O(n*n). |
8284 // Note: revisit design to have dual undefined values to capture absent | 8330 // Note: revisit design to have dual undefined values to capture absent |
8285 // elements. | 8331 // elements. |
8286 MaybeObject* JSObject::SetFastElement(uint32_t index, | 8332 MaybeObject* JSObject::SetFastElement( |
8287 Object* value, | 8333 uint32_t index, |
Jakob Kummerow
2011/09/16 16:30:34
Why the new line break?
danno
2011/09/21 14:32:04
Done.
| |
8288 StrictModeFlag strict_mode, | 8334 Object* value, |
8289 bool check_prototype) { | 8335 StrictModeFlag strict_mode, |
8290 ASSERT(HasFastElements() || HasFastArgumentsElements()); | 8336 bool check_prototype) { |
8337 ASSERT(HasFastElements() || | |
8338 HasFastSmiOnlyElements() || | |
8339 HasFastArgumentsElements()); | |
8291 | 8340 |
8292 FixedArray* backing_store = FixedArray::cast(elements()); | 8341 FixedArray* backing_store = FixedArray::cast(elements()); |
8293 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { | 8342 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { |
8294 backing_store = FixedArray::cast(backing_store->get(1)); | 8343 backing_store = FixedArray::cast(backing_store->get(1)); |
8295 } else { | 8344 } else { |
8296 Object* writable; | 8345 Object* writable; |
8297 MaybeObject* maybe = EnsureWritableFastElements(); | 8346 MaybeObject* maybe = EnsureWritableFastElements(); |
8298 if (!maybe->ToObject(&writable)) return maybe; | 8347 if (!maybe->ToObject(&writable)) return maybe; |
8299 backing_store = FixedArray::cast(writable); | 8348 backing_store = FixedArray::cast(writable); |
8300 } | 8349 } |
8301 uint32_t length = static_cast<uint32_t>(backing_store->length()); | 8350 uint32_t length = static_cast<uint32_t>(backing_store->length()); |
8302 | 8351 |
8303 if (check_prototype && | 8352 if (check_prototype && |
8304 (index >= length || backing_store->get(index)->IsTheHole())) { | 8353 (index >= length || backing_store->get(index)->IsTheHole())) { |
8305 bool found; | 8354 bool found; |
8306 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 8355 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, |
8307 value, | 8356 value, |
8308 &found, | 8357 &found, |
8309 strict_mode); | 8358 strict_mode); |
8310 if (found) return result; | 8359 if (found) return result; |
8311 } | 8360 } |
8312 | 8361 |
8313 // Check whether there is extra space in fixed array. | 8362 // Check whether there is extra space in fixed array. |
8314 if (index < length) { | 8363 if (index < length) { |
8364 if (HasFastSmiOnlyElements()) { | |
8365 if (!value->IsSmi()) { | |
8366 // If the value is a number, transition from smi-only to | |
8367 // FastDoubleElements | |
Jakob Kummerow
2011/09/16 16:30:34
nit: missing period
danno
2011/09/21 14:32:04
Done.
| |
8368 if (value->IsNumber()) { | |
8369 MaybeObject* maybe = | |
8370 SetFastDoubleElementsCapacityAndLength(length, length); | |
8371 if (maybe->IsFailure()) return maybe; | |
8372 FixedDoubleArray::cast(elements())->set(index, value->Number()); | |
8373 return value; | |
8374 } | |
8375 // Value is not a number, transition to generic fast elements. | |
8376 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS); | |
8377 Map* new_map; | |
8378 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; | |
8379 set_map(new_map); | |
8380 } | |
8381 } | |
8315 backing_store->set(index, value); | 8382 backing_store->set(index, value); |
8316 if (IsJSArray()) { | 8383 if (IsJSArray()) { |
8317 // Update the length of the array if needed. | 8384 // Update the length of the array if needed. |
8318 uint32_t array_length = 0; | 8385 uint32_t array_length = 0; |
8319 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 8386 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); |
8320 if (index >= array_length) { | 8387 if (index >= array_length) { |
8321 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 8388 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); |
8322 } | 8389 } |
8323 } | 8390 } |
8324 return value; | 8391 return value; |
8325 } | 8392 } |
8326 | 8393 |
8327 // Allow gap in fast case. | 8394 // Allow gap in fast case. |
8328 if ((index - length) < kMaxGap) { | 8395 if ((index - length) < kMaxGap) { |
8329 // Try allocating extra space. | 8396 // Try allocating extra space. |
8330 int new_capacity = NewElementsCapacity(index + 1); | 8397 int new_capacity = NewElementsCapacity(index + 1); |
8331 if (!ShouldConvertToSlowElements(new_capacity)) { | 8398 if (!ShouldConvertToSlowElements(new_capacity)) { |
8332 ASSERT(static_cast<uint32_t>(new_capacity) > index); | 8399 ASSERT(static_cast<uint32_t>(new_capacity) > index); |
8333 Object* new_elements; | 8400 Object* new_elements; |
8401 SetFastElementsCapacityMode set_capacity_mode = | |
8402 value->IsSmi() && HasFastSmiOnlyElements() | |
8403 ? kAllowSmiOnlyElements | |
8404 : kDontAllowSmiOnlyElements; | |
8334 MaybeObject* maybe = | 8405 MaybeObject* maybe = |
8335 SetFastElementsCapacityAndLength(new_capacity, index + 1); | 8406 SetFastElementsCapacityAndLength(new_capacity, |
8407 index + 1, | |
8408 set_capacity_mode); | |
8336 if (!maybe->ToObject(&new_elements)) return maybe; | 8409 if (!maybe->ToObject(&new_elements)) return maybe; |
8337 FixedArray::cast(new_elements)->set(index, value); | 8410 FixedArray::cast(new_elements)->set(index, value); |
8338 return value; | 8411 return value; |
8339 } | 8412 } |
8340 } | 8413 } |
8341 | 8414 |
8342 // Otherwise default to slow case. | 8415 // Otherwise default to slow case. |
8343 MaybeObject* result = NormalizeElements(); | 8416 MaybeObject* result = NormalizeElements(); |
8344 if (result->IsFailure()) return result; | 8417 if (result->IsFailure()) return result; |
8345 return SetDictionaryElement(index, value, strict_mode, check_prototype); | 8418 return SetDictionaryElement(index, value, strict_mode, check_prototype); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8431 // Attempt to put this object back in fast case. | 8504 // Attempt to put this object back in fast case. |
8432 if (ShouldConvertToFastElements()) { | 8505 if (ShouldConvertToFastElements()) { |
8433 uint32_t new_length = 0; | 8506 uint32_t new_length = 0; |
8434 if (IsJSArray()) { | 8507 if (IsJSArray()) { |
8435 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); | 8508 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); |
8436 } else { | 8509 } else { |
8437 new_length = dictionary->max_number_key() + 1; | 8510 new_length = dictionary->max_number_key() + 1; |
8438 } | 8511 } |
8439 MaybeObject* result = CanConvertToFastDoubleElements() | 8512 MaybeObject* result = CanConvertToFastDoubleElements() |
8440 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) | 8513 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) |
8441 : SetFastElementsCapacityAndLength(new_length, new_length); | 8514 : SetFastElementsCapacityAndLength(new_length, |
8515 new_length, | |
8516 kDontAllowSmiOnlyElements); | |
8442 if (result->IsFailure()) return result; | 8517 if (result->IsFailure()) return result; |
8443 #ifdef DEBUG | 8518 #ifdef DEBUG |
8444 if (FLAG_trace_normalization) { | 8519 if (FLAG_trace_normalization) { |
8445 PrintF("Object elements are fast case again:\n"); | 8520 PrintF("Object elements are fast case again:\n"); |
8446 Print(); | 8521 Print(); |
8447 } | 8522 } |
8448 #endif | 8523 #endif |
8449 } | 8524 } |
8450 return value; | 8525 return value; |
8451 } | 8526 } |
(...skipping 23 matching lines...) Expand all Loading... | |
8475 | 8550 |
8476 // If the value object is not a heap number, switch to fast elements and try | 8551 // If the value object is not a heap number, switch to fast elements and try |
8477 // again. | 8552 // again. |
8478 bool value_is_smi = value->IsSmi(); | 8553 bool value_is_smi = value->IsSmi(); |
8479 if (!value->IsNumber()) { | 8554 if (!value->IsNumber()) { |
8480 Object* obj; | 8555 Object* obj; |
8481 uint32_t length = elms_length; | 8556 uint32_t length = elms_length; |
8482 if (IsJSArray()) { | 8557 if (IsJSArray()) { |
8483 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); | 8558 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); |
8484 } | 8559 } |
8485 MaybeObject* maybe_obj = | 8560 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength( |
8486 SetFastElementsCapacityAndLength(elms_length, length); | 8561 elms_length, |
8562 length, | |
8563 kDontAllowSmiOnlyElements); | |
8487 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8564 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
8488 return SetFastElement(index, value, strict_mode, check_prototype); | 8565 return SetFastElement(index, |
Jakob Kummerow
2011/09/16 16:30:34
Why the line breaks?
| |
8566 value, | |
8567 strict_mode, | |
8568 check_prototype); | |
8489 } | 8569 } |
8490 | 8570 |
8491 double double_value = value_is_smi | 8571 double double_value = value_is_smi |
8492 ? static_cast<double>(Smi::cast(value)->value()) | 8572 ? static_cast<double>(Smi::cast(value)->value()) |
8493 : HeapNumber::cast(value)->value(); | 8573 : HeapNumber::cast(value)->value(); |
8494 | 8574 |
8495 // Check whether there is extra space in the fixed array. | 8575 // Check whether there is extra space in the fixed array. |
8496 if (index < elms_length) { | 8576 if (index < elms_length) { |
8497 elms->set(index, double_value); | 8577 elms->set(index, double_value); |
8498 if (IsJSArray()) { | 8578 if (IsJSArray()) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8575 check_prototype); | 8655 check_prototype); |
8576 } | 8656 } |
8577 | 8657 |
8578 | 8658 |
8579 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 8659 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
8580 Object* value, | 8660 Object* value, |
8581 StrictModeFlag strict_mode, | 8661 StrictModeFlag strict_mode, |
8582 bool check_prototype) { | 8662 bool check_prototype) { |
8583 Isolate* isolate = GetIsolate(); | 8663 Isolate* isolate = GetIsolate(); |
8584 switch (GetElementsKind()) { | 8664 switch (GetElementsKind()) { |
8665 case FAST_SMI_ONLY_ELEMENTS: | |
8585 case FAST_ELEMENTS: | 8666 case FAST_ELEMENTS: |
8586 return SetFastElement(index, value, strict_mode, check_prototype); | 8667 return SetFastElement(index, value, strict_mode, check_prototype); |
8587 case FAST_DOUBLE_ELEMENTS: | 8668 case FAST_DOUBLE_ELEMENTS: |
8588 return SetFastDoubleElement(index, value, strict_mode, check_prototype); | 8669 return SetFastDoubleElement(index, value, strict_mode, check_prototype); |
8589 case EXTERNAL_PIXEL_ELEMENTS: { | 8670 case EXTERNAL_PIXEL_ELEMENTS: { |
8590 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 8671 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
8591 return pixels->SetValue(index, value); | 8672 return pixels->SetValue(index, value); |
8592 } | 8673 } |
8593 case EXTERNAL_BYTE_ELEMENTS: { | 8674 case EXTERNAL_BYTE_ELEMENTS: { |
8594 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 8675 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8737 backing_store_base = | 8818 backing_store_base = |
8738 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); | 8819 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); |
8739 backing_store = FixedArray::cast(backing_store_base); | 8820 backing_store = FixedArray::cast(backing_store_base); |
8740 if (backing_store->IsDictionary()) { | 8821 if (backing_store->IsDictionary()) { |
8741 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); | 8822 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); |
8742 *capacity = dictionary->Capacity(); | 8823 *capacity = dictionary->Capacity(); |
8743 *used = dictionary->NumberOfElements(); | 8824 *used = dictionary->NumberOfElements(); |
8744 break; | 8825 break; |
8745 } | 8826 } |
8746 // Fall through. | 8827 // Fall through. |
8828 case FAST_SMI_ONLY_ELEMENTS: | |
8747 case FAST_ELEMENTS: | 8829 case FAST_ELEMENTS: |
8748 backing_store = FixedArray::cast(backing_store_base); | 8830 backing_store = FixedArray::cast(backing_store_base); |
8749 *capacity = backing_store->length(); | 8831 *capacity = backing_store->length(); |
8750 for (int i = 0; i < *capacity; ++i) { | 8832 for (int i = 0; i < *capacity; ++i) { |
8751 if (!backing_store->get(i)->IsTheHole()) ++(*used); | 8833 if (!backing_store->get(i)->IsTheHole()) ++(*used); |
8752 } | 8834 } |
8753 break; | 8835 break; |
8754 case DICTIONARY_ELEMENTS: { | 8836 case DICTIONARY_ELEMENTS: { |
8755 NumberDictionary* dictionary = | 8837 NumberDictionary* dictionary = |
8756 NumberDictionary::cast(FixedArray::cast(elements())); | 8838 NumberDictionary::cast(FixedArray::cast(elements())); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9012 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 9094 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
9013 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 9095 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
9014 return false; | 9096 return false; |
9015 } | 9097 } |
9016 } | 9098 } |
9017 | 9099 |
9018 // Handle [] on String objects. | 9100 // Handle [] on String objects. |
9019 if (this->IsStringObjectWithCharacterAt(index)) return true; | 9101 if (this->IsStringObjectWithCharacterAt(index)) return true; |
9020 | 9102 |
9021 switch (GetElementsKind()) { | 9103 switch (GetElementsKind()) { |
9104 case FAST_SMI_ONLY_ELEMENTS: | |
9022 case FAST_ELEMENTS: { | 9105 case FAST_ELEMENTS: { |
9023 uint32_t length = IsJSArray() ? | 9106 uint32_t length = IsJSArray() ? |
9024 static_cast<uint32_t>( | 9107 static_cast<uint32_t>( |
9025 Smi::cast(JSArray::cast(this)->length())->value()) : | 9108 Smi::cast(JSArray::cast(this)->length())->value()) : |
9026 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 9109 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
9027 return (index < length) && | 9110 return (index < length) && |
9028 !FixedArray::cast(elements())->get(index)->IsTheHole(); | 9111 !FixedArray::cast(elements())->get(index)->IsTheHole(); |
9029 } | 9112 } |
9030 case FAST_DOUBLE_ELEMENTS: { | 9113 case FAST_DOUBLE_ELEMENTS: { |
9031 uint32_t length = IsJSArray() ? | 9114 uint32_t length = IsJSArray() ? |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9251 } | 9334 } |
9252 // Compute the number of enumerable elements. | 9335 // Compute the number of enumerable elements. |
9253 return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM)); | 9336 return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM)); |
9254 } | 9337 } |
9255 | 9338 |
9256 | 9339 |
9257 int JSObject::GetLocalElementKeys(FixedArray* storage, | 9340 int JSObject::GetLocalElementKeys(FixedArray* storage, |
9258 PropertyAttributes filter) { | 9341 PropertyAttributes filter) { |
9259 int counter = 0; | 9342 int counter = 0; |
9260 switch (GetElementsKind()) { | 9343 switch (GetElementsKind()) { |
9344 case FAST_SMI_ONLY_ELEMENTS: | |
9261 case FAST_ELEMENTS: { | 9345 case FAST_ELEMENTS: { |
9262 int length = IsJSArray() ? | 9346 int length = IsJSArray() ? |
9263 Smi::cast(JSArray::cast(this)->length())->value() : | 9347 Smi::cast(JSArray::cast(this)->length())->value() : |
9264 FixedArray::cast(elements())->length(); | 9348 FixedArray::cast(elements())->length(); |
9265 for (int i = 0; i < length; i++) { | 9349 for (int i = 0; i < length; i++) { |
9266 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { | 9350 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { |
9267 if (storage != NULL) { | 9351 if (storage != NULL) { |
9268 storage->set(counter, Smi::FromInt(i)); | 9352 storage->set(counter, Smi::FromInt(i)); |
9269 } | 9353 } |
9270 counter++; | 9354 counter++; |
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10153 dict->CopyValuesTo(fast_elements); | 10237 dict->CopyValuesTo(fast_elements); |
10154 | 10238 |
10155 set_map(new_map); | 10239 set_map(new_map); |
10156 set_elements(fast_elements); | 10240 set_elements(fast_elements); |
10157 } else if (!HasFastDoubleElements()) { | 10241 } else if (!HasFastDoubleElements()) { |
10158 Object* obj; | 10242 Object* obj; |
10159 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 10243 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
10160 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 10244 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
10161 } | 10245 } |
10162 } | 10246 } |
10163 ASSERT(HasFastElements() || HasFastDoubleElements()); | 10247 ASSERT(HasFastElements() || |
10248 HasFastSmiOnlyElements() || | |
10249 HasFastDoubleElements()); | |
10164 | 10250 |
10165 // Collect holes at the end, undefined before that and the rest at the | 10251 // Collect holes at the end, undefined before that and the rest at the |
10166 // start, and return the number of non-hole, non-undefined values. | 10252 // start, and return the number of non-hole, non-undefined values. |
10167 | 10253 |
10168 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); | 10254 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); |
10169 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); | 10255 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); |
10170 if (limit > elements_length) { | 10256 if (limit > elements_length) { |
10171 limit = elements_length ; | 10257 limit = elements_length ; |
10172 } | 10258 } |
10173 if (limit == 0) { | 10259 if (limit == 0) { |
(...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11588 if (break_point_objects()->IsUndefined()) return 0; | 11674 if (break_point_objects()->IsUndefined()) return 0; |
11589 // Single break point. | 11675 // Single break point. |
11590 if (!break_point_objects()->IsFixedArray()) return 1; | 11676 if (!break_point_objects()->IsFixedArray()) return 1; |
11591 // Multiple break points. | 11677 // Multiple break points. |
11592 return FixedArray::cast(break_point_objects())->length(); | 11678 return FixedArray::cast(break_point_objects())->length(); |
11593 } | 11679 } |
11594 #endif | 11680 #endif |
11595 | 11681 |
11596 | 11682 |
11597 } } // namespace v8::internal | 11683 } } // namespace v8::internal |
OLD | NEW |