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

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: Addressing comments and fixing the handlers in new space issue 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 | « src/code-stub-assembler.h ('k') | src/ic/arm/handler-compiler-arm.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 #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 5068 matching lines...) Expand 10 before | Expand all | Expand 10 after
5079 // Get the map entry from the cache. 5079 // Get the map entry from the cache.
5080 DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() - 5080 DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() -
5081 stub_cache->key_reference(table).address()); 5081 stub_cache->key_reference(table).address());
5082 Node* entry_map = 5082 Node* entry_map =
5083 Load(MachineType::Pointer(), key_base, 5083 Load(MachineType::Pointer(), key_base,
5084 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize * 2))); 5084 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize * 2)));
5085 GotoIf(WordNotEqual(map, entry_map), if_miss); 5085 GotoIf(WordNotEqual(map, entry_map), if_miss);
5086 5086
5087 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() - 5087 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() -
5088 stub_cache->key_reference(table).address()); 5088 stub_cache->key_reference(table).address());
5089 Node* handler = Load(MachineType::Pointer(), key_base, 5089 Node* handler = Load(MachineType::TaggedPointer(), key_base,
5090 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize))); 5090 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize)));
5091 5091
5092 // We found the handler. 5092 // We found the handler.
5093 var_handler->Bind(handler); 5093 var_handler->Bind(handler);
5094 Goto(if_handler); 5094 Goto(if_handler);
5095 } 5095 }
5096 5096
5097 void CodeStubAssembler::TryProbeStubCache( 5097 void CodeStubAssembler::TryProbeStubCache(
5098 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name, 5098 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name,
5099 Label* if_handler, Variable* var_handler, Label* if_miss) { 5099 Label* if_handler, Variable* var_handler, Label* if_miss) {
(...skipping 423 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 check_prototypes(this);
5546 CSA_ASSERT(TaggedIsSmi(smi_handler));
5547 var_holder->Bind(holder);
5548 var_smi_handler->Bind(smi_handler);
5549
5550 GotoUnless(IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>( 5552 GotoUnless(IsSetWord<LoadHandler::DoNegativeLookupOnReceiverBits>(
5551 SmiUntag(smi_handler)), 5553 SmiUntag(smi_handler)),
5552 if_smi_handler); 5554 &check_prototypes);
5555 {
5556 // We have a dictionary receiver, do a negative lookup check.
5557 NameDictionaryNegativeLookup(p->receiver, p->name, miss);
5558 Goto(&check_prototypes);
5559 }
5553 5560
5554 NameDictionaryNegativeLookup(p->receiver, p->name, miss); 5561 Bind(&check_prototypes);
5555 Goto(if_smi_handler); 5562 Node* maybe_holder_cell =
5563 LoadObjectField(handler, LoadHandler::kHolderCellOffset);
5564 Label array_handler(this), tuple_handler(this);
5565 Branch(TaggedIsSmi(maybe_holder_cell), &array_handler, &tuple_handler);
5566
5567 Bind(&tuple_handler);
5568 {
5569 Node* holder = LoadWeakCellValue(maybe_holder_cell);
5570 // The |holder| is guaranteed to be alive at this point since we passed
5571 // both the receiver map check and the validity cell check.
5572 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0)));
5573
5574 var_holder->Bind(holder);
5575 var_smi_handler->Bind(smi_handler);
5576 Goto(if_smi_handler);
5577 }
5578
5579 Bind(&array_handler);
5580 {
5581 Node* length = SmiUntag(maybe_holder_cell);
5582 BuildFastLoop(MachineType::PointerRepresentation(),
5583 IntPtrConstant(LoadHandler::kFirstPrototypeIndex), length,
5584 [this, p, handler, miss](CodeStubAssembler*, Node* current) {
5585 Node* prototype_cell = LoadFixedArrayElement(
5586 handler, current, 0, INTPTR_PARAMETERS);
5587 CheckPrototype(prototype_cell, p->name, miss);
5588 },
5589 1, IndexAdvanceMode::kPost);
5590
5591 Node* holder_cell = LoadFixedArrayElement(
5592 handler, IntPtrConstant(LoadHandler::kHolderCellIndex), 0,
5593 INTPTR_PARAMETERS);
5594 Node* holder = LoadWeakCellValue(holder_cell);
5595 // The |holder| is guaranteed to be alive at this point since we passed
5596 // the receiver map check, the validity cell check and the prototype chain
5597 // check.
5598 CSA_ASSERT(WordNotEqual(holder, IntPtrConstant(0)));
5599
5600 var_holder->Bind(holder);
5601 var_smi_handler->Bind(smi_handler);
5602 Goto(if_smi_handler);
5603 }
5604 }
5605
5606 void CodeStubAssembler::CheckPrototype(Node* prototype_cell, Node* name,
5607 Label* miss) {
5608 Node* maybe_prototype = LoadWeakCellValue(prototype_cell, miss);
5609
5610 Label done(this);
5611 Label if_property_cell(this), if_dictionary_object(this);
5612
5613 // |maybe_prototype| is either a PropertyCell or a slow-mode prototype.
5614 Branch(WordEqual(LoadMap(maybe_prototype),
5615 LoadRoot(Heap::kGlobalPropertyCellMapRootIndex)),
5616 &if_property_cell, &if_dictionary_object);
5617
5618 Bind(&if_dictionary_object);
5619 {
5620 NameDictionaryNegativeLookup(maybe_prototype, name, miss);
5621 Goto(&done);
5622 }
5623
5624 Bind(&if_property_cell);
5625 {
5626 // Ensure the property cell still contains the hole.
5627 Node* value = LoadObjectField(maybe_prototype, PropertyCell::kValueOffset);
5628 GotoIf(WordNotEqual(value, LoadRoot(Heap::kTheHoleValueRootIndex)), miss);
5629 Goto(&done);
5630 }
5631
5632 Bind(&done);
5556 } 5633 }
5557 5634
5558 void CodeStubAssembler::NameDictionaryNegativeLookup(Node* object, Node* name, 5635 void CodeStubAssembler::NameDictionaryNegativeLookup(Node* object, Node* name,
5559 Label* miss) { 5636 Label* miss) {
5560 CSA_ASSERT(IsDictionaryMap(LoadMap(object))); 5637 CSA_ASSERT(IsDictionaryMap(LoadMap(object)));
5561 Node* properties = LoadProperties(object); 5638 Node* properties = LoadProperties(object);
5562 // Ensure the property does not exist in a dictionary-mode object. 5639 // Ensure the property does not exist in a dictionary-mode object.
5563 Variable var_name_index(this, MachineType::PointerRepresentation()); 5640 Variable var_name_index(this, MachineType::PointerRepresentation());
5564 Label done(this); 5641 Label done(this);
5565 NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index, 5642 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( 8651 Node* buffer_bit_field = LoadObjectField(
8575 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); 8652 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
8576 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); 8653 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask);
8577 8654
8578 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), 8655 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask),
8579 Int32Constant(0)); 8656 Int32Constant(0));
8580 } 8657 }
8581 8658
8582 } // namespace internal 8659 } // namespace internal
8583 } // namespace v8 8660 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/ic/arm/handler-compiler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698