OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <iomanip> | 5 #include <iomanip> |
6 #include <sstream> | 6 #include <sstream> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 2405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2416 // Check the state of the root map. | 2416 // Check the state of the root map. |
2417 Handle<Map> root_map(old_map->FindRootMap(), isolate); | 2417 Handle<Map> root_map(old_map->FindRootMap(), isolate); |
2418 if (!old_map->EquivalentToForTransition(*root_map)) { | 2418 if (!old_map->EquivalentToForTransition(*root_map)) { |
2419 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2419 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2420 new_kind, new_attributes, | 2420 new_kind, new_attributes, |
2421 "GenAll_NotEquivalent"); | 2421 "GenAll_NotEquivalent"); |
2422 } | 2422 } |
2423 | 2423 |
2424 ElementsKind from_kind = root_map->elements_kind(); | 2424 ElementsKind from_kind = root_map->elements_kind(); |
2425 ElementsKind to_kind = old_map->elements_kind(); | 2425 ElementsKind to_kind = old_map->elements_kind(); |
| 2426 // TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS. |
2426 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && | 2427 if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS && |
| 2428 to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS && |
2427 !(IsTransitionableFastElementsKind(from_kind) && | 2429 !(IsTransitionableFastElementsKind(from_kind) && |
2428 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { | 2430 IsMoreGeneralElementsKindTransition(from_kind, to_kind))) { |
2429 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2431 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2430 new_kind, new_attributes, | 2432 new_kind, new_attributes, |
2431 "GenAll_InvalidElementsTransition"); | 2433 "GenAll_InvalidElementsTransition"); |
2432 } | 2434 } |
2433 int root_nof = root_map->NumberOfOwnDescriptors(); | 2435 int root_nof = root_map->NumberOfOwnDescriptors(); |
2434 if (modify_index >= 0 && modify_index < root_nof) { | 2436 if (modify_index >= 0 && modify_index < root_nof) { |
2435 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2437 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2436 if (old_details.kind() != new_kind || | 2438 if (old_details.kind() != new_kind || |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3552 Handle<FixedArray> array, | 3554 Handle<FixedArray> array, |
3553 int valid_descriptors) { | 3555 int valid_descriptors) { |
3554 NeanderArray callbacks(descriptors); | 3556 NeanderArray callbacks(descriptors); |
3555 DCHECK(array->length() >= callbacks.length() + valid_descriptors); | 3557 DCHECK(array->length() >= callbacks.length() + valid_descriptors); |
3556 return AppendUniqueCallbacks<FixedArrayAppender>(&callbacks, | 3558 return AppendUniqueCallbacks<FixedArrayAppender>(&callbacks, |
3557 array, | 3559 array, |
3558 valid_descriptors); | 3560 valid_descriptors); |
3559 } | 3561 } |
3560 | 3562 |
3561 | 3563 |
3562 static bool ContainsMap(MapHandleList* maps, Handle<Map> map) { | 3564 static bool ContainsMap(MapHandleList* maps, Map* map) { |
3563 DCHECK(!map.is_null()); | 3565 DCHECK_NOT_NULL(map); |
3564 for (int i = 0; i < maps->length(); ++i) { | 3566 for (int i = 0; i < maps->length(); ++i) { |
3565 if (!maps->at(i).is_null() && maps->at(i).is_identical_to(map)) return true; | 3567 if (!maps->at(i).is_null() && *maps->at(i) == map) return true; |
3566 } | 3568 } |
3567 return false; | 3569 return false; |
3568 } | 3570 } |
3569 | 3571 |
3570 | 3572 |
3571 template <class T> | 3573 Handle<Map> Map::FindTransitionedMap(Handle<Map> map, |
3572 static Handle<T> MaybeNull(T* p) { | 3574 MapHandleList* candidates) { |
3573 if (p == NULL) return Handle<T>::null(); | 3575 ElementsKind kind = map->elements_kind(); |
3574 return Handle<T>(p); | 3576 bool packed = IsFastPackedElementsKind(kind); |
3575 } | |
3576 | 3577 |
3577 | 3578 Map* transition = nullptr; |
3578 Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) { | |
3579 ElementsKind kind = elements_kind(); | |
3580 Handle<Map> transitioned_map = Handle<Map>::null(); | |
3581 Handle<Map> current_map(this); | |
3582 bool packed = IsFastPackedElementsKind(kind); | |
3583 if (IsTransitionableFastElementsKind(kind)) { | 3579 if (IsTransitionableFastElementsKind(kind)) { |
3584 while (CanTransitionToMoreGeneralFastElementsKind(kind, false)) { | 3580 for (Map* current = map->ElementsTransitionMap(); |
3585 kind = GetNextMoreGeneralFastElementsKind(kind, false); | 3581 current != nullptr && current->has_fast_elements(); |
3586 Handle<Map> maybe_transitioned_map = | 3582 current = current->ElementsTransitionMap()) { |
3587 MaybeNull(current_map->LookupElementsTransitionMap(kind)); | 3583 if (ContainsMap(candidates, current) && |
3588 if (maybe_transitioned_map.is_null()) break; | 3584 (packed || !IsFastPackedElementsKind(current->elements_kind()))) { |
3589 if (ContainsMap(candidates, maybe_transitioned_map) && | 3585 transition = current; |
3590 (packed || !IsFastPackedElementsKind(kind))) { | 3586 packed = packed && IsFastPackedElementsKind(current->elements_kind()); |
3591 transitioned_map = maybe_transitioned_map; | |
3592 if (!IsFastPackedElementsKind(kind)) packed = false; | |
3593 } | 3587 } |
3594 current_map = maybe_transitioned_map; | |
3595 } | 3588 } |
3596 } | 3589 } |
3597 return transitioned_map; | 3590 return transition == nullptr ? Handle<Map>() : handle(transition); |
3598 } | 3591 } |
3599 | 3592 |
3600 | 3593 |
3601 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { | 3594 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) { |
3602 Map* current_map = map; | 3595 Map* current_map = map; |
3603 int target_kind = | |
3604 IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind) | |
3605 ? to_kind | |
3606 : TERMINAL_FAST_ELEMENTS_KIND; | |
3607 | 3596 |
3608 // Support for legacy API: SetIndexedPropertiesTo{External,Pixel}Data | 3597 // Support for legacy API: SetIndexedPropertiesTo{External,Pixel}Data |
3609 // allows to change elements from arbitrary kind to any ExternalArray | 3598 // allows to change elements from arbitrary kind to any ExternalArray |
3610 // elements kind. Satisfy its requirements, checking whether we already | 3599 // elements kind. Satisfy its requirements, checking whether we already |
3611 // have the cached transition. | 3600 // have the cached transition. |
3612 if (IsExternalArrayElementsKind(to_kind) && | 3601 if (IsExternalArrayElementsKind(to_kind) && |
3613 !IsFixedTypedArrayElementsKind(map->elements_kind())) { | 3602 !IsFixedTypedArrayElementsKind(map->elements_kind())) { |
3614 Map* next_map = map->ElementsTransitionMap(); | 3603 Map* next_map = map->ElementsTransitionMap(); |
3615 if (next_map != NULL && next_map->elements_kind() == to_kind) { | 3604 if (next_map != NULL && next_map->elements_kind() == to_kind) { |
3616 return next_map; | 3605 return next_map; |
3617 } | 3606 } |
3618 return map; | 3607 return map; |
3619 } | 3608 } |
3620 | 3609 |
3621 ElementsKind kind = map->elements_kind(); | 3610 ElementsKind kind = map->elements_kind(); |
3622 while (kind != target_kind) { | 3611 while (kind != to_kind) { |
3623 kind = GetNextTransitionElementsKind(kind); | |
3624 Map* next_map = current_map->ElementsTransitionMap(); | 3612 Map* next_map = current_map->ElementsTransitionMap(); |
3625 if (next_map == NULL) return current_map; | 3613 if (next_map == nullptr) return current_map; |
| 3614 kind = next_map->elements_kind(); |
3626 current_map = next_map; | 3615 current_map = next_map; |
3627 } | 3616 } |
3628 | 3617 |
3629 Map* next_map = current_map->ElementsTransitionMap(); | 3618 DCHECK_EQ(to_kind, current_map->elements_kind()); |
3630 if (to_kind != kind && next_map != NULL) { | |
3631 DCHECK(to_kind == DICTIONARY_ELEMENTS); | |
3632 if (next_map->elements_kind() == to_kind) return next_map; | |
3633 } | |
3634 | |
3635 DCHECK(current_map->elements_kind() == target_kind); | |
3636 return current_map; | 3619 return current_map; |
3637 } | 3620 } |
3638 | 3621 |
3639 | 3622 |
3640 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { | 3623 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { |
3641 Map* to_map = FindClosestElementsTransition(this, to_kind); | 3624 Map* to_map = FindClosestElementsTransition(this, to_kind); |
3642 if (to_map->elements_kind() == to_kind) return to_map; | 3625 if (to_map->elements_kind() == to_kind) return to_map; |
3643 return NULL; | 3626 return nullptr; |
3644 } | 3627 } |
3645 | 3628 |
3646 | 3629 |
3647 bool Map::IsMapInArrayPrototypeChain() { | 3630 bool Map::IsMapInArrayPrototypeChain() { |
3648 Isolate* isolate = GetIsolate(); | 3631 Isolate* isolate = GetIsolate(); |
3649 if (isolate->initial_array_prototype()->map() == this) { | 3632 if (isolate->initial_array_prototype()->map() == this) { |
3650 return true; | 3633 return true; |
3651 } | 3634 } |
3652 | 3635 |
3653 if (isolate->initial_object_prototype()->map() == this) { | 3636 if (isolate->initial_object_prototype()->map() == this) { |
(...skipping 20 matching lines...) Expand all Loading... |
3674 DCHECK(IsTransitionElementsKind(map->elements_kind())); | 3657 DCHECK(IsTransitionElementsKind(map->elements_kind())); |
3675 | 3658 |
3676 Handle<Map> current_map = map; | 3659 Handle<Map> current_map = map; |
3677 | 3660 |
3678 ElementsKind kind = map->elements_kind(); | 3661 ElementsKind kind = map->elements_kind(); |
3679 TransitionFlag flag; | 3662 TransitionFlag flag; |
3680 if (map->is_prototype_map()) { | 3663 if (map->is_prototype_map()) { |
3681 flag = OMIT_TRANSITION; | 3664 flag = OMIT_TRANSITION; |
3682 } else { | 3665 } else { |
3683 flag = INSERT_TRANSITION; | 3666 flag = INSERT_TRANSITION; |
3684 while (kind != to_kind && !IsTerminalElementsKind(kind)) { | 3667 if (IsFastElementsKind(kind)) { |
3685 kind = GetNextTransitionElementsKind(kind); | 3668 while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
3686 current_map = Map::CopyAsElementsKind(current_map, kind, flag); | 3669 kind = GetNextTransitionElementsKind(kind); |
| 3670 current_map = Map::CopyAsElementsKind(current_map, kind, flag); |
| 3671 } |
3687 } | 3672 } |
3688 } | 3673 } |
3689 | 3674 |
3690 // In case we are exiting the fast elements kind system, just add the map in | 3675 // In case we are exiting the fast elements kind system, just add the map in |
3691 // the end. | 3676 // the end. |
3692 if (kind != to_kind) { | 3677 if (kind != to_kind) { |
3693 current_map = Map::CopyAsElementsKind(current_map, to_kind, flag); | 3678 current_map = Map::CopyAsElementsKind(current_map, to_kind, flag); |
3694 } | 3679 } |
3695 | 3680 |
3696 DCHECK(current_map->elements_kind() == to_kind); | 3681 DCHECK(current_map->elements_kind() == to_kind); |
3697 return current_map; | 3682 return current_map; |
3698 } | 3683 } |
3699 | 3684 |
3700 | 3685 |
3701 Handle<Map> Map::TransitionElementsTo(Handle<Map> map, | 3686 Handle<Map> Map::TransitionElementsTo(Handle<Map> map, |
3702 ElementsKind to_kind) { | 3687 ElementsKind to_kind) { |
3703 ElementsKind from_kind = map->elements_kind(); | 3688 ElementsKind from_kind = map->elements_kind(); |
3704 if (from_kind == to_kind) return map; | 3689 if (from_kind == to_kind) return map; |
3705 | 3690 |
3706 Isolate* isolate = map->GetIsolate(); | 3691 Isolate* isolate = map->GetIsolate(); |
3707 Context* native_context = isolate->context()->native_context(); | 3692 Context* native_context = isolate->context()->native_context(); |
3708 Object* maybe_array_maps = map->is_strong() | 3693 if (from_kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { |
3709 ? native_context->js_array_strong_maps() | 3694 if (*map == native_context->fast_aliased_arguments_map()) { |
3710 : native_context->js_array_maps(); | 3695 DCHECK_EQ(SLOW_SLOPPY_ARGUMENTS_ELEMENTS, to_kind); |
3711 if (maybe_array_maps->IsFixedArray()) { | 3696 return handle(native_context->slow_aliased_arguments_map()); |
3712 DisallowHeapAllocation no_gc; | 3697 } |
3713 FixedArray* array_maps = FixedArray::cast(maybe_array_maps); | 3698 } else if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) { |
3714 if (array_maps->get(from_kind) == *map) { | 3699 if (*map == native_context->slow_aliased_arguments_map()) { |
3715 Object* maybe_transitioned_map = array_maps->get(to_kind); | 3700 DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, to_kind); |
3716 if (maybe_transitioned_map->IsMap()) { | 3701 return handle(native_context->fast_aliased_arguments_map()); |
3717 return handle(Map::cast(maybe_transitioned_map)); | 3702 } |
| 3703 } else { |
| 3704 Object* maybe_array_maps = map->is_strong() |
| 3705 ? native_context->js_array_strong_maps() |
| 3706 : native_context->js_array_maps(); |
| 3707 if (maybe_array_maps->IsFixedArray()) { |
| 3708 DisallowHeapAllocation no_gc; |
| 3709 FixedArray* array_maps = FixedArray::cast(maybe_array_maps); |
| 3710 if (array_maps->get(from_kind) == *map) { |
| 3711 Object* maybe_transitioned_map = array_maps->get(to_kind); |
| 3712 if (maybe_transitioned_map->IsMap()) { |
| 3713 return handle(Map::cast(maybe_transitioned_map)); |
| 3714 } |
3718 } | 3715 } |
3719 } | 3716 } |
3720 } | 3717 } |
3721 | 3718 |
3722 DCHECK(!map->IsUndefined()); | 3719 DCHECK(!map->IsUndefined()); |
3723 bool allow_store_transition = IsTransitionElementsKind(from_kind); | 3720 bool allow_store_transition = IsTransitionElementsKind(from_kind); |
3724 // Only store fast element maps in ascending generality. | 3721 // Only store fast element maps in ascending generality. |
3725 if (IsFastElementsKind(to_kind)) { | 3722 if (IsFastElementsKind(to_kind)) { |
3726 allow_store_transition &= | 3723 allow_store_transition = |
3727 IsTransitionableFastElementsKind(from_kind) && | 3724 allow_store_transition && IsTransitionableFastElementsKind(from_kind) && |
3728 IsMoreGeneralElementsKindTransition(from_kind, to_kind); | 3725 IsMoreGeneralElementsKindTransition(from_kind, to_kind); |
3729 } | 3726 } |
3730 | 3727 |
3731 if (!allow_store_transition) { | 3728 if (!allow_store_transition) { |
3732 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); | 3729 return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION); |
3733 } | 3730 } |
3734 | 3731 |
3735 return Map::AsElementsKind(map, to_kind); | 3732 return Map::AsElementsKind(map, to_kind); |
3736 } | 3733 } |
3737 | 3734 |
(...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4810 : array->length(); | 4807 : array->length(); |
4811 int old_capacity = 0; | 4808 int old_capacity = 0; |
4812 int used_elements = 0; | 4809 int used_elements = 0; |
4813 object->GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 4810 object->GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
4814 Handle<SeededNumberDictionary> dictionary = | 4811 Handle<SeededNumberDictionary> dictionary = |
4815 SeededNumberDictionary::New(isolate, used_elements); | 4812 SeededNumberDictionary::New(isolate, used_elements); |
4816 | 4813 |
4817 dictionary = CopyFastElementsToDictionary(array, length, dictionary); | 4814 dictionary = CopyFastElementsToDictionary(array, length, dictionary); |
4818 | 4815 |
4819 // Switch to using the dictionary as the backing storage for elements. | 4816 // Switch to using the dictionary as the backing storage for elements. |
| 4817 ElementsKind target_kind = |
| 4818 is_arguments ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS : DICTIONARY_ELEMENTS; |
| 4819 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind); |
| 4820 // Set the new map first to satify the elements type assert in set_elements(). |
| 4821 JSObject::MigrateToMap(object, new_map); |
| 4822 |
4820 if (is_arguments) { | 4823 if (is_arguments) { |
4821 FixedArray::cast(object->elements())->set(1, *dictionary); | 4824 FixedArray::cast(object->elements())->set(1, *dictionary); |
4822 } else { | 4825 } else { |
4823 // Set the new map first to satify the elements type assert in | |
4824 // set_elements(). | |
4825 Handle<Map> new_map = | |
4826 JSObject::GetElementsTransitionMap(object, DICTIONARY_ELEMENTS); | |
4827 | |
4828 JSObject::MigrateToMap(object, new_map); | |
4829 object->set_elements(*dictionary); | 4826 object->set_elements(*dictionary); |
4830 } | 4827 } |
4831 | 4828 |
4832 isolate->counters()->elements_to_dictionary()->Increment(); | 4829 isolate->counters()->elements_to_dictionary()->Increment(); |
4833 | 4830 |
4834 #ifdef DEBUG | 4831 #ifdef DEBUG |
4835 if (FLAG_trace_normalization) { | 4832 if (FLAG_trace_normalization) { |
4836 OFStream os(stdout); | 4833 OFStream os(stdout); |
4837 os << "Object elements have been normalized:\n"; | 4834 os << "Object elements have been normalized:\n"; |
4838 object->Print(os); | 4835 object->Print(os); |
4839 } | 4836 } |
4840 #endif | 4837 #endif |
4841 | 4838 |
4842 DCHECK(object->HasDictionaryElements() || | 4839 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); |
4843 object->HasDictionaryArgumentsElements()); | |
4844 return dictionary; | 4840 return dictionary; |
4845 } | 4841 } |
4846 | 4842 |
4847 | 4843 |
4848 static Smi* GenerateIdentityHash(Isolate* isolate) { | 4844 static Smi* GenerateIdentityHash(Isolate* isolate) { |
4849 int hash_value; | 4845 int hash_value; |
4850 int attempts = 0; | 4846 int attempts = 0; |
4851 do { | 4847 do { |
4852 // Generate a random 32-bit hash value but limit range to fit | 4848 // Generate a random 32-bit hash value but limit range to fit |
4853 // within a smi. | 4849 // within a smi. |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5330 case FAST_SMI_ELEMENTS: | 5326 case FAST_SMI_ELEMENTS: |
5331 case FAST_HOLEY_SMI_ELEMENTS: | 5327 case FAST_HOLEY_SMI_ELEMENTS: |
5332 break; | 5328 break; |
5333 case FAST_ELEMENTS: | 5329 case FAST_ELEMENTS: |
5334 case FAST_HOLEY_ELEMENTS: | 5330 case FAST_HOLEY_ELEMENTS: |
5335 case DICTIONARY_ELEMENTS: { | 5331 case DICTIONARY_ELEMENTS: { |
5336 FixedArray* elements = FixedArray::cast(this->elements()); | 5332 FixedArray* elements = FixedArray::cast(this->elements()); |
5337 if (ReferencesObjectFromElements(elements, kind, obj)) return true; | 5333 if (ReferencesObjectFromElements(elements, kind, obj)) return true; |
5338 break; | 5334 break; |
5339 } | 5335 } |
5340 case SLOPPY_ARGUMENTS_ELEMENTS: { | 5336 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 5337 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
5341 FixedArray* parameter_map = FixedArray::cast(elements()); | 5338 FixedArray* parameter_map = FixedArray::cast(elements()); |
5342 // Check the mapped parameters. | 5339 // Check the mapped parameters. |
5343 int length = parameter_map->length(); | 5340 int length = parameter_map->length(); |
5344 for (int i = 2; i < length; ++i) { | 5341 for (int i = 2; i < length; ++i) { |
5345 Object* value = parameter_map->get(i); | 5342 Object* value = parameter_map->get(i); |
5346 if (!value->IsTheHole() && value == obj) return true; | 5343 if (!value->IsTheHole() && value == obj) return true; |
5347 } | 5344 } |
5348 // Check the arguments. | 5345 // Check the arguments. |
5349 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 5346 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
5350 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : | 5347 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5428 // It's not possible to seal objects with external array elements | 5425 // It's not possible to seal objects with external array elements |
5429 if (object->HasExternalArrayElements() || | 5426 if (object->HasExternalArrayElements() || |
5430 object->HasFixedTypedArrayElements()) { | 5427 object->HasFixedTypedArrayElements()) { |
5431 THROW_NEW_ERROR( | 5428 THROW_NEW_ERROR( |
5432 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), | 5429 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), |
5433 Object); | 5430 Object); |
5434 } | 5431 } |
5435 | 5432 |
5436 // If there are fast elements we normalize. | 5433 // If there are fast elements we normalize. |
5437 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 5434 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
5438 DCHECK(object->HasDictionaryElements() || | 5435 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); |
5439 object->HasDictionaryArgumentsElements()); | |
5440 | 5436 |
5441 // Make sure that we never go back to fast case. | 5437 // Make sure that we never go back to fast case. |
5442 dictionary->set_requires_slow_elements(); | 5438 dictionary->set_requires_slow_elements(); |
5443 | 5439 |
5444 // Do a map transition, other objects with this map may still | 5440 // Do a map transition, other objects with this map may still |
5445 // be extensible. | 5441 // be extensible. |
5446 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5442 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
5447 Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions"); | 5443 Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions"); |
5448 | 5444 |
5449 new_map->set_is_extensible(false); | 5445 new_map->set_is_extensible(false); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5857 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 5853 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
5858 JSObject); | 5854 JSObject); |
5859 if (copying) { | 5855 if (copying) { |
5860 element_dictionary->ValueAtPut(i, *result); | 5856 element_dictionary->ValueAtPut(i, *result); |
5861 } | 5857 } |
5862 } | 5858 } |
5863 } | 5859 } |
5864 } | 5860 } |
5865 break; | 5861 break; |
5866 } | 5862 } |
5867 case SLOPPY_ARGUMENTS_ELEMENTS: | 5863 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 5864 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
5868 UNIMPLEMENTED(); | 5865 UNIMPLEMENTED(); |
5869 break; | 5866 break; |
5870 | 5867 |
5871 | 5868 |
5872 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 5869 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
5873 case EXTERNAL_##TYPE##_ELEMENTS: \ | 5870 case EXTERNAL_##TYPE##_ELEMENTS: \ |
5874 case TYPE##_ELEMENTS: \ | 5871 case TYPE##_ELEMENTS: \ |
5875 | 5872 |
5876 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 5873 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
5877 #undef TYPED_ARRAY_CASE | 5874 #undef TYPED_ARRAY_CASE |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6274 | 6271 |
6275 case DICTIONARY_ELEMENTS: | 6272 case DICTIONARY_ELEMENTS: |
6276 if (UpdateGetterSetterInDictionary(object->element_dictionary(), | 6273 if (UpdateGetterSetterInDictionary(object->element_dictionary(), |
6277 index, | 6274 index, |
6278 *getter, | 6275 *getter, |
6279 *setter, | 6276 *setter, |
6280 attributes)) { | 6277 attributes)) { |
6281 return; | 6278 return; |
6282 } | 6279 } |
6283 break; | 6280 break; |
6284 case SLOPPY_ARGUMENTS_ELEMENTS: { | 6281 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 6282 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
6285 // Ascertain whether we have read-only properties or an existing | 6283 // Ascertain whether we have read-only properties or an existing |
6286 // getter/setter pair in an arguments elements dictionary backing | 6284 // getter/setter pair in an arguments elements dictionary backing |
6287 // store. | 6285 // store. |
6288 FixedArray* parameter_map = FixedArray::cast(object->elements()); | 6286 FixedArray* parameter_map = FixedArray::cast(object->elements()); |
6289 uint32_t length = parameter_map->length(); | 6287 uint32_t length = parameter_map->length(); |
6290 Object* probe = | 6288 Object* probe = |
6291 index < (length - 2) ? parameter_map->get(index + 2) : NULL; | 6289 index < (length - 2) ? parameter_map->get(index + 2) : NULL; |
6292 if (probe == NULL || probe->IsTheHole()) { | 6290 if (probe == NULL || probe->IsTheHole()) { |
6293 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 6291 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
6294 if (arguments->IsDictionary()) { | 6292 if (arguments->IsDictionary()) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6340 uint32_t index, | 6338 uint32_t index, |
6341 Handle<Object> structure, | 6339 Handle<Object> structure, |
6342 PropertyAttributes attributes) { | 6340 PropertyAttributes attributes) { |
6343 Heap* heap = object->GetHeap(); | 6341 Heap* heap = object->GetHeap(); |
6344 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0, | 6342 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0, |
6345 PropertyCellType::kNoCell); | 6343 PropertyCellType::kNoCell); |
6346 | 6344 |
6347 // Normalize elements to make this operation simple. | 6345 // Normalize elements to make this operation simple. |
6348 bool had_dictionary_elements = object->HasDictionaryElements(); | 6346 bool had_dictionary_elements = object->HasDictionaryElements(); |
6349 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6347 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
6350 DCHECK(object->HasDictionaryElements() || | 6348 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); |
6351 object->HasDictionaryArgumentsElements()); | |
6352 // Update the dictionary with the new ACCESSOR_CONSTANT property. | 6349 // Update the dictionary with the new ACCESSOR_CONSTANT property. |
6353 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6350 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
6354 details); | 6351 details); |
6355 dictionary->set_requires_slow_elements(); | 6352 dictionary->set_requires_slow_elements(); |
6356 | 6353 |
6357 // Update the dictionary backing store on the object. | 6354 // Update the dictionary backing store on the object. |
6358 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) { | 6355 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) { |
6359 // Also delete any parameter alias. | 6356 // Also delete any parameter alias. |
6360 // | 6357 // |
6361 // TODO(kmillikin): when deleting the last parameter alias we could | 6358 // TODO(kmillikin): when deleting the last parameter alias we could |
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7123 | 7120 |
7124 case FAST_DOUBLE_ELEMENTS: | 7121 case FAST_DOUBLE_ELEMENTS: |
7125 case FAST_HOLEY_DOUBLE_ELEMENTS: | 7122 case FAST_HOLEY_DOUBLE_ELEMENTS: |
7126 if (value->IsNumber()) return map; | 7123 if (value->IsNumber()) return map; |
7127 kind = FAST_ELEMENTS; | 7124 kind = FAST_ELEMENTS; |
7128 break; | 7125 break; |
7129 | 7126 |
7130 case FAST_ELEMENTS: | 7127 case FAST_ELEMENTS: |
7131 case FAST_HOLEY_ELEMENTS: | 7128 case FAST_HOLEY_ELEMENTS: |
7132 case DICTIONARY_ELEMENTS: | 7129 case DICTIONARY_ELEMENTS: |
7133 case SLOPPY_ARGUMENTS_ELEMENTS: | 7130 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 7131 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
7134 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 7132 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
7135 case EXTERNAL_##TYPE##_ELEMENTS: \ | 7133 case EXTERNAL_##TYPE##_ELEMENTS: \ |
7136 case TYPE##_ELEMENTS: | 7134 case TYPE##_ELEMENTS: |
7137 | 7135 |
7138 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 7136 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
7139 #undef TYPED_ARRAY_CASE | 7137 #undef TYPED_ARRAY_CASE |
7140 return map; | 7138 return map; |
7141 } | 7139 } |
7142 | 7140 |
7143 if (holey) kind = GetHoleyElementsKind(kind); | 7141 if (holey) kind = GetHoleyElementsKind(kind); |
(...skipping 5149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12293 uint32_t arg_count, | 12291 uint32_t arg_count, |
12294 EnsureElementsMode mode) { | 12292 EnsureElementsMode mode) { |
12295 // Elements in |Arguments| are ordered backwards (because they're on the | 12293 // Elements in |Arguments| are ordered backwards (because they're on the |
12296 // stack), but the method that's called here iterates over them in forward | 12294 // stack), but the method that's called here iterates over them in forward |
12297 // direction. | 12295 // direction. |
12298 return EnsureCanContainElements( | 12296 return EnsureCanContainElements( |
12299 object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode); | 12297 object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode); |
12300 } | 12298 } |
12301 | 12299 |
12302 | 12300 |
12303 bool JSObject::HasFastArgumentsElements() { | |
12304 Heap* heap = GetHeap(); | |
12305 if (!elements()->IsFixedArray()) return false; | |
12306 FixedArray* elements = FixedArray::cast(this->elements()); | |
12307 if (elements->map() != heap->sloppy_arguments_elements_map()) { | |
12308 return false; | |
12309 } | |
12310 FixedArray* arguments = FixedArray::cast(elements->get(1)); | |
12311 return !arguments->IsDictionary(); | |
12312 } | |
12313 | |
12314 | |
12315 bool JSObject::HasDictionaryArgumentsElements() { | |
12316 Heap* heap = GetHeap(); | |
12317 if (!elements()->IsFixedArray()) return false; | |
12318 FixedArray* elements = FixedArray::cast(this->elements()); | |
12319 if (elements->map() != heap->sloppy_arguments_elements_map()) { | |
12320 return false; | |
12321 } | |
12322 FixedArray* arguments = FixedArray::cast(elements->get(1)); | |
12323 return arguments->IsDictionary(); | |
12324 } | |
12325 | |
12326 | |
12327 ElementsAccessor* JSObject::GetElementsAccessor() { | 12301 ElementsAccessor* JSObject::GetElementsAccessor() { |
12328 return ElementsAccessor::ForKind(GetElementsKind()); | 12302 return ElementsAccessor::ForKind(GetElementsKind()); |
12329 } | 12303 } |
12330 | 12304 |
12331 | 12305 |
12332 void JSObject::ValidateElements(Handle<JSObject> object) { | 12306 void JSObject::ValidateElements(Handle<JSObject> object) { |
12333 #ifdef ENABLE_SLOW_DCHECKS | 12307 #ifdef ENABLE_SLOW_DCHECKS |
12334 if (FLAG_enable_slow_asserts) { | 12308 if (FLAG_enable_slow_asserts) { |
12335 ElementsAccessor* accessor = object->GetElementsAccessor(); | 12309 ElementsAccessor* accessor = object->GetElementsAccessor(); |
12336 accessor->Validate(object); | 12310 accessor->Validate(object); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12383 Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements())); | 12357 Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements())); |
12384 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 12358 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
12385 uint32_t new_capacity; | 12359 uint32_t new_capacity; |
12386 return ShouldConvertToSlowElements(this, capacity, index, &new_capacity); | 12360 return ShouldConvertToSlowElements(this, capacity, index, &new_capacity); |
12387 } | 12361 } |
12388 return false; | 12362 return false; |
12389 } | 12363 } |
12390 | 12364 |
12391 | 12365 |
12392 static ElementsKind BestFittingFastElementsKind(JSObject* object) { | 12366 static ElementsKind BestFittingFastElementsKind(JSObject* object) { |
12393 if (object->HasSloppyArgumentsElements()) return SLOPPY_ARGUMENTS_ELEMENTS; | 12367 if (object->HasSloppyArgumentsElements()) { |
| 12368 return FAST_SLOPPY_ARGUMENTS_ELEMENTS; |
| 12369 } |
12394 DCHECK(object->HasDictionaryElements()); | 12370 DCHECK(object->HasDictionaryElements()); |
12395 SeededNumberDictionary* dictionary = object->element_dictionary(); | 12371 SeededNumberDictionary* dictionary = object->element_dictionary(); |
12396 ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS; | 12372 ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS; |
12397 for (int i = 0; i < dictionary->Capacity(); i++) { | 12373 for (int i = 0; i < dictionary->Capacity(); i++) { |
12398 Object* key = dictionary->KeyAt(i); | 12374 Object* key = dictionary->KeyAt(i); |
12399 if (key->IsNumber()) { | 12375 if (key->IsNumber()) { |
12400 Object* value = dictionary->ValueAt(i); | 12376 Object* value = dictionary->ValueAt(i); |
12401 if (!value->IsNumber()) return FAST_HOLEY_ELEMENTS; | 12377 if (!value->IsNumber()) return FAST_HOLEY_ELEMENTS; |
12402 if (!value->IsSmi()) { | 12378 if (!value->IsSmi()) { |
12403 if (!FLAG_unbox_double_arrays) return FAST_HOLEY_ELEMENTS; | 12379 if (!FLAG_unbox_double_arrays) return FAST_HOLEY_ELEMENTS; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12450 Handle<Object> old_length_handle; | 12426 Handle<Object> old_length_handle; |
12451 if (object->IsJSArray()) { | 12427 if (object->IsJSArray()) { |
12452 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length)); | 12428 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length)); |
12453 if (object->map()->is_observed()) { | 12429 if (object->map()->is_observed()) { |
12454 old_length_handle = handle(JSArray::cast(*object)->length(), isolate); | 12430 old_length_handle = handle(JSArray::cast(*object)->length(), isolate); |
12455 } | 12431 } |
12456 } | 12432 } |
12457 | 12433 |
12458 ElementsKind kind = object->GetElementsKind(); | 12434 ElementsKind kind = object->GetElementsKind(); |
12459 FixedArrayBase* elements = object->elements(); | 12435 FixedArrayBase* elements = object->elements(); |
| 12436 ElementsKind dictionary_kind = DICTIONARY_ELEMENTS; |
12460 if (IsSloppyArgumentsElements(kind)) { | 12437 if (IsSloppyArgumentsElements(kind)) { |
12461 elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1)); | 12438 elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1)); |
| 12439 dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS; |
12462 } | 12440 } |
12463 | 12441 |
12464 if (attributes != NONE) { | 12442 if (attributes != NONE) { |
12465 kind = DICTIONARY_ELEMENTS; | 12443 kind = dictionary_kind; |
12466 } else if (elements->IsSeededNumberDictionary()) { | 12444 } else if (elements->IsSeededNumberDictionary()) { |
12467 kind = ShouldConvertToFastElements(*object, | 12445 kind = ShouldConvertToFastElements(*object, |
12468 SeededNumberDictionary::cast(elements), | 12446 SeededNumberDictionary::cast(elements), |
12469 index, &new_capacity) | 12447 index, &new_capacity) |
12470 ? BestFittingFastElementsKind(*object) | 12448 ? BestFittingFastElementsKind(*object) |
12471 : DICTIONARY_ELEMENTS; // Overwrite in case of arguments. | 12449 : dictionary_kind; // Overwrite in case of arguments. |
12472 } else if (ShouldConvertToSlowElements( | 12450 } else if (ShouldConvertToSlowElements( |
12473 *object, static_cast<uint32_t>(elements->length()), index, | 12451 *object, static_cast<uint32_t>(elements->length()), index, |
12474 &new_capacity)) { | 12452 &new_capacity)) { |
12475 kind = DICTIONARY_ELEMENTS; | 12453 kind = dictionary_kind; |
12476 } | 12454 } |
12477 | 12455 |
12478 if (kind == DICTIONARY_ELEMENTS && object->HasSloppyArgumentsElements()) { | 12456 ElementsKind to = value->OptimalElementsKind(); |
12479 // TODO(verwaest): Distinguish fast/slow sloppy elements in ElementsKind. | 12457 if (IsHoleyElementsKind(kind) || !object->IsJSArray() || index > old_length) { |
12480 Handle<SeededNumberDictionary> dictionary = | 12458 to = GetHoleyElementsKind(to); |
12481 elements->IsSeededNumberDictionary() | 12459 kind = GetHoleyElementsKind(kind); |
12482 ? handle(SeededNumberDictionary::cast(elements)) | |
12483 : NormalizeElements(object); | |
12484 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); | |
12485 Handle<SeededNumberDictionary> new_dictionary = | |
12486 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, | |
12487 details); | |
12488 if (attributes != NONE) new_dictionary->set_requires_slow_elements(); | |
12489 if (*dictionary != *new_dictionary) { | |
12490 FixedArray::cast(object->elements())->set(1, *new_dictionary); | |
12491 } | |
12492 } else { | |
12493 ElementsKind to = value->OptimalElementsKind(); | |
12494 if (IsHoleyElementsKind(kind) || !object->IsJSArray() || | |
12495 index > old_length) { | |
12496 to = GetHoleyElementsKind(to); | |
12497 kind = GetHoleyElementsKind(kind); | |
12498 } | |
12499 to = IsMoreGeneralElementsKindTransition(kind, to) ? to : kind; | |
12500 ElementsAccessor* accessor = ElementsAccessor::ForKind(to); | |
12501 accessor->Add(object, index, value, attributes, new_capacity); | |
12502 } | 12460 } |
| 12461 to = IsMoreGeneralElementsKindTransition(kind, to) ? to : kind; |
| 12462 ElementsAccessor* accessor = ElementsAccessor::ForKind(to); |
| 12463 accessor->Add(object, index, value, attributes, new_capacity); |
12503 | 12464 |
12504 uint32_t new_length = old_length; | 12465 uint32_t new_length = old_length; |
12505 Handle<Object> new_length_handle; | 12466 Handle<Object> new_length_handle; |
12506 if (object->IsJSArray() && index >= old_length) { | 12467 if (object->IsJSArray() && index >= old_length) { |
12507 new_length = index + 1; | 12468 new_length = index + 1; |
12508 new_length_handle = isolate->factory()->NewNumberFromUint(new_length); | 12469 new_length_handle = isolate->factory()->NewNumberFromUint(new_length); |
12509 JSArray::cast(*object)->set_length(*new_length_handle); | 12470 JSArray::cast(*object)->set_length(*new_length_handle); |
12510 } | 12471 } |
12511 | 12472 |
12512 if (!old_length_handle.is_null() && new_length != old_length) { | 12473 if (!old_length_handle.is_null() && new_length != old_length) { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12751 } | 12712 } |
12752 | 12713 |
12753 | 12714 |
12754 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { | 12715 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { |
12755 *capacity = 0; | 12716 *capacity = 0; |
12756 *used = 0; | 12717 *used = 0; |
12757 | 12718 |
12758 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); | 12719 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); |
12759 FixedArray* backing_store = NULL; | 12720 FixedArray* backing_store = NULL; |
12760 switch (GetElementsKind()) { | 12721 switch (GetElementsKind()) { |
12761 case SLOPPY_ARGUMENTS_ELEMENTS: | 12722 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 12723 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
12762 backing_store_base = | 12724 backing_store_base = |
12763 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); | 12725 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); |
12764 backing_store = FixedArray::cast(backing_store_base); | 12726 backing_store = FixedArray::cast(backing_store_base); |
12765 if (backing_store->IsDictionary()) { | 12727 if (backing_store->IsDictionary()) { |
12766 SeededNumberDictionary* dictionary = | 12728 SeededNumberDictionary* dictionary = |
12767 SeededNumberDictionary::cast(backing_store); | 12729 SeededNumberDictionary::cast(backing_store); |
12768 *capacity = dictionary->Capacity(); | 12730 *capacity = dictionary->Capacity(); |
12769 *used = dictionary->NumberOfElements(); | 12731 *used = dictionary->NumberOfElements(); |
12770 break; | 12732 break; |
12771 } | 12733 } |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13248 } | 13210 } |
13249 | 13211 |
13250 case DICTIONARY_ELEMENTS: { | 13212 case DICTIONARY_ELEMENTS: { |
13251 if (storage != NULL) { | 13213 if (storage != NULL) { |
13252 element_dictionary()->CopyKeysTo(storage, filter, | 13214 element_dictionary()->CopyKeysTo(storage, filter, |
13253 SeededNumberDictionary::SORTED); | 13215 SeededNumberDictionary::SORTED); |
13254 } | 13216 } |
13255 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); | 13217 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
13256 break; | 13218 break; |
13257 } | 13219 } |
13258 case SLOPPY_ARGUMENTS_ELEMENTS: { | 13220 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 13221 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
13259 FixedArray* parameter_map = FixedArray::cast(elements()); | 13222 FixedArray* parameter_map = FixedArray::cast(elements()); |
13260 int mapped_length = parameter_map->length() - 2; | 13223 int mapped_length = parameter_map->length() - 2; |
13261 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 13224 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
13262 if (arguments->IsDictionary()) { | 13225 if (arguments->IsDictionary()) { |
13263 // Copy the keys from arguments first, because Dictionary::CopyKeysTo | 13226 // Copy the keys from arguments first, because Dictionary::CopyKeysTo |
13264 // will insert in storage starting at index 0. | 13227 // will insert in storage starting at index 0. |
13265 SeededNumberDictionary* dictionary = | 13228 SeededNumberDictionary* dictionary = |
13266 SeededNumberDictionary::cast(arguments); | 13229 SeededNumberDictionary::cast(arguments); |
13267 if (storage != NULL) { | 13230 if (storage != NULL) { |
13268 dictionary->CopyKeysTo(storage, filter, | 13231 dictionary->CopyKeysTo(storage, filter, |
(...skipping 2881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16150 Handle<Object> new_value) { | 16113 Handle<Object> new_value) { |
16151 if (cell->value() != *new_value) { | 16114 if (cell->value() != *new_value) { |
16152 cell->set_value(*new_value); | 16115 cell->set_value(*new_value); |
16153 Isolate* isolate = cell->GetIsolate(); | 16116 Isolate* isolate = cell->GetIsolate(); |
16154 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16117 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
16155 isolate, DependentCode::kPropertyCellChangedGroup); | 16118 isolate, DependentCode::kPropertyCellChangedGroup); |
16156 } | 16119 } |
16157 } | 16120 } |
16158 } // namespace internal | 16121 } // namespace internal |
16159 } // namespace v8 | 16122 } // namespace v8 |
OLD | NEW |