Chromium Code Reviews| 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/js-builtin-reducer.h" | 5 #include "src/compiler/js-builtin-reducer.h" |
| 6 | 6 |
| 7 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
| 8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| 11 #include "src/compiler/node-properties.h" | 11 #include "src/compiler/node-properties.h" |
| 12 #include "src/compiler/operator-properties.h" | |
| 12 #include "src/compiler/simplified-operator.h" | 13 #include "src/compiler/simplified-operator.h" |
| 13 #include "src/compiler/type-cache.h" | 14 #include "src/compiler/type-cache.h" |
| 14 #include "src/compiler/types.h" | 15 #include "src/compiler/types.h" |
| 15 #include "src/objects-inl.h" | 16 #include "src/objects-inl.h" |
| 16 | |
| 17 namespace v8 { | 17 namespace v8 { |
| 18 namespace internal { | 18 namespace internal { |
| 19 namespace compiler { | 19 namespace compiler { |
| 20 | 20 |
| 21 | 21 |
| 22 // Helper class to access JSCallFunction nodes that are potential candidates | 22 // Helper class to access JSCallFunction nodes that are potential candidates |
| 23 // for reduction when they have a BuiltinFunctionId associated with them. | 23 // for reduction when they have a BuiltinFunctionId associated with them. |
| 24 class JSCallReduction { | 24 class JSCallReduction { |
| 25 public: | 25 public: |
| 26 explicit JSCallReduction(Node* node) : node_(node) {} | 26 explicit JSCallReduction(Node* node) : node_(node) {} |
| (...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1019 | 1019 |
| 1020 ReplaceWithValue(node, value, effect, control); | 1020 ReplaceWithValue(node, value, effect, control); |
| 1021 return Replace(value); | 1021 return Replace(value); |
| 1022 } | 1022 } |
| 1023 } | 1023 } |
| 1024 } | 1024 } |
| 1025 | 1025 |
| 1026 return NoChange(); | 1026 return NoChange(); |
| 1027 } | 1027 } |
| 1028 | 1028 |
| 1029 Reduction JSBuiltinReducer::ReduceStringIteratorPrototypeNext(Node* node) { | |
| 1030 Node* receiver = NodeProperties::GetValueInput(node, 1); | |
| 1031 Node* effect = NodeProperties::GetEffectInput(node); | |
| 1032 Node* control = NodeProperties::GetControlInput(node); | |
| 1033 Node* context = NodeProperties::GetContextInput(node); | |
| 1034 if (HasInstanceTypeWitness(receiver, effect, JS_STRING_ITERATOR_TYPE)) { | |
| 1035 Node* string = effect = graph()->NewNode( | |
| 1036 simplified()->LoadField(AccessBuilder::ForJSStringIteratorString()), | |
| 1037 receiver, effect, control); | |
| 1038 Node* index = effect = graph()->NewNode( | |
| 1039 simplified()->LoadField(AccessBuilder::ForJSStringIteratorIndex()), | |
| 1040 receiver, effect, control); | |
| 1041 Node* length = effect = graph()->NewNode( | |
| 1042 simplified()->LoadField(AccessBuilder::ForStringLength()), string, | |
| 1043 effect, control); | |
| 1044 | |
| 1045 // branch0: if (index < length) | |
| 1046 Node* check0 = | |
| 1047 graph()->NewNode(simplified()->NumberLessThan(), index, length); | |
| 1048 Node* branch0 = | |
| 1049 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); | |
| 1050 | |
| 1051 Node* etrue0 = effect; | |
|
Benedikt Meurer
2016/09/29 13:04:27
You don't need the etrue0.
| |
| 1052 Node* vtrue0; | |
| 1053 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | |
| 1054 Node* done_true; | |
|
Benedikt Meurer
2016/09/29 13:04:27
Can you indent the branches below and add { } for
| |
| 1055 { | |
| 1056 done_true = jsgraph()->FalseConstant(); | |
| 1057 Node* uint32_index = | |
|
Benedikt Meurer
2016/09/29 13:04:27
You don't need this NumberToUint32. The type of th
caitp
2016/09/29 17:21:44
Ah, makes sense. Thanks!
| |
| 1058 graph()->NewNode(simplified()->NumberToUint32(), index); | |
| 1059 Node* lead = graph()->NewNode(simplified()->StringCharCodeAt(), string, | |
| 1060 uint32_index, if_true0); | |
| 1061 Node* codepoint; | |
| 1062 Node* control; | |
| 1063 Node* check1 = graph()->NewNode(simplified()->NumberLessThan(), lead, | |
| 1064 jsgraph()->Int32Constant(0xD800)); | |
| 1065 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
| 1066 check1, if_true0); | |
| 1067 | |
| 1068 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
| 1069 Node* check2 = graph()->NewNode(simplified()->NumberLessThanOrEqual(), | |
| 1070 lead, jsgraph()->Int32Constant(0xDC00)); | |
| 1071 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
| 1072 check2, if_false1); | |
| 1073 | |
| 1074 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
| 1075 Node* next_index = graph()->NewNode(simplified()->NumberAdd(), index, | |
| 1076 jsgraph()->OneConstant()); | |
| 1077 Node* check3 = | |
| 1078 graph()->NewNode(simplified()->NumberLessThan(), next_index, length); | |
| 1079 Node* branch3 = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
| 1080 check3, if_true2); | |
| 1081 | |
| 1082 Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3); | |
| 1083 Node* uint32_next_index = | |
| 1084 graph()->NewNode(simplified()->NumberToUint32(), next_index); | |
|
Benedikt Meurer
2016/09/29 13:04:27
Same here, you don't need it if you have the types
| |
| 1085 Node* trail = graph()->NewNode(simplified()->StringCharCodeAt(), string, | |
| 1086 uint32_next_index, if_true3); | |
| 1087 Node* check4 = graph()->NewNode(simplified()->NumberLessThanOrEqual(), | |
| 1088 jsgraph()->Int32Constant(0xDC00), trail); | |
| 1089 Node* branch4 = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
| 1090 check4, if_true3); | |
| 1091 | |
| 1092 Node* if_true4 = graph()->NewNode(common()->IfTrue(), branch4); | |
| 1093 Node* check5 = graph()->NewNode(simplified()->NumberLessThanOrEqual(), | |
| 1094 trail, jsgraph()->Int32Constant(0xDFFF)); | |
| 1095 Node* branch5 = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
| 1096 check5, if_true4); | |
| 1097 | |
| 1098 Node* if_true5 = graph()->NewNode(common()->IfTrue(), branch5); | |
| 1099 codepoint = graph()->NewNode( | |
| 1100 simplified()->NumberBitwiseOr(), | |
| 1101 graph()->NewNode(simplified()->NumberShiftLeft(), trail, | |
| 1102 jsgraph()->Int32Constant(16)), | |
| 1103 lead); | |
| 1104 | |
| 1105 Node* if_false5 = graph()->NewNode(common()->IfFalse(), branch5); | |
| 1106 control = graph()->NewNode(common()->Merge(2), if_true5, if_false5); | |
| 1107 codepoint = | |
| 1108 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), | |
| 1109 codepoint, lead, control); | |
| 1110 | |
| 1111 Node* if_false4 = graph()->NewNode(common()->IfFalse(), branch4); | |
| 1112 control = graph()->NewNode(common()->Merge(2), if_true4, if_false4); | |
| 1113 codepoint = | |
| 1114 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), | |
| 1115 codepoint, lead, control); | |
| 1116 Node* if_false3 = graph()->NewNode(common()->IfFalse(), branch3); | |
| 1117 control = graph()->NewNode(common()->Merge(2), if_true3, if_false3); | |
| 1118 codepoint = | |
| 1119 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), | |
| 1120 codepoint, lead, control); | |
| 1121 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
| 1122 control = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
| 1123 codepoint = | |
| 1124 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), | |
| 1125 codepoint, lead, control); | |
| 1126 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
| 1127 control = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
| 1128 codepoint = | |
| 1129 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), | |
| 1130 codepoint, lead, control); | |
| 1131 | |
| 1132 vtrue0 = etrue0 = graph()->NewNode( | |
|
Benedikt Meurer
2016/09/29 13:04:27
StringFromCodePoint doesn't produce an effect.
| |
| 1133 simplified()->StringFromCodePoint(UnicodeEncoding::UTF16), codepoint); | |
| 1134 } | |
| 1135 | |
| 1136 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | |
| 1137 Node* vfalse0; | |
| 1138 Node* done_false; | |
| 1139 { | |
| 1140 done_false = jsgraph()->TrueConstant(); | |
| 1141 vfalse0 = jsgraph()->UndefinedConstant(); | |
| 1142 } | |
| 1143 | |
| 1144 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | |
| 1145 Node* value_phi = | |
| 1146 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | |
| 1147 vtrue0, vfalse0, control); | |
| 1148 Node* done_phi = | |
| 1149 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | |
| 1150 done_true, done_false, control); | |
| 1151 | |
| 1152 Node* native_context = effect = | |
| 1153 graph()->NewNode(jsgraph()->javascript()->LoadContext( | |
| 1154 0, Context::NATIVE_CONTEXT_INDEX, true), | |
| 1155 context, context, effect); | |
| 1156 Node* map = effect = | |
| 1157 graph()->NewNode(jsgraph()->javascript()->LoadContext( | |
| 1158 0, Context::ITERATOR_RESULT_MAP_INDEX, true), | |
| 1159 context, native_context, effect); | |
| 1160 | |
| 1161 Node* value = effect = graph()->NewNode( | |
| 1162 simplified()->Allocate(NOT_TENURED), | |
| 1163 jsgraph()->Int32Constant(JSIteratorResult::kSize), effect, control); | |
| 1164 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), | |
| 1165 value, map, effect, control); | |
|
Benedikt Meurer
2016/09/29 13:04:27
You need to initialize properties and elements her
| |
| 1166 effect = graph()->NewNode( | |
| 1167 simplified()->StoreField(AccessBuilder::ForJSIteratorResultDone()), | |
| 1168 value, done_phi, effect, control); | |
| 1169 effect = graph()->NewNode( | |
| 1170 simplified()->StoreField(AccessBuilder::ForJSIteratorResultValue()), | |
| 1171 value, value_phi, effect, control); | |
| 1172 | |
| 1173 ReplaceWithValue(node, value, effect, control); | |
| 1174 return Replace(value); | |
| 1175 } | |
| 1176 return NoChange(); | |
| 1177 } | |
| 1178 | |
| 1029 Reduction JSBuiltinReducer::ReduceArrayBufferViewAccessor( | 1179 Reduction JSBuiltinReducer::ReduceArrayBufferViewAccessor( |
| 1030 Node* node, InstanceType instance_type, FieldAccess const& access) { | 1180 Node* node, InstanceType instance_type, FieldAccess const& access) { |
| 1031 Node* receiver = NodeProperties::GetValueInput(node, 1); | 1181 Node* receiver = NodeProperties::GetValueInput(node, 1); |
| 1032 Node* effect = NodeProperties::GetEffectInput(node); | 1182 Node* effect = NodeProperties::GetEffectInput(node); |
| 1033 Node* control = NodeProperties::GetControlInput(node); | 1183 Node* control = NodeProperties::GetControlInput(node); |
| 1034 if (HasInstanceTypeWitness(receiver, effect, instance_type)) { | 1184 if (HasInstanceTypeWitness(receiver, effect, instance_type)) { |
| 1035 // Load the {receiver}s field. | 1185 // Load the {receiver}s field. |
| 1036 Node* receiver_value = effect = graph()->NewNode( | 1186 Node* receiver_value = effect = graph()->NewNode( |
| 1037 simplified()->LoadField(access), receiver, effect, control); | 1187 simplified()->LoadField(access), receiver, effect, control); |
| 1038 | 1188 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1188 case kNumberParseInt: | 1338 case kNumberParseInt: |
| 1189 reduction = ReduceNumberParseInt(node); | 1339 reduction = ReduceNumberParseInt(node); |
| 1190 break; | 1340 break; |
| 1191 case kStringFromCharCode: | 1341 case kStringFromCharCode: |
| 1192 reduction = ReduceStringFromCharCode(node); | 1342 reduction = ReduceStringFromCharCode(node); |
| 1193 break; | 1343 break; |
| 1194 case kStringCharAt: | 1344 case kStringCharAt: |
| 1195 return ReduceStringCharAt(node); | 1345 return ReduceStringCharAt(node); |
| 1196 case kStringCharCodeAt: | 1346 case kStringCharCodeAt: |
| 1197 return ReduceStringCharCodeAt(node); | 1347 return ReduceStringCharCodeAt(node); |
| 1348 case kStringIteratorPrototypeNext: | |
| 1349 return ReduceStringIteratorPrototypeNext(node); | |
| 1198 case kDataViewByteLength: | 1350 case kDataViewByteLength: |
| 1199 return ReduceArrayBufferViewAccessor( | 1351 return ReduceArrayBufferViewAccessor( |
| 1200 node, JS_DATA_VIEW_TYPE, | 1352 node, JS_DATA_VIEW_TYPE, |
| 1201 AccessBuilder::ForJSArrayBufferViewByteLength()); | 1353 AccessBuilder::ForJSArrayBufferViewByteLength()); |
| 1202 case kDataViewByteOffset: | 1354 case kDataViewByteOffset: |
| 1203 return ReduceArrayBufferViewAccessor( | 1355 return ReduceArrayBufferViewAccessor( |
| 1204 node, JS_DATA_VIEW_TYPE, | 1356 node, JS_DATA_VIEW_TYPE, |
| 1205 AccessBuilder::ForJSArrayBufferViewByteOffset()); | 1357 AccessBuilder::ForJSArrayBufferViewByteOffset()); |
| 1206 case kTypedArrayByteLength: | 1358 case kTypedArrayByteLength: |
| 1207 return ReduceArrayBufferViewAccessor( | 1359 return ReduceArrayBufferViewAccessor( |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1250 } | 1402 } |
| 1251 | 1403 |
| 1252 | 1404 |
| 1253 SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const { | 1405 SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const { |
| 1254 return jsgraph()->simplified(); | 1406 return jsgraph()->simplified(); |
| 1255 } | 1407 } |
| 1256 | 1408 |
| 1257 } // namespace compiler | 1409 } // namespace compiler |
| 1258 } // namespace internal | 1410 } // namespace internal |
| 1259 } // namespace v8 | 1411 } // namespace v8 |
| OLD | NEW |