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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2471613006: [ic] Data handlers for loads of non-existent properties. (Closed)
Patch Set: Addressing comments Created 4 years, 1 month 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 | « no previous file | src/counters.h » ('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 #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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/counters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698