Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/ic/accessor-assembler.cc

Issue 2560663002: [stubs] Fix issues found by the machine graph verifier in load/store IC stubs. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/code-stub-assembler.cc ('k') | test/cctest/test-code-stub-assembler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/code-stub-assembler.cc ('k') | test/cctest/test-code-stub-assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698