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

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

Issue 2419513002: [ic] Support data handlers that represent loads from prototypes. (Closed)
Patch Set: Created 4 years, 2 months 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 4
5 #include "src/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 4346 matching lines...) Expand 10 before | Expand all | Expand 10 after
4357 // Get the map entry from the cache. 4357 // Get the map entry from the cache.
4358 DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() - 4358 DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() -
4359 stub_cache->key_reference(table).address()); 4359 stub_cache->key_reference(table).address());
4360 Node* entry_map = 4360 Node* entry_map =
4361 Load(MachineType::Pointer(), key_base, 4361 Load(MachineType::Pointer(), key_base,
4362 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize * 2))); 4362 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize * 2)));
4363 GotoIf(WordNotEqual(map, entry_map), if_miss); 4363 GotoIf(WordNotEqual(map, entry_map), if_miss);
4364 4364
4365 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() - 4365 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() -
4366 stub_cache->key_reference(table).address()); 4366 stub_cache->key_reference(table).address());
4367 Node* code = Load(MachineType::Pointer(), key_base, 4367 Node* handler = Load(MachineType::Pointer(), key_base,
4368 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize))); 4368 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize)));
4369 4369
4370 // We found the handler. 4370 // We found the handler.
4371 var_handler->Bind(code); 4371 var_handler->Bind(handler);
4372 Goto(if_handler); 4372 Goto(if_handler);
4373 } 4373 }
4374 4374
4375 void CodeStubAssembler::TryProbeStubCache( 4375 void CodeStubAssembler::TryProbeStubCache(
4376 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name, 4376 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name,
4377 Label* if_handler, Variable* var_handler, Label* if_miss) { 4377 Label* if_handler, Variable* var_handler, Label* if_miss) {
4378 Label try_secondary(this), miss(this); 4378 Label try_secondary(this), miss(this);
4379 4379
4380 Counters* counters = isolate()->counters(); 4380 Counters* counters = isolate()->counters();
4381 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); 4381 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4647 var_double_value->Bind(element); 4647 var_double_value->Bind(element);
4648 Goto(rebox_double); 4648 Goto(rebox_double);
4649 } 4649 }
4650 } 4650 }
4651 } 4651 }
4652 4652
4653 void CodeStubAssembler::HandleLoadICHandlerCase( 4653 void CodeStubAssembler::HandleLoadICHandlerCase(
4654 const LoadICParameters* p, Node* handler, Label* miss, 4654 const LoadICParameters* p, Node* handler, Label* miss,
4655 ElementSupport support_elements) { 4655 ElementSupport support_elements) {
4656 Comment("have_handler"); 4656 Comment("have_handler");
4657 Label call_handler(this); 4657 Variable var_holder(this, MachineRepresentation::kTagged);
4658 GotoUnless(TaggedIsSmi(handler), &call_handler); 4658 var_holder.Bind(p->receiver);
4659 Variable var_handler(this, MachineRepresentation::kTagged);
4660 var_handler.Bind(handler);
4661
4662 Variable* vars[] = {&var_holder, &var_handler};
4663 Label if_smi_handler(this, 2, vars);
4664 Label try_proto_cell_handler(this), call_handler(this);
4665
4666 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_cell_handler);
4659 4667
4660 // |handler| is a Smi, encoding what to do. See handler-configuration.h 4668 // |handler| is a Smi, encoding what to do. See handler-configuration.h
4661 // for the encoding format. 4669 // for the encoding format.
4670 Bind(&if_smi_handler);
4662 { 4671 {
4672 Node* holder = var_holder.value();
4673 Node* handler = var_handler.value();
Jakob Kummerow 2016/10/13 11:59:26 nit: This (and its two friends in 4770 and 4794) s
Igor Sheludko 2016/10/13 13:20:38 Done.
4663 Variable var_double_value(this, MachineRepresentation::kFloat64); 4674 Variable var_double_value(this, MachineRepresentation::kFloat64);
4664 Label rebox_double(this, &var_double_value); 4675 Label rebox_double(this, &var_double_value);
4665 4676
4666 Node* handler_word = SmiUntag(handler); 4677 Node* handler_word = SmiUntag(handler);
4667 if (support_elements == kSupportElements) { 4678 if (support_elements == kSupportElements) {
4668 Label property(this); 4679 Label property(this);
4669 Node* handler_type = 4680 Node* handler_type =
4670 WordAnd(handler_word, IntPtrConstant(LoadHandlerTypeBit::kMask)); 4681 WordAnd(handler_word, IntPtrConstant(LoadHandlerTypeBit::kMask));
4671 GotoUnless( 4682 GotoUnless(
4672 WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)), 4683 WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)),
4673 &property); 4684 &property);
4674 4685
4675 Comment("element_load"); 4686 Comment("element_load");
4676 Node* intptr_index = TryToIntptr(p->name, miss); 4687 Node* intptr_index = TryToIntptr(p->name, miss);
4677 Node* elements = LoadElements(p->receiver); 4688 Node* elements = LoadElements(holder);
4678 Node* is_jsarray = 4689 Node* is_jsarray =
4679 WordAnd(handler_word, IntPtrConstant(KeyedLoadIsJsArray::kMask)); 4690 WordAnd(handler_word, IntPtrConstant(KeyedLoadIsJsArray::kMask));
4680 Node* is_jsarray_condition = WordNotEqual(is_jsarray, IntPtrConstant(0)); 4691 Node* is_jsarray_condition = WordNotEqual(is_jsarray, IntPtrConstant(0));
4681 Node* elements_kind = BitFieldDecode<KeyedLoadElementsKind>(handler_word); 4692 Node* elements_kind = BitFieldDecode<KeyedLoadElementsKind>(handler_word);
4682 Label if_hole(this), unimplemented_elements_kind(this); 4693 Label if_hole(this), unimplemented_elements_kind(this);
4683 Label* out_of_bounds = miss; 4694 Label* out_of_bounds = miss;
4684 EmitElementLoad(p->receiver, elements, elements_kind, intptr_index, 4695 EmitElementLoad(holder, elements, elements_kind, intptr_index,
4685 is_jsarray_condition, &if_hole, &rebox_double, 4696 is_jsarray_condition, &if_hole, &rebox_double,
4686 &var_double_value, &unimplemented_elements_kind, 4697 &var_double_value, &unimplemented_elements_kind,
4687 out_of_bounds, miss); 4698 out_of_bounds, miss);
4688 4699
4689 Bind(&unimplemented_elements_kind); 4700 Bind(&unimplemented_elements_kind);
4690 { 4701 {
4691 // Smi handlers should only be installed for supported elements kinds. 4702 // Smi handlers should only be installed for supported elements kinds.
4692 // Crash if we get here. 4703 // Crash if we get here.
4693 DebugBreak(); 4704 DebugBreak();
4694 Goto(miss); 4705 Goto(miss);
(...skipping 26 matching lines...) Expand all
4721 Node* inobject_bit = 4732 Node* inobject_bit =
4722 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsInobject::kMask)); 4733 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsInobject::kMask));
4723 Node* double_bit = 4734 Node* double_bit =
4724 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsDouble::kMask)); 4735 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsDouble::kMask));
4725 Node* offset = 4736 Node* offset =
4726 WordSar(handler_word, IntPtrConstant(FieldOffsetOffset::kShift)); 4737 WordSar(handler_word, IntPtrConstant(FieldOffsetOffset::kShift));
4727 4738
4728 GotoIf(WordEqual(inobject_bit, IntPtrConstant(0)), &out_of_object); 4739 GotoIf(WordEqual(inobject_bit, IntPtrConstant(0)), &out_of_object);
4729 4740
4730 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), &inobject_double); 4741 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), &inobject_double);
4731 Return(LoadObjectField(p->receiver, offset)); 4742 Return(LoadObjectField(holder, offset));
4732 4743
4733 Bind(&inobject_double); 4744 Bind(&inobject_double);
4734 if (FLAG_unbox_double_fields) { 4745 if (FLAG_unbox_double_fields) {
4735 var_double_value.Bind( 4746 var_double_value.Bind(
4736 LoadObjectField(p->receiver, offset, MachineType::Float64())); 4747 LoadObjectField(holder, offset, MachineType::Float64()));
4737 } else { 4748 } else {
4738 Node* mutable_heap_number = LoadObjectField(p->receiver, offset); 4749 Node* mutable_heap_number = LoadObjectField(holder, offset);
4739 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); 4750 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
4740 } 4751 }
4741 Goto(&rebox_double); 4752 Goto(&rebox_double);
4742 4753
4743 Bind(&out_of_object); 4754 Bind(&out_of_object);
4744 Node* properties = LoadProperties(p->receiver); 4755 Node* properties = LoadProperties(holder);
4745 Node* value = LoadObjectField(properties, offset); 4756 Node* value = LoadObjectField(properties, offset);
4746 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), &out_of_object_double); 4757 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), &out_of_object_double);
4747 Return(value); 4758 Return(value);
4748 4759
4749 Bind(&out_of_object_double); 4760 Bind(&out_of_object_double);
4750 var_double_value.Bind(LoadHeapNumberValue(value)); 4761 var_double_value.Bind(LoadHeapNumberValue(value));
4751 Goto(&rebox_double); 4762 Goto(&rebox_double);
4752 4763
4753 Bind(&rebox_double); 4764 Bind(&rebox_double);
4754 Return(AllocateHeapNumberWithValue(var_double_value.value())); 4765 Return(AllocateHeapNumberWithValue(var_double_value.value()));
4755 } 4766 }
4756 4767
4768 Bind(&try_proto_cell_handler);
4769 {
4770 Node* handler = var_handler.value();
4771 GotoIf(WordNotEqual(LoadMap(handler), LoadRoot(Heap::kTuple3MapRootIndex)),
4772 &call_handler);
4773 Node* validity_cell = LoadObjectField(handler, Tuple3::kValue1Offset);
4774 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset);
4775 GotoIf(WordNotEqual(cell_value,
4776 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))),
4777 miss);
4778
4779 Node* holder =
4780 LoadWeakCellValue(LoadObjectField(handler, Tuple3::kValue2Offset));
4781 Assert(WordNotEqual(holder, IntPtrConstant(0)));
Jakob Kummerow 2016/10/13 11:59:26 Why is it guaranteed that this WeakCell has not be
Igor Sheludko 2016/10/13 13:20:38 Done.
4782
4783 Node* smi_handler = LoadObjectField(handler, Tuple3::kValue3Offset);
4784 Assert(TaggedIsSmi(smi_handler));
4785
4786 var_holder.Bind(holder);
4787 var_handler.Bind(smi_handler);
4788 Goto(&if_smi_handler);
4789 }
4790
4757 // |handler| is a heap object. Must be code, call it. 4791 // |handler| is a heap object. Must be code, call it.
4758 Bind(&call_handler); 4792 Bind(&call_handler);
4759 typedef LoadWithVectorDescriptor Descriptor; 4793 {
4760 TailCallStub(Descriptor(isolate()), handler, p->context, 4794 Node* handler = var_handler.value();
4761 Arg(Descriptor::kReceiver, p->receiver), 4795 typedef LoadWithVectorDescriptor Descriptor;
4762 Arg(Descriptor::kName, p->name), 4796 TailCallStub(Descriptor(isolate()), handler, p->context,
4763 Arg(Descriptor::kSlot, p->slot), 4797 Arg(Descriptor::kReceiver, p->receiver),
4764 Arg(Descriptor::kVector, p->vector)); 4798 Arg(Descriptor::kName, p->name),
4799 Arg(Descriptor::kSlot, p->slot),
4800 Arg(Descriptor::kVector, p->vector));
4801 }
4765 } 4802 }
4766 4803
4767 void CodeStubAssembler::LoadIC(const LoadICParameters* p) { 4804 void CodeStubAssembler::LoadIC(const LoadICParameters* p) {
4768 Variable var_handler(this, MachineRepresentation::kTagged); 4805 Variable var_handler(this, MachineRepresentation::kTagged);
4769 // TODO(ishell): defer blocks when it works. 4806 // TODO(ishell): defer blocks when it works.
4770 Label if_handler(this, &var_handler), try_polymorphic(this), 4807 Label if_handler(this, &var_handler), try_polymorphic(this),
4771 try_megamorphic(this /*, Label::kDeferred*/), 4808 try_megamorphic(this /*, Label::kDeferred*/),
4772 miss(this /*, Label::kDeferred*/); 4809 miss(this /*, Label::kDeferred*/);
4773 4810
4774 Node* receiver_map = LoadReceiverMap(p->receiver); 4811 Node* receiver_map = LoadReceiverMap(p->receiver);
(...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after
7237 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); 7274 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable));
7238 Goto(&end); 7275 Goto(&end);
7239 } 7276 }
7240 7277
7241 Bind(&end); 7278 Bind(&end);
7242 return result.value(); 7279 return result.value();
7243 } 7280 }
7244 7281
7245 } // namespace internal 7282 } // namespace internal
7246 } // namespace v8 7283 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/ast-types.cc ('k') | src/compiler/types.cc » ('j') | src/ic/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698