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 | 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 4818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4829 var_holder.Bind(p->receiver); | 4829 var_holder.Bind(p->receiver); |
4830 Variable var_smi_handler(this, MachineRepresentation::kTagged); | 4830 Variable var_smi_handler(this, MachineRepresentation::kTagged); |
4831 var_smi_handler.Bind(handler); | 4831 var_smi_handler.Bind(handler); |
4832 | 4832 |
4833 Variable* vars[] = {&var_holder, &var_smi_handler}; | 4833 Variable* vars[] = {&var_holder, &var_smi_handler}; |
4834 Label if_smi_handler(this, 2, vars); | 4834 Label if_smi_handler(this, 2, vars); |
4835 Label try_proto_cell_handler(this), call_handler(this); | 4835 Label try_proto_cell_handler(this), call_handler(this); |
4836 | 4836 |
4837 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_cell_handler); | 4837 Branch(TaggedIsSmi(handler), &if_smi_handler, &try_proto_cell_handler); |
4838 | 4838 |
4839 // |handler| is a Smi, encoding what to do. See handler-configuration.h | 4839 // |handler| is a Smi, encoding what to do. See SmiHandler methods |
4840 // for the encoding format. | 4840 // for the encoding format. |
4841 Bind(&if_smi_handler); | 4841 Bind(&if_smi_handler); |
4842 { | 4842 { |
4843 Variable var_double_value(this, MachineRepresentation::kFloat64); | 4843 Variable var_double_value(this, MachineRepresentation::kFloat64); |
4844 Label rebox_double(this, &var_double_value); | 4844 Label rebox_double(this, &var_double_value); |
4845 | 4845 |
4846 Node* holder = var_holder.value(); | 4846 Node* holder = var_holder.value(); |
4847 Node* handler_word = SmiUntag(var_smi_handler.value()); | 4847 Node* handler_word = SmiUntag(var_smi_handler.value()); |
| 4848 Node* handler_type = |
| 4849 WordAnd(handler_word, IntPtrConstant(LoadHandlerTypeBits::kMask)); |
4848 if (support_elements == kSupportElements) { | 4850 if (support_elements == kSupportElements) { |
4849 Label property(this); | 4851 Label property(this); |
4850 Node* handler_type = | |
4851 WordAnd(handler_word, IntPtrConstant(LoadHandlerTypeBit::kMask)); | |
4852 GotoUnless( | 4852 GotoUnless( |
4853 WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)), | 4853 WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)), |
4854 &property); | 4854 &property); |
4855 | 4855 |
4856 Comment("element_load"); | 4856 Comment("element_load"); |
4857 Node* intptr_index = TryToIntptr(p->name, miss); | 4857 Node* intptr_index = TryToIntptr(p->name, miss); |
4858 Node* elements = LoadElements(holder); | 4858 Node* elements = LoadElements(holder); |
4859 Node* is_jsarray = | 4859 Node* is_jsarray = |
4860 WordAnd(handler_word, IntPtrConstant(KeyedLoadIsJsArray::kMask)); | 4860 WordAnd(handler_word, IntPtrConstant(KeyedLoadIsJsArray::kMask)); |
4861 Node* is_jsarray_condition = WordNotEqual(is_jsarray, IntPtrConstant(0)); | 4861 Node* is_jsarray_condition = WordNotEqual(is_jsarray, IntPtrConstant(0)); |
(...skipping 26 matching lines...) Expand all Loading... |
4888 LoadObjectField(protector_cell, PropertyCell::kValueOffset), | 4888 LoadObjectField(protector_cell, PropertyCell::kValueOffset), |
4889 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), | 4889 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), |
4890 miss); | 4890 miss); |
4891 Return(UndefinedConstant()); | 4891 Return(UndefinedConstant()); |
4892 } | 4892 } |
4893 | 4893 |
4894 Bind(&property); | 4894 Bind(&property); |
4895 Comment("property_load"); | 4895 Comment("property_load"); |
4896 } | 4896 } |
4897 | 4897 |
4898 // |handler_word| is a field index as obtained by | 4898 Label constant(this), field(this); |
4899 // FieldIndex.GetLoadByFieldOffset(): | 4899 Branch(WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForFields)), |
4900 Label inobject_double(this), out_of_object(this), | 4900 &field, &constant); |
4901 out_of_object_double(this); | |
4902 Node* inobject_bit = | |
4903 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsInobject::kMask)); | |
4904 Node* double_bit = | |
4905 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsDouble::kMask)); | |
4906 Node* offset = | |
4907 WordSar(handler_word, IntPtrConstant(FieldOffsetOffset::kShift)); | |
4908 | 4901 |
4909 GotoIf(WordEqual(inobject_bit, IntPtrConstant(0)), &out_of_object); | 4902 Bind(&field); |
| 4903 { |
| 4904 Comment("field_load"); |
| 4905 Label inobject_double(this), out_of_object(this), |
| 4906 out_of_object_double(this); |
| 4907 Node* inobject_bit = |
| 4908 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsInobject::kMask)); |
| 4909 Node* double_bit = |
| 4910 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsDouble::kMask)); |
| 4911 Node* offset = |
| 4912 WordSar(handler_word, IntPtrConstant(FieldOffsetOffset::kShift)); |
4910 | 4913 |
4911 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), &inobject_double); | 4914 GotoIf(WordEqual(inobject_bit, IntPtrConstant(0)), &out_of_object); |
4912 Return(LoadObjectField(holder, offset)); | |
4913 | 4915 |
4914 Bind(&inobject_double); | 4916 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), &inobject_double); |
4915 if (FLAG_unbox_double_fields) { | 4917 Return(LoadObjectField(holder, offset)); |
4916 var_double_value.Bind( | 4918 |
4917 LoadObjectField(holder, offset, MachineType::Float64())); | 4919 Bind(&inobject_double); |
4918 } else { | 4920 if (FLAG_unbox_double_fields) { |
4919 Node* mutable_heap_number = LoadObjectField(holder, offset); | 4921 var_double_value.Bind( |
4920 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); | 4922 LoadObjectField(holder, offset, MachineType::Float64())); |
| 4923 } else { |
| 4924 Node* mutable_heap_number = LoadObjectField(holder, offset); |
| 4925 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); |
| 4926 } |
| 4927 Goto(&rebox_double); |
| 4928 |
| 4929 Bind(&out_of_object); |
| 4930 Node* properties = LoadProperties(holder); |
| 4931 Node* value = LoadObjectField(properties, offset); |
| 4932 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), |
| 4933 &out_of_object_double); |
| 4934 Return(value); |
| 4935 |
| 4936 Bind(&out_of_object_double); |
| 4937 var_double_value.Bind(LoadHeapNumberValue(value)); |
| 4938 Goto(&rebox_double); |
| 4939 |
| 4940 Bind(&rebox_double); |
| 4941 Return(AllocateHeapNumberWithValue(var_double_value.value())); |
4921 } | 4942 } |
4922 Goto(&rebox_double); | |
4923 | 4943 |
4924 Bind(&out_of_object); | 4944 Bind(&constant); |
4925 Node* properties = LoadProperties(holder); | 4945 { |
4926 Node* value = LoadObjectField(properties, offset); | 4946 Comment("constant_load"); |
4927 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), &out_of_object_double); | 4947 Node* descriptors = LoadMapDescriptors(LoadMap(holder)); |
4928 Return(value); | 4948 Node* descriptor = WordSar( |
4929 | 4949 handler_word, IntPtrConstant(ValueIndexInDescriptorArray::kShift)); |
4930 Bind(&out_of_object_double); | 4950 #if defined(DEBUG) |
4931 var_double_value.Bind(LoadHeapNumberValue(value)); | 4951 Assert(UintPtrLessThan(descriptor, |
4932 Goto(&rebox_double); | 4952 LoadAndUntagFixedArrayBaseLength(descriptors))); |
4933 | 4953 #endif |
4934 Bind(&rebox_double); | 4954 Return( |
4935 Return(AllocateHeapNumberWithValue(var_double_value.value())); | 4955 LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS)); |
| 4956 } |
4936 } | 4957 } |
4937 | 4958 |
4938 Bind(&try_proto_cell_handler); | 4959 Bind(&try_proto_cell_handler); |
4939 { | 4960 { |
4940 GotoIf(WordNotEqual(LoadMap(handler), LoadRoot(Heap::kTuple3MapRootIndex)), | 4961 GotoIf(WordNotEqual(LoadMap(handler), LoadRoot(Heap::kTuple3MapRootIndex)), |
4941 &call_handler); | 4962 &call_handler); |
4942 Node* validity_cell = LoadObjectField(handler, Tuple3::kValue1Offset); | 4963 Node* validity_cell = LoadObjectField(handler, Tuple3::kValue1Offset); |
4943 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); | 4964 Node* cell_value = LoadObjectField(validity_cell, Cell::kValueOffset); |
4944 GotoIf(WordNotEqual(cell_value, | 4965 GotoIf(WordNotEqual(cell_value, |
4945 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), | 4966 SmiConstant(Smi::FromInt(Map::kPrototypeChainValid))), |
(...skipping 2498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7444 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); | 7465 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); |
7445 Goto(&end); | 7466 Goto(&end); |
7446 } | 7467 } |
7447 | 7468 |
7448 Bind(&end); | 7469 Bind(&end); |
7449 return result.value(); | 7470 return result.value(); |
7450 } | 7471 } |
7451 | 7472 |
7452 } // namespace internal | 7473 } // namespace internal |
7453 } // namespace v8 | 7474 } // namespace v8 |
OLD | NEW |