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

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

Issue 2449463002: [ic] Load IC data handlers now support prototype chain checks with global and dictionary objects. (Closed)
Patch Set: 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
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 5512 matching lines...) Expand 10 before | Expand all | Expand 10 after
5523 Arg(Descriptor::kVector, p->vector)); 5523 Arg(Descriptor::kVector, p->vector));
5524 } 5524 }
5525 } 5525 }
5526 5526
5527 void CodeStubAssembler::HandleLoadICProtoHandler( 5527 void CodeStubAssembler::HandleLoadICProtoHandler(
5528 const LoadICParameters* p, Node* handler, Variable* var_holder, 5528 const LoadICParameters* p, Node* handler, Variable* var_holder,
5529 Variable* var_smi_handler, Label* if_smi_handler, Label* miss) { 5529 Variable* var_smi_handler, Label* if_smi_handler, Label* miss) {
5530 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); 5530 DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep());
5531 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); 5531 DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep());
5532 5532
5533 Node* validity_cell = LoadObjectField(handler, Tuple3::kValue1Offset); 5533 // IC dispatchers rely on these assumptions to be held.
5534 STATIC_ASSERT(FixedArray::kLengthOffset == LoadHandler::kHolderCellOffset);
5535 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kSmiHandlerIndex),
5536 LoadHandler::kSmiHandlerOffset);
5537 DCHECK_EQ(FixedArray::OffsetOfElementAt(LoadHandler::kValidityCellIndex),
5538 LoadHandler::kValidityCellOffset);
5539
5540 // Both FixedArray and Tuple3 handlers have validity cell at the same offset.
5541 Node* validity_cell =
5542 LoadObjectField(handler, LoadHandler::kValidityCellOffset);
5534 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); 5543 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset);
5535 GotoIf(WordNotEqual(cell_value, 5544 GotoIf(WordNotEqual(cell_value,
5536 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), 5545 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))),
5537 miss); 5546 miss);
5538 5547
5539 Node* holder = 5548 Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset);
5540 LoadWeakCellValue(LoadObjectField(handler, Tuple3::kValue2Offset)); 5549 CSA_ASSERT(TaggedIsSmi(smi_handler));
5541 // The |holder| is guaranteed to be alive at this point since we passed
5542 // both the receiver map check and the validity cell check.
5543 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0)));
5544 5550
5545 Node* smi_handler = LoadObjectField(handler, Tuple3::kValue3Offset); 5551 Label if_negative_lookup_on_receiver(this), if_check_prototypes(this);
5546 CSA_ASSERT(TaggedIsSmi(smi_handler)); 5552 Branch(IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>(
5547 var_holder->Bind(holder); 5553 SmiUntag(smi_handler)),
5548 var_smi_handler->Bind(smi_handler); 5554 &if_negative_lookup_on_receiver, &if_check_prototypes);
5549 5555
5550 GotoUnless(IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>( 5556 Bind(&if_check_prototypes);
5551 SmiUntag(smi_handler)),
5552 if_smi_handler);
5553 5557
5554 NameDictionaryNegativeLookup(p->receiver, p->name, miss); 5558 Node* maybe_holder_cell =
5555 Goto(if_smi_handler); 5559 LoadObjectField(handler, LoadHandler::kHolderCellOffset);
5560 Label array_handler(this), tuple_handler(this);
5561 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler);
5562
5563 Bind(&if_negative_lookup_on_receiver);
Jakob Kummerow 2016/10/27 11:30:54 nit: I'd put this above the "Bind(&if_check_protot
Igor Sheludko 2016/10/27 14:55:30 Done.
5564 {
5565 NameDictionaryNegativeLookup(p->receiver, p->name, miss);
5566 Goto(&if_check_prototypes);
5567 }
5568
5569 Bind(&tuple_handler);
5570 {
5571 Node* holder = LoadWeakCellValue(maybe_holder_cell);
5572 // The |holder| is guaranteed to be alive at this point since we passed
5573 // both the receiver map check and the validity cell check.
5574 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0)));
5575
5576 var_holder->Bind(holder);
5577 var_smi_handler->Bind(smi_handler);
5578 Goto(if_smi_handler);
5579 }
5580
5581 Bind(&array_handler);
5582 {
5583 Node* length = SmiUntag(maybe_holder_cell);
5584 BuildFastLoop(MachineType::PointerRepresentation(),
5585 IntPtrConstant(LoadHandler::kFirstPrototypeIndex), length,
5586 [this, p, handler, miss](CodeStubAssembler*, Node* current) {
5587 Node* prototype_cell = LoadFixedArrayElement(
5588 handler, current, 0, INTPTR_PARAMETERS);
5589 CheckPrototype(prototype_cell, p->name, miss);
5590 },
5591 1, IndexAdvanceMode::kPost);
5592
5593 Node* holder_cell = LoadFixedArrayElement(
5594 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0,
5595 INTPTR_PARAMETERS);
5596 Node* holder = LoadWeakCellValue(holder_cell);
5597 // The |holder| is guaranteed to be alive at this point since we passed
5598 // the receiver map check, the validity cell check and the prototype chain
5599 // check.
5600 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0)));
5601
5602 var_holder->Bind(holder);
5603 var_smi_handler->Bind(smi_handler);
5604 Goto(if_smi_handler);
5605 }
5606 }
5607
5608 void CodeStubAssembler::CheckPrototype(Node* prototype_cell, Node* name,
5609 Label* miss) {
5610 Node* maybe_prototype = LoadWeakCellValue(prototype_cell, miss);
5611
5612 Label done(this);
5613 Label if_property_cell(this), if_dictionary_object(this);
5614
5615 // |maybe_prototype| is either a PropertyCell or a slow-mode prototype.
5616 Branch(WordEqual(LoadMap(maybe_prototype),
5617 LoadRoot(Heap::kGlobalPropertyCellMapRootIndex)),
5618 &if_property_cell, &if_dictionary_object);
5619
5620 Bind(&if_dictionary_object);
5621 {
5622 NameDictionaryNegativeLookup(maybe_prototype, name, miss);
5623 Goto(&done);
5624 }
5625
5626 Bind(&if_property_cell);
5627 {
5628 // Ensure the property cell still contains the hole.
5629 Node* value = LoadObjectField(maybe_prototype, PropertyCell::kValueOffset);
5630 Branch(WordEqual(value, LoadRoot(Heap::kTheHoleValueRootIndex)), &done,
Jakob Kummerow 2016/10/27 11:30:53 Is there a reason you prefer this Branch() over "G
Igor Sheludko 2016/10/27 14:55:30 Because it has to be followed by Goto(&done) anywa
5631 miss);
5632 }
5633
5634 Bind(&done);
5556 } 5635 }
5557 5636
5558 void CodeStubAssembler::NameDictionaryNegativeLookup(Node* object, Node* name, 5637 void CodeStubAssembler::NameDictionaryNegativeLookup(Node* object, Node* name,
5559 Label* miss) { 5638 Label* miss) {
5560 CSA_ASSERT(IsDictionaryMap(LoadMap(object))); 5639 CSA_ASSERT(IsDictionaryMap(LoadMap(object)));
5561 Node* properties = LoadProperties(object); 5640 Node* properties = LoadProperties(object);
5562 // Ensure the property does not exist in a dictionary-mode object. 5641 // Ensure the property does not exist in a dictionary-mode object.
5563 Variable var_name_index(this, MachineType::PointerRepresentation()); 5642 Variable var_name_index(this, MachineType::PointerRepresentation());
5564 Label done(this); 5643 Label done(this);
5565 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index, 5644 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index,
(...skipping 3008 matching lines...) Expand 10 before | Expand all | Expand 10 after
8574 Node* buffer_bit_field = LoadObjectField( 8653 Node* buffer_bit_field = LoadObjectField(
8575 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); 8654 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
8576 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); 8655 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask);
8577 8656
8578 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), 8657 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask),
8579 Int32Constant(0)); 8658 Int32Constant(0));
8580 } 8659 }
8581 8660
8582 } // namespace internal 8661 } // namespace internal
8583 } // namespace v8 8662 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/ic/arm/handler-compiler-arm.cc » ('j') | src/ic/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698