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 |