| 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
| 5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
| 7 #include "src/frames.h" | 7 #include "src/frames.h" |
| 8 #include "src/ic/handler-configuration.h" | 8 #include "src/ic/handler-configuration.h" |
| 9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
| 10 | 10 |
| (...skipping 5590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5601 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); | 5601 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); |
| 5602 | 5602 |
| 5603 // IC dispatchers rely on these assumptions to be held. | 5603 // IC dispatchers rely on these assumptions to be held. |
| 5604 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); | 5604 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset); |
| 5605 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), | 5605 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex), |
| 5606 LoadHandler::kSmiHandlerOffset); | 5606 LoadHandler::kSmiHandlerOffset); |
| 5607 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex), | 5607 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex), |
| 5608 LoadHandler::kValidityCellOffset); | 5608 LoadHandler::kValidityCellOffset); |
| 5609 | 5609 |
| 5610 // Both FixedArray and Tuple3 handlers have validity cell at the same offset. | 5610 // Both FixedArray and Tuple3 handlers have validity cell at the same offset. |
| 5611 Label validity_cell_check_done(this); |
| 5611 Node* validity_cell = | 5612 Node* validity_cell = |
| 5612 LoadObjectField(handler, LoadHandler::kValidityCellOffset); | 5613 LoadObjectField(handler, LoadHandler::kValidityCellOffset); |
| 5614 GotoIf(WordEqual(validity_cell, IntPtrConstant(0)), |
| 5615 &validity_cell_check_done); |
| 5613 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); | 5616 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); |
| 5614 GotoIf(WordNotEqual(cell_value, | 5617 GotoIf(WordNotEqual(cell_value, |
| 5615 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), | 5618 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), |
| 5616 miss); | 5619 miss); |
| 5620 Goto(&validity_cell_check_done); |
| 5617 | 5621 |
| 5622 Bind(&validity_cell_check_done); |
| 5618 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); | 5623 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset); |
| 5619 CSA_ASSERT(TaggedIsSmi(smi_handler)); | 5624 CSA_ASSERT(TaggedIsSmi(smi_handler)); |
| 5620 | 5625 |
| 5621 Label check_prototypes(this); | 5626 Label check_prototypes(this); |
| 5622 GotoUnless(IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>( | 5627 GotoUnless(IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>( |
| 5623 SmiUntag(smi_handler)), | 5628 SmiUntag(smi_handler)), |
| 5624 &check_prototypes); | 5629 &check_prototypes); |
| 5625 { | 5630 { |
| 5626 // We have a dictionary receiver, do a negative lookup check. | 5631 // We have a dictionary receiver, do a negative lookup check. |
| 5627 NameDictionaryNegativeLookup(p->receiver, p->name, miss); | 5632 NameDictionaryNegativeLookup(p->receiver, p->name, miss); |
| 5628 Goto(&check_prototypes); | 5633 Goto(&check_prototypes); |
| 5629 } | 5634 } |
| 5630 | 5635 |
| 5631 Bind(&check_prototypes); | 5636 Bind(&check_prototypes); |
| 5632 Node* maybe_holder_cell = | 5637 Node* maybe_holder_cell = |
| 5633 LoadObjectField(handler, LoadHandler::kHolderCellOffset); | 5638 LoadObjectField(handler, LoadHandler::kHolderCellOffset); |
| 5634 Label array_handler(this), tuple_handler(this); | 5639 Label array_handler(this), tuple_handler(this); |
| 5635 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler); | 5640 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler); |
| 5636 | 5641 |
| 5637 Bind(&tuple_handler); | 5642 Bind(&tuple_handler); |
| 5638 { | 5643 { |
| 5644 Label load_existent(this); |
| 5645 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); |
| 5646 // This is a handler for a load of a non-existent value. |
| 5647 Return(UndefinedConstant()); |
| 5648 |
| 5649 Bind(&load_existent); |
| 5639 Node* holder = LoadWeakCellValue(maybe_holder_cell); | 5650 Node* holder = LoadWeakCellValue(maybe_holder_cell); |
| 5640 // The |holder| is guaranteed to be alive at this point since we passed | 5651 // The |holder| is guaranteed to be alive at this point since we passed |
| 5641 // both the receiver map check and the validity cell check. | 5652 // both the receiver map check and the validity cell check. |
| 5642 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0))); | 5653 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0))); |
| 5643 | 5654 |
| 5644 var_holder->Bind(holder); | 5655 var_holder->Bind(holder); |
| 5645 var_smi_handler->Bind(smi_handler); | 5656 var_smi_handler->Bind(smi_handler); |
| 5646 Goto(if_smi_handler); | 5657 Goto(if_smi_handler); |
| 5647 } | 5658 } |
| 5648 | 5659 |
| 5649 Bind(&array_handler); | 5660 Bind(&array_handler); |
| 5650 { | 5661 { |
| 5651 Node* length = SmiUntag(maybe_holder_cell); | 5662 Node* length = SmiUntag(maybe_holder_cell); |
| 5652 BuildFastLoop(MachineType::PointerRepresentation(), | 5663 BuildFastLoop(MachineType::PointerRepresentation(), |
| 5653 IntPtrConstant(LoadHandler::kFirstPrototypeIndex), length, | 5664 IntPtrConstant(LoadHandler::kFirstPrototypeIndex), length, |
| 5654 [this, p, handler, miss](CodeStubAssembler*, Node* current) { | 5665 [this, p, handler, miss](CodeStubAssembler*, Node* current) { |
| 5655 Node* prototype_cell = LoadFixedArrayElement( | 5666 Node* prototype_cell = LoadFixedArrayElement( |
| 5656 handler, current, 0, INTPTR_PARAMETERS); | 5667 handler, current, 0, INTPTR_PARAMETERS); |
| 5657 CheckPrototype(prototype_cell, p->name, miss); | 5668 CheckPrototype(prototype_cell, p->name, miss); |
| 5658 }, | 5669 }, |
| 5659 1, IndexAdvanceMode::kPost); | 5670 1, IndexAdvanceMode::kPost); |
| 5660 | 5671 |
| 5661 Node* holder_cell = LoadFixedArrayElement( | 5672 Node* maybe_holder_cell = LoadFixedArrayElement( |
| 5662 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0, | 5673 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0, |
| 5663 INTPTR_PARAMETERS); | 5674 INTPTR_PARAMETERS); |
| 5664 Node* holder = LoadWeakCellValue(holder_cell); | 5675 Label load_existent(this); |
| 5676 GotoIf(WordNotEqual(maybe_holder_cell, NullConstant()), &load_existent); |
| 5677 // This is a handler for a load of a non-existent value. |
| 5678 Return(UndefinedConstant()); |
| 5679 |
| 5680 Bind(&load_existent); |
| 5681 Node* holder = LoadWeakCellValue(maybe_holder_cell); |
| 5665 // The |holder| is guaranteed to be alive at this point since we passed | 5682 // The |holder| is guaranteed to be alive at this point since we passed |
| 5666 // the receiver map check, the validity cell check and the prototype chain | 5683 // the receiver map check, the validity cell check and the prototype chain |
| 5667 // check. | 5684 // check. |
| 5668 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0))); | 5685 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0))); |
| 5669 | 5686 |
| 5670 var_holder->Bind(holder); | 5687 var_holder->Bind(holder); |
| 5671 var_smi_handler->Bind(smi_handler); | 5688 var_smi_handler->Bind(smi_handler); |
| 5672 Goto(if_smi_handler); | 5689 Goto(if_smi_handler); |
| 5673 } | 5690 } |
| 5674 } | 5691 } |
| (...skipping 3049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8724 Node* buffer_bit_field = LoadObjectField( | 8741 Node* buffer_bit_field = LoadObjectField( |
| 8725 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 8742 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
| 8726 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 8743 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); |
| 8727 | 8744 |
| 8728 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | 8745 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), |
| 8729 Int32Constant(0)); | 8746 Int32Constant(0)); |
| 8730 } | 8747 } |
| 8731 | 8748 |
| 8732 } // namespace internal | 8749 } // namespace internal |
| 8733 } // namespace v8 | 8750 } // namespace v8 |
| OLD | NEW |