OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/ic/accessor-assembler.h" | 5 #include "src/ic/accessor-assembler.h" |
6 #include "src/ic/accessor-assembler-impl.h" | 6 #include "src/ic/accessor-assembler-impl.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/ic/handler-configuration.h" | 10 #include "src/ic/handler-configuration.h" |
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
796 // Handled by if_fast_holey_double. | 796 // Handled by if_fast_holey_double. |
797 FAST_HOLEY_DOUBLE_ELEMENTS}; | 797 FAST_HOLEY_DOUBLE_ELEMENTS}; |
798 Label* labels[] = {// FAST_{SMI,}_ELEMENTS | 798 Label* labels[] = {// FAST_{SMI,}_ELEMENTS |
799 &if_fast_packed, &if_fast_packed, | 799 &if_fast_packed, &if_fast_packed, |
800 // FAST_HOLEY_{SMI,}_ELEMENTS | 800 // FAST_HOLEY_{SMI,}_ELEMENTS |
801 &if_fast_holey, &if_fast_holey, | 801 &if_fast_holey, &if_fast_holey, |
802 // FAST_DOUBLE_ELEMENTS | 802 // FAST_DOUBLE_ELEMENTS |
803 &if_fast_double, | 803 &if_fast_double, |
804 // FAST_HOLEY_DOUBLE_ELEMENTS | 804 // FAST_HOLEY_DOUBLE_ELEMENTS |
805 &if_fast_holey_double}; | 805 &if_fast_holey_double}; |
806 Switch(elements_kind, unimplemented_elements_kind, kinds, labels, | 806 Switch(TruncateWordToWord32(elements_kind), unimplemented_elements_kind, |
807 arraysize(kinds)); | 807 kinds, labels, arraysize(kinds)); |
808 | 808 |
809 Bind(&if_fast_packed); | 809 Bind(&if_fast_packed); |
810 { | 810 { |
811 Comment("fast packed elements"); | 811 Comment("fast packed elements"); |
812 Return(LoadFixedArrayElement(elements, intptr_index, 0, INTPTR_PARAMETERS)); | 812 Return(LoadFixedArrayElement(elements, intptr_index, 0, INTPTR_PARAMETERS)); |
813 } | 813 } |
814 | 814 |
815 Bind(&if_fast_holey); | 815 Bind(&if_fast_holey); |
816 { | 816 { |
817 Comment("fast holey elements"); | 817 Comment("fast holey elements"); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
874 Return(LoadFixedArrayElement(elements, value_index, 0, INTPTR_PARAMETERS)); | 874 Return(LoadFixedArrayElement(elements, value_index, 0, INTPTR_PARAMETERS)); |
875 } | 875 } |
876 | 876 |
877 Bind(&if_typed_array); | 877 Bind(&if_typed_array); |
878 { | 878 { |
879 Comment("typed elements"); | 879 Comment("typed elements"); |
880 // Check if buffer has been neutered. | 880 // Check if buffer has been neutered. |
881 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); | 881 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); |
882 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, | 882 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, |
883 MachineType::Uint32()); | 883 MachineType::Uint32()); |
884 Node* neutered_bit = | 884 GotoIf(IsSetWord32<JSArrayBuffer::WasNeutered>(bitfield), miss); |
Igor Sheludko
2016/12/07 10:20:42
Drive-by cleanup.
| |
885 Word32And(bitfield, Int32Constant(JSArrayBuffer::WasNeutered::kMask)); | |
886 GotoUnless(Word32Equal(neutered_bit, Int32Constant(0)), miss); | |
887 | 885 |
888 // Bounds check. | 886 // Bounds check. |
889 Node* length = | 887 Node* length = |
890 SmiUntag(LoadObjectField(object, JSTypedArray::kLengthOffset)); | 888 SmiUntag(LoadObjectField(object, JSTypedArray::kLengthOffset)); |
891 GotoUnless(UintPtrLessThan(intptr_index, length), out_of_bounds); | 889 GotoUnless(UintPtrLessThan(intptr_index, length), out_of_bounds); |
892 | 890 |
893 // Backing store = external_pointer + base_pointer. | 891 // Backing store = external_pointer + base_pointer. |
894 Node* external_pointer = | 892 Node* external_pointer = |
895 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, | 893 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, |
896 MachineType::Pointer()); | 894 MachineType::Pointer()); |
897 Node* base_pointer = | 895 Node* base_pointer = |
898 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); | 896 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset, |
897 MachineType::Pointer()); | |
899 Node* backing_store = IntPtrAdd(external_pointer, base_pointer); | 898 Node* backing_store = IntPtrAdd(external_pointer, base_pointer); |
900 | 899 |
901 Label uint8_elements(this), int8_elements(this), uint16_elements(this), | 900 Label uint8_elements(this), int8_elements(this), uint16_elements(this), |
902 int16_elements(this), uint32_elements(this), int32_elements(this), | 901 int16_elements(this), uint32_elements(this), int32_elements(this), |
903 float32_elements(this), float64_elements(this); | 902 float32_elements(this), float64_elements(this); |
904 Label* elements_kind_labels[] = { | 903 Label* elements_kind_labels[] = { |
905 &uint8_elements, &uint8_elements, &int8_elements, | 904 &uint8_elements, &uint8_elements, &int8_elements, |
906 &uint16_elements, &int16_elements, &uint32_elements, | 905 &uint16_elements, &int16_elements, &uint32_elements, |
907 &int32_elements, &float32_elements, &float64_elements}; | 906 &int32_elements, &float32_elements, &float64_elements}; |
908 int32_t elements_kinds[] = { | 907 int32_t elements_kinds[] = { |
909 UINT8_ELEMENTS, UINT8_CLAMPED_ELEMENTS, INT8_ELEMENTS, | 908 UINT8_ELEMENTS, UINT8_CLAMPED_ELEMENTS, INT8_ELEMENTS, |
910 UINT16_ELEMENTS, INT16_ELEMENTS, UINT32_ELEMENTS, | 909 UINT16_ELEMENTS, INT16_ELEMENTS, UINT32_ELEMENTS, |
911 INT32_ELEMENTS, FLOAT32_ELEMENTS, FLOAT64_ELEMENTS}; | 910 INT32_ELEMENTS, FLOAT32_ELEMENTS, FLOAT64_ELEMENTS}; |
912 const size_t kTypedElementsKindCount = | 911 const size_t kTypedElementsKindCount = |
913 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND - | 912 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND - |
914 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 1; | 913 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 1; |
915 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds)); | 914 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds)); |
916 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels)); | 915 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels)); |
917 Switch(elements_kind, miss, elements_kinds, elements_kind_labels, | 916 Switch(TruncateWordToWord32(elements_kind), miss, elements_kinds, |
918 kTypedElementsKindCount); | 917 elements_kind_labels, kTypedElementsKindCount); |
919 Bind(&uint8_elements); | 918 Bind(&uint8_elements); |
920 { | 919 { |
921 Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too. | 920 Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too. |
922 Return(SmiTag(Load(MachineType::Uint8(), backing_store, intptr_index))); | 921 Node* element = Load(MachineType::Uint8(), backing_store, intptr_index); |
922 Return(SmiFromWord32(element)); | |
923 } | 923 } |
924 Bind(&int8_elements); | 924 Bind(&int8_elements); |
925 { | 925 { |
926 Comment("INT8_ELEMENTS"); | 926 Comment("INT8_ELEMENTS"); |
927 Return(SmiTag(Load(MachineType::Int8(), backing_store, intptr_index))); | 927 Node* element = Load(MachineType::Int8(), backing_store, intptr_index); |
928 Return(SmiFromWord32(element)); | |
928 } | 929 } |
929 Bind(&uint16_elements); | 930 Bind(&uint16_elements); |
930 { | 931 { |
931 Comment("UINT16_ELEMENTS"); | 932 Comment("UINT16_ELEMENTS"); |
932 Node* index = WordShl(intptr_index, IntPtrConstant(1)); | 933 Node* index = WordShl(intptr_index, IntPtrConstant(1)); |
933 Return(SmiTag(Load(MachineType::Uint16(), backing_store, index))); | 934 Node* element = Load(MachineType::Uint16(), backing_store, index); |
935 Return(SmiFromWord32(element)); | |
934 } | 936 } |
935 Bind(&int16_elements); | 937 Bind(&int16_elements); |
936 { | 938 { |
937 Comment("INT16_ELEMENTS"); | 939 Comment("INT16_ELEMENTS"); |
938 Node* index = WordShl(intptr_index, IntPtrConstant(1)); | 940 Node* index = WordShl(intptr_index, IntPtrConstant(1)); |
939 Return(SmiTag(Load(MachineType::Int16(), backing_store, index))); | 941 Node* element = Load(MachineType::Int16(), backing_store, index); |
942 Return(SmiFromWord32(element)); | |
940 } | 943 } |
941 Bind(&uint32_elements); | 944 Bind(&uint32_elements); |
942 { | 945 { |
943 Comment("UINT32_ELEMENTS"); | 946 Comment("UINT32_ELEMENTS"); |
944 Node* index = WordShl(intptr_index, IntPtrConstant(2)); | 947 Node* index = WordShl(intptr_index, IntPtrConstant(2)); |
945 Node* element = Load(MachineType::Uint32(), backing_store, index); | 948 Node* element = Load(MachineType::Uint32(), backing_store, index); |
946 Return(ChangeUint32ToTagged(element)); | 949 Return(ChangeUint32ToTagged(element)); |
947 } | 950 } |
948 Bind(&int32_elements); | 951 Bind(&int32_elements); |
949 { | 952 { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1027 // Compute the hash of the name (use entire hash field). | 1030 // Compute the hash of the name (use entire hash field). |
1028 Node* hash_field = LoadNameHashField(name); | 1031 Node* hash_field = LoadNameHashField(name); |
1029 CSA_ASSERT(this, | 1032 CSA_ASSERT(this, |
1030 Word32Equal(Word32And(hash_field, | 1033 Word32Equal(Word32And(hash_field, |
1031 Int32Constant(Name::kHashNotComputedMask)), | 1034 Int32Constant(Name::kHashNotComputedMask)), |
1032 Int32Constant(0))); | 1035 Int32Constant(0))); |
1033 | 1036 |
1034 // Using only the low bits in 64-bit mode is unlikely to increase the | 1037 // Using only the low bits in 64-bit mode is unlikely to increase the |
1035 // risk of collision even if the heap is spread over an area larger than | 1038 // risk of collision even if the heap is spread over an area larger than |
1036 // 4Gb (and not at all if it isn't). | 1039 // 4Gb (and not at all if it isn't). |
1037 Node* hash = Int32Add(hash_field, map); | 1040 Node* map32 = TruncateWordToWord32(BitcastTaggedToWord(map)); |
1041 Node* hash = Int32Add(hash_field, map32); | |
1038 // Base the offset on a simple combination of name and map. | 1042 // Base the offset on a simple combination of name and map. |
1039 hash = Word32Xor(hash, Int32Constant(StubCache::kPrimaryMagic)); | 1043 hash = Word32Xor(hash, Int32Constant(StubCache::kPrimaryMagic)); |
1040 uint32_t mask = (StubCache::kPrimaryTableSize - 1) | 1044 uint32_t mask = (StubCache::kPrimaryTableSize - 1) |
1041 << StubCache::kCacheIndexShift; | 1045 << StubCache::kCacheIndexShift; |
1042 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); | 1046 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); |
1043 } | 1047 } |
1044 | 1048 |
1045 Node* AccessorAssemblerImpl::StubCacheSecondaryOffset(Node* name, Node* seed) { | 1049 Node* AccessorAssemblerImpl::StubCacheSecondaryOffset(Node* name, Node* seed) { |
1046 // See v8::internal::StubCache::SecondaryOffset(). | 1050 // See v8::internal::StubCache::SecondaryOffset(). |
1047 | 1051 |
1048 // Use the seed from the primary cache in the secondary cache. | 1052 // Use the seed from the primary cache in the secondary cache. |
1049 Node* hash = Int32Sub(seed, name); | 1053 Node* name32 = TruncateWordToWord32(BitcastTaggedToWord(name)); |
1054 Node* hash = Int32Sub(TruncateWordToWord32(seed), name32); | |
1050 hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); | 1055 hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); |
1051 int32_t mask = (StubCache::kSecondaryTableSize - 1) | 1056 int32_t mask = (StubCache::kSecondaryTableSize - 1) |
1052 << StubCache::kCacheIndexShift; | 1057 << StubCache::kCacheIndexShift; |
1053 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); | 1058 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); |
1054 } | 1059 } |
1055 | 1060 |
1056 void AccessorAssemblerImpl::TryProbeStubCacheTable( | 1061 void AccessorAssemblerImpl::TryProbeStubCacheTable( |
1057 StubCache* stub_cache, StubCacheTable table_id, Node* entry_offset, | 1062 StubCache* stub_cache, StubCacheTable table_id, Node* entry_offset, |
1058 Node* name, Node* map, Label* if_handler, Variable* var_handler, | 1063 Node* name, Node* map, Label* if_handler, Variable* var_handler, |
1059 Label* if_miss) { | 1064 Label* if_miss) { |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1505 } | 1510 } |
1506 Bind(&miss); | 1511 Bind(&miss); |
1507 { | 1512 { |
1508 TailCallRuntime(Runtime::kStoreIC_Miss, p->context, p->value, p->slot, | 1513 TailCallRuntime(Runtime::kStoreIC_Miss, p->context, p->value, p->slot, |
1509 p->vector, p->receiver, p->name); | 1514 p->vector, p->receiver, p->name); |
1510 } | 1515 } |
1511 } | 1516 } |
1512 | 1517 |
1513 void AccessorAssemblerImpl::KeyedStoreIC(const StoreICParameters* p, | 1518 void AccessorAssemblerImpl::KeyedStoreIC(const StoreICParameters* p, |
1514 LanguageMode language_mode) { | 1519 LanguageMode language_mode) { |
1515 Variable var_handler(this, MachineRepresentation::kTagged); | 1520 // TODO(ishell): defer blocks when it works. |
1516 // This is to make |miss| label see the var_handler bound on all paths. | 1521 Label miss(this /*, Label::kDeferred*/); |
1517 var_handler.Bind(IntPtrConstant(0)); | 1522 { |
Igor Sheludko
2016/12/07 10:20:42
I moved |miss| label to outer scope to avoid this
| |
1523 Variable var_handler(this, MachineRepresentation::kTagged); | |
1518 | 1524 |
1519 // TODO(ishell): defer blocks when it works. | 1525 // TODO(ishell): defer blocks when it works. |
1520 Label if_handler(this, &var_handler), try_polymorphic(this), | 1526 Label if_handler(this, &var_handler), try_polymorphic(this), |
1521 try_megamorphic(this /*, Label::kDeferred*/), | 1527 try_megamorphic(this /*, Label::kDeferred*/), |
1522 try_polymorphic_name(this /*, Label::kDeferred*/), | 1528 try_polymorphic_name(this /*, Label::kDeferred*/); |
1523 miss(this /*, Label::kDeferred*/); | |
1524 | 1529 |
1525 Node* receiver_map = LoadReceiverMap(p->receiver); | 1530 Node* receiver_map = LoadReceiverMap(p->receiver); |
1526 | 1531 |
1527 // Check monomorphic case. | 1532 // Check monomorphic case. |
1528 Node* feedback = | 1533 Node* feedback = |
1529 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, | 1534 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, |
1530 &var_handler, &try_polymorphic); | 1535 &var_handler, &try_polymorphic); |
1531 Bind(&if_handler); | 1536 Bind(&if_handler); |
1532 { | 1537 { |
1533 Comment("KeyedStoreIC_if_handler"); | 1538 Comment("KeyedStoreIC_if_handler"); |
1534 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements); | 1539 HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements); |
1535 } | 1540 } |
1536 | 1541 |
1537 Bind(&try_polymorphic); | 1542 Bind(&try_polymorphic); |
1538 { | |
1539 // CheckPolymorphic case. | |
1540 Comment("KeyedStoreIC_try_polymorphic"); | |
1541 GotoUnless( | |
1542 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), | |
1543 &try_megamorphic); | |
1544 Label if_transition_handler(this); | |
1545 Variable var_transition_map_cell(this, MachineRepresentation::kTagged); | |
1546 HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler, | |
1547 &var_handler, &if_transition_handler, | |
1548 &var_transition_map_cell, &miss); | |
1549 Bind(&if_transition_handler); | |
1550 Comment("KeyedStoreIC_polymorphic_transition"); | |
1551 { | 1543 { |
1552 Node* handler = var_handler.value(); | 1544 // CheckPolymorphic case. |
1545 Comment("KeyedStoreIC_try_polymorphic"); | |
1546 GotoUnless( | |
1547 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), | |
1548 &try_megamorphic); | |
1549 Label if_transition_handler(this); | |
1550 Variable var_transition_map_cell(this, MachineRepresentation::kTagged); | |
1551 HandleKeyedStorePolymorphicCase(receiver_map, feedback, &if_handler, | |
1552 &var_handler, &if_transition_handler, | |
1553 &var_transition_map_cell, &miss); | |
1554 Bind(&if_transition_handler); | |
1555 Comment("KeyedStoreIC_polymorphic_transition"); | |
1556 { | |
1557 Node* handler = var_handler.value(); | |
1553 | 1558 |
1554 Label call_handler(this); | 1559 Label call_handler(this); |
1555 Variable var_code_handler(this, MachineRepresentation::kTagged); | 1560 Variable var_code_handler(this, MachineRepresentation::kTagged); |
1556 var_code_handler.Bind(handler); | 1561 var_code_handler.Bind(handler); |
1557 GotoUnless(IsTuple2Map(LoadMap(handler)), &call_handler); | 1562 GotoUnless(IsTuple2Map(LoadMap(handler)), &call_handler); |
1558 { | 1563 { |
1559 CSA_ASSERT(this, IsTuple2Map(LoadMap(handler))); | 1564 CSA_ASSERT(this, IsTuple2Map(LoadMap(handler))); |
1560 | 1565 |
1561 // Check validity cell. | 1566 // Check validity cell. |
1562 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset); | 1567 Node* validity_cell = LoadObjectField(handler, Tuple2::kValue1Offset); |
1563 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); | 1568 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); |
1564 GotoIf(WordNotEqual(cell_value, SmiConstant(Map::kPrototypeChainValid)), | 1569 GotoIf( |
1565 &miss); | 1570 WordNotEqual(cell_value, SmiConstant(Map::kPrototypeChainValid)), |
1571 &miss); | |
1566 | 1572 |
1567 var_code_handler.Bind(LoadObjectField(handler, Tuple2::kValue2Offset)); | 1573 var_code_handler.Bind( |
1568 Goto(&call_handler); | 1574 LoadObjectField(handler, Tuple2::kValue2Offset)); |
1569 } | 1575 Goto(&call_handler); |
1576 } | |
1570 | 1577 |
1571 Bind(&call_handler); | 1578 Bind(&call_handler); |
1572 { | 1579 { |
1573 Node* code_handler = var_code_handler.value(); | 1580 Node* code_handler = var_code_handler.value(); |
1574 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler))); | 1581 CSA_ASSERT(this, IsCodeMap(LoadMap(code_handler))); |
1575 | 1582 |
1576 Node* transition_map = | 1583 Node* transition_map = |
1577 LoadWeakCellValue(var_transition_map_cell.value(), &miss); | 1584 LoadWeakCellValue(var_transition_map_cell.value(), &miss); |
1578 StoreTransitionDescriptor descriptor(isolate()); | 1585 StoreTransitionDescriptor descriptor(isolate()); |
1579 TailCallStub(descriptor, code_handler, p->context, p->receiver, p->name, | 1586 TailCallStub(descriptor, code_handler, p->context, p->receiver, |
1580 transition_map, p->value, p->slot, p->vector); | 1587 p->name, transition_map, p->value, p->slot, p->vector); |
1588 } | |
1581 } | 1589 } |
1582 } | 1590 } |
1591 | |
1592 Bind(&try_megamorphic); | |
1593 { | |
1594 // Check megamorphic case. | |
1595 Comment("KeyedStoreIC_try_megamorphic"); | |
1596 GotoUnless( | |
1597 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), | |
1598 &try_polymorphic_name); | |
1599 TailCallStub( | |
1600 CodeFactory::KeyedStoreIC_Megamorphic(isolate(), language_mode), | |
1601 p->context, p->receiver, p->name, p->value, p->slot, p->vector); | |
1602 } | |
1603 | |
1604 Bind(&try_polymorphic_name); | |
1605 { | |
1606 // We might have a name in feedback, and a fixed array in the next slot. | |
1607 Comment("KeyedStoreIC_try_polymorphic_name"); | |
1608 GotoUnless(WordEqual(feedback, p->name), &miss); | |
1609 // If the name comparison succeeded, we know we have a FixedArray with | |
1610 // at least one map/handler pair. | |
1611 Node* offset = ElementOffsetFromIndex( | |
1612 p->slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS, | |
1613 FixedArray::kHeaderSize + kPointerSize - kHeapObjectTag); | |
1614 Node* array = Load(MachineType::AnyTagged(), p->vector, offset); | |
1615 HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, | |
1616 &miss, 1); | |
1617 } | |
1583 } | 1618 } |
1584 | |
1585 Bind(&try_megamorphic); | |
1586 { | |
1587 // Check megamorphic case. | |
1588 Comment("KeyedStoreIC_try_megamorphic"); | |
1589 GotoUnless( | |
1590 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), | |
1591 &try_polymorphic_name); | |
1592 TailCallStub( | |
1593 CodeFactory::KeyedStoreIC_Megamorphic(isolate(), language_mode), | |
1594 p->context, p->receiver, p->name, p->value, p->slot, p->vector); | |
1595 } | |
1596 | |
1597 Bind(&try_polymorphic_name); | |
1598 { | |
1599 // We might have a name in feedback, and a fixed array in the next slot. | |
1600 Comment("KeyedStoreIC_try_polymorphic_name"); | |
1601 GotoUnless(WordEqual(feedback, p->name), &miss); | |
1602 // If the name comparison succeeded, we know we have a FixedArray with | |
1603 // at least one map/handler pair. | |
1604 Node* offset = ElementOffsetFromIndex( | |
1605 p->slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS, | |
1606 FixedArray::kHeaderSize + kPointerSize - kHeapObjectTag); | |
1607 Node* array = Load(MachineType::AnyTagged(), p->vector, offset); | |
1608 HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss, | |
1609 1); | |
1610 } | |
1611 | |
1612 Bind(&miss); | 1619 Bind(&miss); |
1613 { | 1620 { |
1614 Comment("KeyedStoreIC_miss"); | 1621 Comment("KeyedStoreIC_miss"); |
1615 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot, | 1622 TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context, p->value, p->slot, |
1616 p->vector, p->receiver, p->name); | 1623 p->vector, p->receiver, p->name); |
1617 } | 1624 } |
1618 } | 1625 } |
1619 | 1626 |
1620 //////////////////// Public methods. | 1627 //////////////////// Public methods. |
1621 | 1628 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1819 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( | 1826 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( |
1820 CodeAssemblerState* state, LanguageMode language_mode) { | 1827 CodeAssemblerState* state, LanguageMode language_mode) { |
1821 AccessorAssemblerImpl assembler(state); | 1828 AccessorAssemblerImpl assembler(state); |
1822 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); | 1829 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); |
1823 } | 1830 } |
1824 | 1831 |
1825 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE | 1832 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE |
1826 | 1833 |
1827 } // namespace internal | 1834 } // namespace internal |
1828 } // namespace v8 | 1835 } // namespace v8 |
OLD | NEW |