| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/elements.h" | 9 #include "src/elements.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 123 |
| 124 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 124 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 125 | 125 |
| 126 | 126 |
| 127 static bool HasKey(Handle<FixedArray> array, Handle<Object> key_handle) { | 127 static bool HasKey(Handle<FixedArray> array, Handle<Object> key_handle) { |
| 128 DisallowHeapAllocation no_gc; | 128 DisallowHeapAllocation no_gc; |
| 129 Object* key = *key_handle; | 129 Object* key = *key_handle; |
| 130 int len0 = array->length(); | 130 int len0 = array->length(); |
| 131 for (int i = 0; i < len0; i++) { | 131 for (int i = 0; i < len0; i++) { |
| 132 Object* element = array->get(i); | 132 Object* element = array->get(i); |
| 133 if (element->IsSmi() && element == key) return true; | 133 if (key->KeyEquals(element)) return true; |
| 134 if (element->IsString() && | |
| 135 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | |
| 136 return true; | |
| 137 } | |
| 138 } | 134 } |
| 139 return false; | 135 return false; |
| 140 } | 136 } |
| 141 | 137 |
| 142 | 138 |
| 143 MUST_USE_RESULT | 139 MUST_USE_RESULT |
| 144 static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { | 140 static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { |
| 145 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidArrayLength), | 141 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidArrayLength), |
| 146 Object); | 142 Object); |
| 147 } | 143 } |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 // | 727 // |
| 732 // Details: The idea is that allocations actually happen only in case of | 728 // Details: The idea is that allocations actually happen only in case of |
| 733 // copying from object with fast double elements to object with object | 729 // copying from object with fast double elements to object with object |
| 734 // elements. In all the other cases there are no allocations performed and | 730 // elements. In all the other cases there are no allocations performed and |
| 735 // handle creation causes noticeable performance degradation of the builtin. | 731 // handle creation causes noticeable performance degradation of the builtin. |
| 736 ElementsAccessorSubclass::CopyElementsImpl( | 732 ElementsAccessorSubclass::CopyElementsImpl( |
| 737 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 733 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
| 738 } | 734 } |
| 739 | 735 |
| 740 virtual MaybeHandle<FixedArray> AddElementsToFixedArray( | 736 virtual MaybeHandle<FixedArray> AddElementsToFixedArray( |
| 741 Handle<Object> receiver, Handle<JSObject> holder, Handle<FixedArray> to, | 737 Handle<JSObject> receiver, Handle<FixedArray> to, |
| 742 Handle<FixedArrayBase> from, FixedArray::KeyFilter filter) final { | 738 FixedArray::KeyFilter filter) final { |
| 739 Handle<FixedArrayBase> from(receiver->elements()); |
| 740 |
| 743 int len0 = to->length(); | 741 int len0 = to->length(); |
| 744 #ifdef ENABLE_SLOW_DCHECKS | 742 #ifdef ENABLE_SLOW_DCHECKS |
| 745 if (FLAG_enable_slow_asserts) { | 743 if (FLAG_enable_slow_asserts) { |
| 746 for (int i = 0; i < len0; i++) { | 744 for (int i = 0; i < len0; i++) { |
| 747 DCHECK(!to->get(i)->IsTheHole()); | 745 DCHECK(!to->get(i)->IsTheHole()); |
| 748 } | 746 } |
| 749 } | 747 } |
| 750 #endif | 748 #endif |
| 751 | 749 |
| 752 // Optimize if 'other' is empty. | 750 // Optimize if 'other' is empty. |
| 753 // We cannot optimize if 'this' is empty, as other may have holes. | 751 // We cannot optimize if 'this' is empty, as other may have holes. |
| 754 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(holder, from); | 752 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(receiver, from); |
| 755 if (len1 == 0) return to; | 753 if (len1 == 0) return to; |
| 756 | 754 |
| 757 Isolate* isolate = from->GetIsolate(); | 755 Isolate* isolate = from->GetIsolate(); |
| 758 | 756 |
| 759 // Compute how many elements are not in other. | 757 // Compute how many elements are not in other. |
| 760 uint32_t extra = 0; | 758 uint32_t extra = 0; |
| 761 for (uint32_t y = 0; y < len1; y++) { | 759 for (uint32_t y = 0; y < len1; y++) { |
| 762 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 760 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
| 763 if (ElementsAccessorSubclass::HasElementImpl(holder, key, from)) { | 761 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { |
| 764 Handle<Object> value; | 762 Handle<Object> value; |
| 765 ASSIGN_RETURN_ON_EXCEPTION( | 763 ASSIGN_RETURN_ON_EXCEPTION( |
| 766 isolate, value, | 764 isolate, value, |
| 767 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from), | 765 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from), |
| 768 FixedArray); | 766 FixedArray); |
| 769 | 767 |
| 770 DCHECK(!value->IsTheHole()); | 768 DCHECK(!value->IsTheHole()); |
| 771 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { | 769 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { |
| 772 continue; | 770 continue; |
| 773 } | 771 } |
| 774 if (!HasKey(to, value)) { | 772 if (!HasKey(to, value)) { |
| 775 extra++; | 773 extra++; |
| 776 } | 774 } |
| 777 } | 775 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 790 Object* e = to->get(i); | 788 Object* e = to->get(i); |
| 791 DCHECK(e->IsString() || e->IsNumber()); | 789 DCHECK(e->IsString() || e->IsNumber()); |
| 792 result->set(i, e, mode); | 790 result->set(i, e, mode); |
| 793 } | 791 } |
| 794 } | 792 } |
| 795 // Fill in the extra values. | 793 // Fill in the extra values. |
| 796 uint32_t index = 0; | 794 uint32_t index = 0; |
| 797 for (uint32_t y = 0; y < len1; y++) { | 795 for (uint32_t y = 0; y < len1; y++) { |
| 798 uint32_t key = | 796 uint32_t key = |
| 799 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 797 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
| 800 if (ElementsAccessorSubclass::HasElementImpl(holder, key, from)) { | 798 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { |
| 801 Handle<Object> value; | 799 Handle<Object> value; |
| 802 ASSIGN_RETURN_ON_EXCEPTION( | 800 ASSIGN_RETURN_ON_EXCEPTION( |
| 803 isolate, value, | 801 isolate, value, |
| 804 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from), | 802 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from), |
| 805 FixedArray); | 803 FixedArray); |
| 806 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { | 804 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { |
| 807 continue; | 805 continue; |
| 808 } | 806 } |
| 809 if (!value->IsTheHole() && !HasKey(to, value)) { | 807 if (!value->IsTheHole() && !HasKey(to, value)) { |
| 810 result->set(len0 + index, *value); | 808 result->set(len0 + index, *value); |
| 811 index++; | 809 index++; |
| 812 } | 810 } |
| 813 } | 811 } |
| 814 } | 812 } |
| (...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1851 UNREACHABLE(); | 1849 UNREACHABLE(); |
| 1852 break; | 1850 break; |
| 1853 } | 1851 } |
| 1854 | 1852 |
| 1855 array->set_elements(*elms); | 1853 array->set_elements(*elms); |
| 1856 array->set_length(Smi::FromInt(number_of_elements)); | 1854 array->set_length(Smi::FromInt(number_of_elements)); |
| 1857 return array; | 1855 return array; |
| 1858 } | 1856 } |
| 1859 | 1857 |
| 1860 } } // namespace v8::internal | 1858 } } // namespace v8::internal |
| OLD | NEW |