| 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/elements.h" | 5 #include "src/elements.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/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 uint32_t end) final { | 511 uint32_t end) final { |
| 512 return ElementsAccessorSubclass::IsPackedImpl(holder, backing_store, start, | 512 return ElementsAccessorSubclass::IsPackedImpl(holder, backing_store, start, |
| 513 end); | 513 end); |
| 514 } | 514 } |
| 515 | 515 |
| 516 static bool IsPackedImpl(Handle<JSObject> holder, | 516 static bool IsPackedImpl(Handle<JSObject> holder, |
| 517 Handle<FixedArrayBase> backing_store, uint32_t start, | 517 Handle<FixedArrayBase> backing_store, uint32_t start, |
| 518 uint32_t end) { | 518 uint32_t end) { |
| 519 if (IsFastPackedElementsKind(kind())) return true; | 519 if (IsFastPackedElementsKind(kind())) return true; |
| 520 for (uint32_t i = start; i < end; i++) { | 520 for (uint32_t i = start; i < end; i++) { |
| 521 if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store)) { | 521 if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store, |
| 522 NONE)) { |
| 522 return false; | 523 return false; |
| 523 } | 524 } |
| 524 } | 525 } |
| 525 return true; | 526 return true; |
| 526 } | 527 } |
| 527 | 528 |
| 528 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { | 529 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { |
| 529 if (!IsHoleyElementsKind(kind())) return; | 530 if (!IsHoleyElementsKind(kind())) return; |
| 530 int length = Smi::cast(array->length())->value(); | 531 int length = Smi::cast(array->length())->value(); |
| 531 Handle<FixedArrayBase> backing_store(array->elements()); | 532 Handle<FixedArrayBase> backing_store(array->elements()); |
| 532 if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0, | 533 if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0, |
| 533 length)) { | 534 length)) { |
| 534 return; | 535 return; |
| 535 } | 536 } |
| 536 ElementsKind packed_kind = GetPackedElementsKind(kind()); | 537 ElementsKind packed_kind = GetPackedElementsKind(kind()); |
| 537 Handle<Map> new_map = | 538 Handle<Map> new_map = |
| 538 JSObject::GetElementsTransitionMap(array, packed_kind); | 539 JSObject::GetElementsTransitionMap(array, packed_kind); |
| 539 JSObject::MigrateToMap(array, new_map); | 540 JSObject::MigrateToMap(array, new_map); |
| 540 if (FLAG_trace_elements_transitions) { | 541 if (FLAG_trace_elements_transitions) { |
| 541 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, | 542 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, |
| 542 packed_kind, backing_store); | 543 packed_kind, backing_store); |
| 543 } | 544 } |
| 544 } | 545 } |
| 545 | 546 |
| 546 virtual bool HasElement(Handle<JSObject> holder, uint32_t index, | 547 virtual bool HasElement(Handle<JSObject> holder, uint32_t index, |
| 547 Handle<FixedArrayBase> backing_store) final { | 548 Handle<FixedArrayBase> backing_store, |
| 549 PropertyAttributes filter) final { |
| 548 return ElementsAccessorSubclass::HasElementImpl(holder, index, | 550 return ElementsAccessorSubclass::HasElementImpl(holder, index, |
| 549 backing_store); | 551 backing_store, filter); |
| 550 } | 552 } |
| 551 | 553 |
| 552 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, | 554 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, |
| 553 Handle<FixedArrayBase> backing_store) { | 555 Handle<FixedArrayBase> backing_store, |
| 556 PropertyAttributes filter) { |
| 554 return ElementsAccessorSubclass::GetEntryForIndexImpl( | 557 return ElementsAccessorSubclass::GetEntryForIndexImpl( |
| 555 *holder, *backing_store, index) != kMaxUInt32; | 558 *holder, *backing_store, index, filter) != kMaxUInt32; |
| 556 } | 559 } |
| 557 | 560 |
| 558 virtual Handle<Object> Get(Handle<FixedArrayBase> backing_store, | 561 virtual Handle<Object> Get(Handle<FixedArrayBase> backing_store, |
| 559 uint32_t entry) final { | 562 uint32_t entry) final { |
| 560 return ElementsAccessorSubclass::GetImpl(backing_store, entry); | 563 return ElementsAccessorSubclass::GetImpl(backing_store, entry); |
| 561 } | 564 } |
| 562 | 565 |
| 563 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, | 566 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, |
| 564 uint32_t entry) { | 567 uint32_t entry) { |
| 565 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); | 568 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 // Details: The idea is that allocations actually happen only in case of | 866 // Details: The idea is that allocations actually happen only in case of |
| 864 // copying from object with fast double elements to object with object | 867 // copying from object with fast double elements to object with object |
| 865 // elements. In all the other cases there are no allocations performed and | 868 // elements. In all the other cases there are no allocations performed and |
| 866 // handle creation causes noticeable performance degradation of the builtin. | 869 // handle creation causes noticeable performance degradation of the builtin. |
| 867 ElementsAccessorSubclass::CopyElementsImpl( | 870 ElementsAccessorSubclass::CopyElementsImpl( |
| 868 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 871 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
| 869 } | 872 } |
| 870 | 873 |
| 871 virtual void AddElementsToKeyAccumulator(Handle<JSObject> receiver, | 874 virtual void AddElementsToKeyAccumulator(Handle<JSObject> receiver, |
| 872 KeyAccumulator* accumulator, | 875 KeyAccumulator* accumulator, |
| 873 KeyFilter filter) final { | 876 AddKeyConversion convert) final { |
| 874 Handle<FixedArrayBase> from(receiver->elements()); | 877 Handle<FixedArrayBase> from(receiver->elements()); |
| 875 uint32_t add_length = | 878 uint32_t add_length = |
| 876 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); | 879 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); |
| 877 if (add_length == 0) return; | 880 if (add_length == 0) return; |
| 878 accumulator->PrepareForComparisons(add_length); | 881 |
| 879 int prev_key_count = accumulator->GetLength(); | |
| 880 for (uint32_t i = 0; i < add_length; i++) { | 882 for (uint32_t i = 0; i < add_length; i++) { |
| 881 if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue; | 883 if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue; |
| 882 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i); | 884 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i); |
| 883 DCHECK(!value->IsTheHole()); | 885 DCHECK(!value->IsTheHole()); |
| 884 DCHECK(!value->IsAccessorPair()); | 886 DCHECK(!value->IsAccessorPair()); |
| 885 DCHECK(!value->IsExecutableAccessorInfo()); | 887 DCHECK(!value->IsExecutableAccessorInfo()); |
| 886 if (filter == SKIP_SYMBOLS && value->IsSymbol()) { | 888 accumulator->AddKey(value, convert); |
| 887 continue; | |
| 888 } | |
| 889 accumulator->AddKey(value, prev_key_count); | |
| 890 } | 889 } |
| 891 } | 890 } |
| 892 | 891 |
| 893 static uint32_t GetCapacityImpl(JSObject* holder, | 892 static uint32_t GetCapacityImpl(JSObject* holder, |
| 894 FixedArrayBase* backing_store) { | 893 FixedArrayBase* backing_store) { |
| 895 return backing_store->length(); | 894 return backing_store->length(); |
| 896 } | 895 } |
| 897 | 896 |
| 898 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { | 897 virtual uint32_t GetCapacity(JSObject* holder, |
| 898 FixedArrayBase* backing_store) final { |
| 899 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); | 899 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); |
| 900 } | 900 } |
| 901 | 901 |
| 902 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { | 902 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { |
| 903 return true; | 903 return true; |
| 904 } | 904 } |
| 905 | 905 |
| 906 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 906 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
| 907 uint32_t entry) { | 907 uint32_t entry) { |
| 908 return entry; | 908 return entry; |
| 909 } | 909 } |
| 910 | 910 |
| 911 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 911 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
| 912 FixedArrayBase* backing_store, | 912 FixedArrayBase* backing_store, |
| 913 uint32_t index) { | 913 uint32_t index, |
| 914 PropertyAttributes filter) { |
| 914 if (IsHoleyElementsKind(kind())) { | 915 if (IsHoleyElementsKind(kind())) { |
| 915 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, | 916 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, |
| 916 backing_store) && | 917 backing_store) && |
| 917 !BackingStore::cast(backing_store)->is_the_hole(index) | 918 !BackingStore::cast(backing_store)->is_the_hole(index) |
| 918 ? index | 919 ? index |
| 919 : kMaxUInt32; | 920 : kMaxUInt32; |
| 920 } else { | 921 } else { |
| 921 Smi* smi_length = Smi::cast(JSArray::cast(holder)->length()); | 922 Smi* smi_length = Smi::cast(JSArray::cast(holder)->length()); |
| 922 uint32_t length = static_cast<uint32_t>(smi_length->value()); | 923 uint32_t length = static_cast<uint32_t>(smi_length->value()); |
| 923 return index < length ? index : kMaxUInt32; | 924 return index < length ? index : kMaxUInt32; |
| 924 } | 925 } |
| 925 } | 926 } |
| 926 | 927 |
| 927 virtual uint32_t GetEntryForIndex(JSObject* holder, | 928 virtual uint32_t GetEntryForIndex(JSObject* holder, |
| 928 FixedArrayBase* backing_store, | 929 FixedArrayBase* backing_store, |
| 929 uint32_t index) final { | 930 uint32_t index) final { |
| 930 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store, | 931 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store, |
| 931 index); | 932 index, NONE); |
| 932 } | 933 } |
| 933 | 934 |
| 934 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 935 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
| 935 uint32_t entry) { | 936 uint32_t entry) { |
| 936 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 937 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
| 937 } | 938 } |
| 938 | 939 |
| 939 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, | 940 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, |
| 940 uint32_t entry) final { | 941 uint32_t entry) final { |
| 941 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry); | 942 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 | 1084 |
| 1084 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { | 1085 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { |
| 1085 DisallowHeapAllocation no_gc; | 1086 DisallowHeapAllocation no_gc; |
| 1086 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1087 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
| 1087 uint32_t result = 0; | 1088 uint32_t result = 0; |
| 1088 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); | 1089 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); |
| 1089 return result; | 1090 return result; |
| 1090 } | 1091 } |
| 1091 | 1092 |
| 1092 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, | 1093 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, |
| 1093 uint32_t index) { | 1094 uint32_t index, |
| 1095 PropertyAttributes filter) { |
| 1094 DisallowHeapAllocation no_gc; | 1096 DisallowHeapAllocation no_gc; |
| 1095 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1097 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); |
| 1096 int entry = dict->FindEntry(index); | 1098 int entry = dictionary->FindEntry(index); |
| 1097 return entry == SeededNumberDictionary::kNotFound | 1099 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; |
| 1098 ? kMaxUInt32 | 1100 if (filter != NONE) { |
| 1099 : static_cast<uint32_t>(entry); | 1101 PropertyDetails details = dictionary->DetailsAt(entry); |
| 1102 PropertyAttributes attr = details.attributes(); |
| 1103 if ((attr & filter) != 0) return kMaxUInt32; |
| 1104 } |
| 1105 return static_cast<uint32_t>(entry); |
| 1100 } | 1106 } |
| 1101 | 1107 |
| 1102 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1108 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
| 1103 uint32_t entry) { | 1109 uint32_t entry) { |
| 1104 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); | 1110 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); |
| 1105 } | 1111 } |
| 1106 }; | 1112 }; |
| 1107 | 1113 |
| 1108 | 1114 |
| 1109 // Super class for all fast element arrays. | 1115 // Super class for all fast element arrays. |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1752 UNREACHABLE(); | 1758 UNREACHABLE(); |
| 1753 } | 1759 } |
| 1754 | 1760 |
| 1755 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1761 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
| 1756 uint32_t entry) { | 1762 uint32_t entry) { |
| 1757 return entry; | 1763 return entry; |
| 1758 } | 1764 } |
| 1759 | 1765 |
| 1760 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1766 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
| 1761 FixedArrayBase* backing_store, | 1767 FixedArrayBase* backing_store, |
| 1762 uint32_t index) { | 1768 uint32_t index, |
| 1769 PropertyAttributes filter) { |
| 1763 return index < AccessorClass::GetCapacityImpl(holder, backing_store) | 1770 return index < AccessorClass::GetCapacityImpl(holder, backing_store) |
| 1764 ? index | 1771 ? index |
| 1765 : kMaxUInt32; | 1772 : kMaxUInt32; |
| 1766 } | 1773 } |
| 1767 | 1774 |
| 1768 static uint32_t GetCapacityImpl(JSObject* holder, | 1775 static uint32_t GetCapacityImpl(JSObject* holder, |
| 1769 FixedArrayBase* backing_store) { | 1776 FixedArrayBase* backing_store) { |
| 1770 JSArrayBufferView* view = JSArrayBufferView::cast(holder); | 1777 JSArrayBufferView* view = JSArrayBufferView::cast(holder); |
| 1771 if (view->WasNeutered()) return 0; | 1778 if (view->WasNeutered()) return 0; |
| 1772 return backing_store->length(); | 1779 return backing_store->length(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 FixedArray* parameter_map = FixedArray::cast(parameters); | 1893 FixedArray* parameter_map = FixedArray::cast(parameters); |
| 1887 uint32_t length = parameter_map->length() - 2; | 1894 uint32_t length = parameter_map->length() - 2; |
| 1888 if (entry < length) return entry; | 1895 if (entry < length) return entry; |
| 1889 | 1896 |
| 1890 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1897 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 1891 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); | 1898 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); |
| 1892 } | 1899 } |
| 1893 | 1900 |
| 1894 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1901 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
| 1895 FixedArrayBase* parameters, | 1902 FixedArrayBase* parameters, |
| 1896 uint32_t index) { | 1903 uint32_t index, |
| 1904 PropertyAttributes filter) { |
| 1897 FixedArray* parameter_map = FixedArray::cast(parameters); | 1905 FixedArray* parameter_map = FixedArray::cast(parameters); |
| 1898 Object* probe = GetParameterMapArg(parameter_map, index); | 1906 Object* probe = GetParameterMapArg(parameter_map, index); |
| 1899 if (!probe->IsTheHole()) return index; | 1907 if (!probe->IsTheHole()) return index; |
| 1900 | 1908 |
| 1901 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1909 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 1902 uint32_t entry = | 1910 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, |
| 1903 ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, index); | 1911 index, filter); |
| 1904 if (entry == kMaxUInt32) return entry; | 1912 if (entry == kMaxUInt32) return entry; |
| 1905 return (parameter_map->length() - 2) + entry; | 1913 return (parameter_map->length() - 2) + entry; |
| 1906 } | 1914 } |
| 1907 | 1915 |
| 1908 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, | 1916 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, |
| 1909 uint32_t entry) { | 1917 uint32_t entry) { |
| 1910 FixedArray* parameter_map = FixedArray::cast(parameters); | 1918 FixedArray* parameter_map = FixedArray::cast(parameters); |
| 1911 uint32_t length = parameter_map->length() - 2; | 1919 uint32_t length = parameter_map->length() - 2; |
| 1912 if (entry < length) { | 1920 if (entry < length) { |
| 1913 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 1921 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2326 } | 2334 } |
| 2327 } | 2335 } |
| 2328 | 2336 |
| 2329 DCHECK(j == result_len); | 2337 DCHECK(j == result_len); |
| 2330 return result_array; | 2338 return result_array; |
| 2331 } | 2339 } |
| 2332 | 2340 |
| 2333 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2341 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 2334 } // namespace internal | 2342 } // namespace internal |
| 2335 } // namespace v8 | 2343 } // namespace v8 |
| OLD | NEW |