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" | 9 #include "src/address-map.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 return changer_->Uint32OverflowOperatorFor(node->opcode()); | 1024 return changer_->Uint32OverflowOperatorFor(node->opcode()); |
1025 } | 1025 } |
1026 | 1026 |
1027 const Operator* Float64Op(Node* node) { | 1027 const Operator* Float64Op(Node* node) { |
1028 return changer_->Float64OperatorFor(node->opcode()); | 1028 return changer_->Float64OperatorFor(node->opcode()); |
1029 } | 1029 } |
1030 | 1030 |
1031 WriteBarrierKind WriteBarrierKindFor( | 1031 WriteBarrierKind WriteBarrierKindFor( |
1032 BaseTaggedness base_taggedness, | 1032 BaseTaggedness base_taggedness, |
1033 MachineRepresentation field_representation, Type* field_type, | 1033 MachineRepresentation field_representation, Type* field_type, |
1034 Node* value) { | 1034 MachineRepresentation value_representation, Node* value) { |
1035 if (base_taggedness == kTaggedBase && | 1035 if (base_taggedness == kTaggedBase && |
1036 CanBeTaggedPointer(field_representation)) { | 1036 CanBeTaggedPointer(field_representation)) { |
1037 Type* value_type = NodeProperties::GetType(value); | 1037 Type* value_type = NodeProperties::GetType(value); |
1038 if (field_type->Is(Type::TaggedSigned()) || | 1038 if (field_representation == MachineRepresentation::kTaggedSigned || |
1039 value_type->Is(Type::TaggedSigned())) { | 1039 value_representation == MachineRepresentation::kTaggedSigned) { |
1040 // Write barriers are only for stores of heap objects. | 1040 // Write barriers are only for stores of heap objects. |
1041 return kNoWriteBarrier; | 1041 return kNoWriteBarrier; |
1042 } | 1042 } |
1043 if (field_type->Is(Type::BooleanOrNullOrUndefined()) || | 1043 if (field_type->Is(Type::BooleanOrNullOrUndefined()) || |
1044 value_type->Is(Type::BooleanOrNullOrUndefined())) { | 1044 value_type->Is(Type::BooleanOrNullOrUndefined())) { |
1045 // Write barriers are not necessary when storing true, false, null or | 1045 // Write barriers are not necessary when storing true, false, null or |
1046 // undefined, because these special oddballs are always in the root set. | 1046 // undefined, because these special oddballs are always in the root set. |
1047 return kNoWriteBarrier; | 1047 return kNoWriteBarrier; |
1048 } | 1048 } |
1049 if (value_type->IsConstant() && | 1049 if (value_type->IsConstant() && |
1050 value_type->AsConstant()->Value()->IsHeapObject()) { | 1050 value_type->AsConstant()->Value()->IsHeapObject()) { |
1051 Handle<HeapObject> value_object = | 1051 Handle<HeapObject> value_object = |
1052 Handle<HeapObject>::cast(value_type->AsConstant()->Value()); | 1052 Handle<HeapObject>::cast(value_type->AsConstant()->Value()); |
1053 RootIndexMap root_index_map(jsgraph_->isolate()); | 1053 RootIndexMap root_index_map(jsgraph_->isolate()); |
1054 int root_index = root_index_map.Lookup(*value_object); | 1054 int root_index = root_index_map.Lookup(*value_object); |
1055 if (root_index != RootIndexMap::kInvalidRootIndex && | 1055 if (root_index != RootIndexMap::kInvalidRootIndex && |
1056 jsgraph_->isolate()->heap()->RootIsImmortalImmovable(root_index)) { | 1056 jsgraph_->isolate()->heap()->RootIsImmortalImmovable(root_index)) { |
1057 // Write barriers are unnecessary for immortal immovable roots. | 1057 // Write barriers are unnecessary for immortal immovable roots. |
1058 return kNoWriteBarrier; | 1058 return kNoWriteBarrier; |
1059 } | 1059 } |
1060 if (value_object->IsMap()) { | 1060 if (value_object->IsMap()) { |
1061 // Write barriers for storing maps are cheaper. | 1061 // Write barriers for storing maps are cheaper. |
1062 return kMapWriteBarrier; | 1062 return kMapWriteBarrier; |
1063 } | 1063 } |
1064 } | 1064 } |
1065 if (field_type->Is(Type::TaggedPointer()) || | 1065 if (field_representation == MachineRepresentation::kTaggedPointer || |
1066 value_type->Is(Type::TaggedPointer())) { | 1066 value_representation == MachineRepresentation::kTaggedPointer) { |
1067 // Write barriers for heap objects are cheaper. | 1067 // Write barriers for heap objects are cheaper. |
1068 return kPointerWriteBarrier; | 1068 return kPointerWriteBarrier; |
1069 } | 1069 } |
1070 NumberMatcher m(value); | 1070 NumberMatcher m(value); |
1071 if (m.HasValue()) { | 1071 if (m.HasValue()) { |
1072 if (IsSmiDouble(m.Value())) { | 1072 if (IsSmiDouble(m.Value())) { |
1073 // Storing a smi doesn't need a write barrier. | 1073 // Storing a smi doesn't need a write barrier. |
1074 return kNoWriteBarrier; | 1074 return kNoWriteBarrier; |
1075 } | 1075 } |
1076 // The NumberConstant will be represented as HeapNumber. | 1076 // The NumberConstant will be represented as HeapNumber. |
1077 return kPointerWriteBarrier; | 1077 return kPointerWriteBarrier; |
1078 } | 1078 } |
1079 return kFullWriteBarrier; | 1079 return kFullWriteBarrier; |
1080 } | 1080 } |
1081 return kNoWriteBarrier; | 1081 return kNoWriteBarrier; |
1082 } | 1082 } |
1083 | 1083 |
1084 WriteBarrierKind WriteBarrierKindFor( | 1084 WriteBarrierKind WriteBarrierKindFor( |
1085 BaseTaggedness base_taggedness, | 1085 BaseTaggedness base_taggedness, |
1086 MachineRepresentation field_representation, int field_offset, | 1086 MachineRepresentation field_representation, int field_offset, |
1087 Type* field_type, Node* value) { | 1087 Type* field_type, MachineRepresentation value_representation, |
| 1088 Node* value) { |
1088 if (base_taggedness == kTaggedBase && | 1089 if (base_taggedness == kTaggedBase && |
1089 field_offset == HeapObject::kMapOffset) { | 1090 field_offset == HeapObject::kMapOffset) { |
1090 return kMapWriteBarrier; | 1091 return kMapWriteBarrier; |
1091 } | 1092 } |
1092 return WriteBarrierKindFor(base_taggedness, field_representation, | 1093 return WriteBarrierKindFor(base_taggedness, field_representation, |
1093 field_type, value); | 1094 field_type, value_representation, value); |
1094 } | 1095 } |
1095 | 1096 |
1096 Graph* graph() const { return jsgraph_->graph(); } | 1097 Graph* graph() const { return jsgraph_->graph(); } |
1097 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 1098 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
1098 SimplifiedOperatorBuilder* simplified() const { | 1099 SimplifiedOperatorBuilder* simplified() const { |
1099 return jsgraph_->simplified(); | 1100 return jsgraph_->simplified(); |
1100 } | 1101 } |
1101 | 1102 |
1102 void LowerToCheckedInt32Mul(Node* node, Truncation truncation, | 1103 void LowerToCheckedInt32Mul(Node* node, Truncation truncation, |
1103 Type* input0_type, Type* input1_type) { | 1104 Type* input0_type, Type* input1_type) { |
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2166 ProcessInput(node, 0, UseInfo::TruncatingWord32()); | 2167 ProcessInput(node, 0, UseInfo::TruncatingWord32()); |
2167 ProcessRemainingInputs(node, 1); | 2168 ProcessRemainingInputs(node, 1); |
2168 SetOutput(node, MachineRepresentation::kTagged); | 2169 SetOutput(node, MachineRepresentation::kTagged); |
2169 return; | 2170 return; |
2170 } | 2171 } |
2171 case IrOpcode::kLoadField: { | 2172 case IrOpcode::kLoadField: { |
2172 if (truncation.IsUnused()) return VisitUnused(node); | 2173 if (truncation.IsUnused()) return VisitUnused(node); |
2173 FieldAccess access = FieldAccessOf(node->op()); | 2174 FieldAccess access = FieldAccessOf(node->op()); |
2174 MachineRepresentation const representation = | 2175 MachineRepresentation const representation = |
2175 access.machine_type.representation(); | 2176 access.machine_type.representation(); |
2176 // TODO(bmeurer): Introduce an appropriate tagged-signed machine rep. | |
2177 VisitUnop(node, UseInfoForBasePointer(access), representation); | 2177 VisitUnop(node, UseInfoForBasePointer(access), representation); |
2178 return; | 2178 return; |
2179 } | 2179 } |
2180 case IrOpcode::kStoreField: { | 2180 case IrOpcode::kStoreField: { |
2181 FieldAccess access = FieldAccessOf(node->op()); | 2181 FieldAccess access = FieldAccessOf(node->op()); |
| 2182 NodeInfo* input_info = GetInfo(node->InputAt(1)); |
2182 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( | 2183 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( |
2183 access.base_is_tagged, access.machine_type.representation(), | 2184 access.base_is_tagged, access.machine_type.representation(), |
2184 access.offset, access.type, node->InputAt(1)); | 2185 access.offset, access.type, input_info->representation(), |
| 2186 node->InputAt(1)); |
2185 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 2187 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
2186 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( | 2188 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( |
2187 access.machine_type.representation())); | 2189 access.machine_type.representation())); |
2188 ProcessRemainingInputs(node, 2); | 2190 ProcessRemainingInputs(node, 2); |
2189 SetOutput(node, MachineRepresentation::kNone); | 2191 SetOutput(node, MachineRepresentation::kNone); |
2190 if (lower()) { | 2192 if (lower()) { |
2191 if (write_barrier_kind < access.write_barrier_kind) { | 2193 if (write_barrier_kind < access.write_barrier_kind) { |
2192 access.write_barrier_kind = write_barrier_kind; | 2194 access.write_barrier_kind = write_barrier_kind; |
2193 NodeProperties::ChangeOp( | 2195 NodeProperties::ChangeOp( |
2194 node, jsgraph_->simplified()->StoreField(access)); | 2196 node, jsgraph_->simplified()->StoreField(access)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2246 case IrOpcode::kLoadElement: { | 2248 case IrOpcode::kLoadElement: { |
2247 if (truncation.IsUnused()) return VisitUnused(node); | 2249 if (truncation.IsUnused()) return VisitUnused(node); |
2248 ElementAccess access = ElementAccessOf(node->op()); | 2250 ElementAccess access = ElementAccessOf(node->op()); |
2249 VisitBinop(node, UseInfoForBasePointer(access), | 2251 VisitBinop(node, UseInfoForBasePointer(access), |
2250 UseInfo::TruncatingWord32(), | 2252 UseInfo::TruncatingWord32(), |
2251 access.machine_type.representation()); | 2253 access.machine_type.representation()); |
2252 return; | 2254 return; |
2253 } | 2255 } |
2254 case IrOpcode::kStoreElement: { | 2256 case IrOpcode::kStoreElement: { |
2255 ElementAccess access = ElementAccessOf(node->op()); | 2257 ElementAccess access = ElementAccessOf(node->op()); |
| 2258 NodeInfo* input_info = GetInfo(node->InputAt(2)); |
2256 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( | 2259 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( |
2257 access.base_is_tagged, access.machine_type.representation(), | 2260 access.base_is_tagged, access.machine_type.representation(), |
2258 access.type, node->InputAt(2)); | 2261 access.type, input_info->representation(), node->InputAt(2)); |
2259 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 2262 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
2260 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 2263 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
2261 ProcessInput(node, 2, | 2264 ProcessInput(node, 2, |
2262 TruncatingUseInfoFromRepresentation( | 2265 TruncatingUseInfoFromRepresentation( |
2263 access.machine_type.representation())); // value | 2266 access.machine_type.representation())); // value |
2264 ProcessRemainingInputs(node, 3); | 2267 ProcessRemainingInputs(node, 3); |
2265 SetOutput(node, MachineRepresentation::kNone); | 2268 SetOutput(node, MachineRepresentation::kNone); |
2266 if (lower()) { | 2269 if (lower()) { |
2267 if (write_barrier_kind < access.write_barrier_kind) { | 2270 if (write_barrier_kind < access.write_barrier_kind) { |
2268 access.write_barrier_kind = write_barrier_kind; | 2271 access.write_barrier_kind = write_barrier_kind; |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3193 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3196 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3194 Operator::kNoProperties); | 3197 Operator::kNoProperties); |
3195 to_number_operator_.set(common()->Call(desc)); | 3198 to_number_operator_.set(common()->Call(desc)); |
3196 } | 3199 } |
3197 return to_number_operator_.get(); | 3200 return to_number_operator_.get(); |
3198 } | 3201 } |
3199 | 3202 |
3200 } // namespace compiler | 3203 } // namespace compiler |
3201 } // namespace internal | 3204 } // namespace internal |
3202 } // namespace v8 | 3205 } // namespace v8 |
OLD | NEW |