OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/address-map.h" | |
10 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
11 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
12 #include "src/compiler/access-builder.h" | 11 #include "src/compiler/access-builder.h" |
13 #include "src/compiler/common-operator.h" | 12 #include "src/compiler/common-operator.h" |
14 #include "src/compiler/diamond.h" | 13 #include "src/compiler/diamond.h" |
15 #include "src/compiler/linkage.h" | 14 #include "src/compiler/linkage.h" |
16 #include "src/compiler/node-matchers.h" | 15 #include "src/compiler/node-matchers.h" |
17 #include "src/compiler/node-properties.h" | 16 #include "src/compiler/node-properties.h" |
18 #include "src/compiler/operator-properties.h" | 17 #include "src/compiler/operator-properties.h" |
19 #include "src/compiler/representation-change.h" | 18 #include "src/compiler/representation-change.h" |
20 #include "src/compiler/simplified-operator.h" | 19 #include "src/compiler/simplified-operator.h" |
21 #include "src/compiler/source-position.h" | 20 #include "src/compiler/source-position.h" |
22 #include "src/conversions-inl.h" | |
23 #include "src/objects.h" | 21 #include "src/objects.h" |
24 #include "src/type-cache.h" | 22 #include "src/type-cache.h" |
25 | 23 |
26 namespace v8 { | 24 namespace v8 { |
27 namespace internal { | 25 namespace internal { |
28 namespace compiler { | 26 namespace compiler { |
29 | 27 |
30 // Macro for outputting trace information from representation inference. | 28 // Macro for outputting trace information from representation inference. |
31 #define TRACE(...) \ | 29 #define TRACE(...) \ |
32 do { \ | 30 do { \ |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 } | 702 } |
705 | 703 |
706 const Operator* Uint32Op(Node* node) { | 704 const Operator* Uint32Op(Node* node) { |
707 return changer_->Uint32OperatorFor(node->opcode()); | 705 return changer_->Uint32OperatorFor(node->opcode()); |
708 } | 706 } |
709 | 707 |
710 const Operator* Float64Op(Node* node) { | 708 const Operator* Float64Op(Node* node) { |
711 return changer_->Float64OperatorFor(node->opcode()); | 709 return changer_->Float64OperatorFor(node->opcode()); |
712 } | 710 } |
713 | 711 |
714 WriteBarrierKind WriteBarrierKindFor( | |
715 BaseTaggedness base_taggedness, | |
716 MachineRepresentation field_representation, Type* field_type, | |
717 Node* value) { | |
718 if (base_taggedness == kTaggedBase && | |
719 field_representation == MachineRepresentation::kTagged) { | |
720 Type* value_type = NodeProperties::GetType(value); | |
721 if (field_type->Is(Type::TaggedSigned()) || | |
722 value_type->Is(Type::TaggedSigned())) { | |
723 // Write barriers are only for stores of heap objects. | |
724 return kNoWriteBarrier; | |
725 } | |
726 if (field_type->Is(Type::BooleanOrNullOrUndefined()) || | |
727 value_type->Is(Type::BooleanOrNullOrUndefined())) { | |
728 // Write barriers are not necessary when storing true, false, null or | |
729 // undefined, because these special oddballs are always in the root set. | |
730 return kNoWriteBarrier; | |
731 } | |
732 if (value_type->IsConstant() && | |
733 value_type->AsConstant()->Value()->IsHeapObject()) { | |
734 Handle<HeapObject> value_object = | |
735 Handle<HeapObject>::cast(value_type->AsConstant()->Value()); | |
736 if (value_object->IsMap()) { | |
737 // Write barriers for storing maps are cheaper. | |
738 return kMapWriteBarrier; | |
739 } | |
740 RootIndexMap root_index_map(jsgraph_->isolate()); | |
741 int root_index = root_index_map.Lookup(*value_object); | |
742 if (root_index != RootIndexMap::kInvalidRootIndex && | |
743 jsgraph_->isolate()->heap()->RootIsImmortalImmovable(root_index)) { | |
744 // Write barriers are unnecessary for immortal immovable roots. | |
745 return kNoWriteBarrier; | |
746 } | |
747 } | |
748 if (field_type->Is(Type::TaggedPointer()) || | |
749 value_type->Is(Type::TaggedPointer())) { | |
750 // Write barriers for heap objects are cheaper. | |
751 return kPointerWriteBarrier; | |
752 } | |
753 NumberMatcher m(value); | |
754 if (m.HasValue()) { | |
755 if (IsSmiDouble(m.Value())) { | |
756 // Storing a smi doesn't need a write barrier. | |
757 return kNoWriteBarrier; | |
758 } | |
759 // The NumberConstant will be represented as HeapNumber. | |
760 return kPointerWriteBarrier; | |
761 } | |
762 return kFullWriteBarrier; | |
763 } | |
764 return kNoWriteBarrier; | |
765 } | |
766 | |
767 WriteBarrierKind WriteBarrierKindFor( | |
768 BaseTaggedness base_taggedness, | |
769 MachineRepresentation field_representation, int field_offset, | |
770 Type* field_type, Node* value) { | |
771 if (base_taggedness == kTaggedBase && | |
772 field_offset == HeapObject::kMapOffset) { | |
773 return kMapWriteBarrier; | |
774 } | |
775 return WriteBarrierKindFor(base_taggedness, field_representation, | |
776 field_type, value); | |
777 } | |
778 | |
779 // Dispatching routine for visiting the node {node} with the usage {use}. | 712 // Dispatching routine for visiting the node {node} with the usage {use}. |
780 // Depending on the operator, propagate new usage info to the inputs. | 713 // Depending on the operator, propagate new usage info to the inputs. |
781 void VisitNode(Node* node, Truncation truncation, | 714 void VisitNode(Node* node, Truncation truncation, |
782 SimplifiedLowering* lowering) { | 715 SimplifiedLowering* lowering) { |
783 switch (node->opcode()) { | 716 switch (node->opcode()) { |
784 //------------------------------------------------------------------ | 717 //------------------------------------------------------------------ |
785 // Common operators. | 718 // Common operators. |
786 //------------------------------------------------------------------ | 719 //------------------------------------------------------------------ |
787 case IrOpcode::kStart: | 720 case IrOpcode::kStart: |
788 case IrOpcode::kDead: | 721 case IrOpcode::kDead: |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 SetOutput(node, access.machine_type.representation()); | 1129 SetOutput(node, access.machine_type.representation()); |
1197 break; | 1130 break; |
1198 } | 1131 } |
1199 case IrOpcode::kStoreField: { | 1132 case IrOpcode::kStoreField: { |
1200 FieldAccess access = FieldAccessOf(node->op()); | 1133 FieldAccess access = FieldAccessOf(node->op()); |
1201 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1134 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
1202 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( | 1135 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( |
1203 access.machine_type.representation())); | 1136 access.machine_type.representation())); |
1204 ProcessRemainingInputs(node, 2); | 1137 ProcessRemainingInputs(node, 2); |
1205 SetOutput(node, MachineRepresentation::kNone); | 1138 SetOutput(node, MachineRepresentation::kNone); |
1206 if (lower()) { | |
1207 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( | |
1208 access.base_is_tagged, access.machine_type.representation(), | |
1209 access.offset, access.type, node->InputAt(1)); | |
1210 if (write_barrier_kind < access.write_barrier_kind) { | |
1211 access.write_barrier_kind = write_barrier_kind; | |
1212 NodeProperties::ChangeOp( | |
1213 node, jsgraph_->simplified()->StoreField(access)); | |
1214 } | |
1215 } | |
1216 break; | 1139 break; |
1217 } | 1140 } |
1218 case IrOpcode::kLoadBuffer: { | 1141 case IrOpcode::kLoadBuffer: { |
1219 BufferAccess access = BufferAccessOf(node->op()); | 1142 BufferAccess access = BufferAccessOf(node->op()); |
1220 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1143 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
1221 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1144 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
1222 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1145 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
1223 ProcessRemainingInputs(node, 3); | 1146 ProcessRemainingInputs(node, 3); |
1224 | 1147 |
1225 MachineRepresentation output; | 1148 MachineRepresentation output; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1271 } | 1194 } |
1272 case IrOpcode::kStoreElement: { | 1195 case IrOpcode::kStoreElement: { |
1273 ElementAccess access = ElementAccessOf(node->op()); | 1196 ElementAccess access = ElementAccessOf(node->op()); |
1274 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1197 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
1275 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1198 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
1276 ProcessInput(node, 2, | 1199 ProcessInput(node, 2, |
1277 TruncatingUseInfoFromRepresentation( | 1200 TruncatingUseInfoFromRepresentation( |
1278 access.machine_type.representation())); // value | 1201 access.machine_type.representation())); // value |
1279 ProcessRemainingInputs(node, 3); | 1202 ProcessRemainingInputs(node, 3); |
1280 SetOutput(node, MachineRepresentation::kNone); | 1203 SetOutput(node, MachineRepresentation::kNone); |
1281 if (lower()) { | |
1282 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( | |
1283 access.base_is_tagged, access.machine_type.representation(), | |
1284 access.type, node->InputAt(2)); | |
1285 if (write_barrier_kind < access.write_barrier_kind) { | |
1286 access.write_barrier_kind = write_barrier_kind; | |
1287 NodeProperties::ChangeOp( | |
1288 node, jsgraph_->simplified()->StoreElement(access)); | |
1289 } | |
1290 } | |
1291 break; | 1204 break; |
1292 } | 1205 } |
1293 case IrOpcode::kObjectIsCallable: | 1206 case IrOpcode::kObjectIsCallable: |
1294 case IrOpcode::kObjectIsNumber: | 1207 case IrOpcode::kObjectIsNumber: |
1295 case IrOpcode::kObjectIsReceiver: | 1208 case IrOpcode::kObjectIsReceiver: |
1296 case IrOpcode::kObjectIsSmi: | 1209 case IrOpcode::kObjectIsSmi: |
1297 case IrOpcode::kObjectIsString: | 1210 case IrOpcode::kObjectIsString: |
1298 case IrOpcode::kObjectIsUndetectable: { | 1211 case IrOpcode::kObjectIsUndetectable: { |
1299 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1212 ProcessInput(node, 0, UseInfo::AnyTagged()); |
1300 SetOutput(node, MachineRepresentation::kBit); | 1213 SetOutput(node, MachineRepresentation::kBit); |
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2460 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 2373 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
2461 Operator::kNoProperties); | 2374 Operator::kNoProperties); |
2462 to_number_operator_.set(common()->Call(desc)); | 2375 to_number_operator_.set(common()->Call(desc)); |
2463 } | 2376 } |
2464 return to_number_operator_.get(); | 2377 return to_number_operator_.get(); |
2465 } | 2378 } |
2466 | 2379 |
2467 } // namespace compiler | 2380 } // namespace compiler |
2468 } // namespace internal | 2381 } // namespace internal |
2469 } // namespace v8 | 2382 } // namespace v8 |
OLD | NEW |