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" |
(...skipping 1008 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; |
| 1052 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1053 Node* done_true; |
| 1054 Node* vtrue0; |
| 1055 { |
| 1056 done_true = jsgraph()->FalseConstant(); |
| 1057 Node* lead = graph()->NewNode(simplified()->StringCharCodeAt(), string, |
| 1058 index, if_true0); |
| 1059 |
| 1060 // branch1: if ((lead & 0xFC00) === 0xD800) |
| 1061 Node* check1 = graph()->NewNode( |
| 1062 simplified()->NumberEqual(), |
| 1063 graph()->NewNode(simplified()->NumberBitwiseAnd(), lead, |
| 1064 jsgraph()->Int32Constant(0xFC00)), |
| 1065 jsgraph()->Int32Constant(0xD800)); |
| 1066 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 1067 check1, if_true0); |
| 1068 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1069 Node* vtrue1; |
| 1070 { |
| 1071 Node* next_index = graph()->NewNode(simplified()->NumberAdd(), index, |
| 1072 jsgraph()->OneConstant()); |
| 1073 // branch2: if ((index + 1) < length) |
| 1074 Node* check2 = graph()->NewNode(simplified()->NumberLessThan(), |
| 1075 next_index, length); |
| 1076 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
| 1077 check2, if_true1); |
| 1078 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
| 1079 Node* vtrue2; |
| 1080 { |
| 1081 Node* trail = graph()->NewNode(simplified()->StringCharCodeAt(), |
| 1082 string, next_index, if_true2); |
| 1083 // branch3: if ((trail & 0xFC00) === 0xDC00) |
| 1084 Node* check3 = graph()->NewNode( |
| 1085 simplified()->NumberEqual(), |
| 1086 graph()->NewNode(simplified()->NumberBitwiseAnd(), trail, |
| 1087 jsgraph()->Int32Constant(0xFC00)), |
| 1088 jsgraph()->Int32Constant(0xDC00)); |
| 1089 Node* branch3 = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
| 1090 check3, if_true2); |
| 1091 Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3); |
| 1092 Node* vtrue3; |
| 1093 { |
| 1094 vtrue3 = graph()->NewNode( |
| 1095 simplified()->NumberBitwiseOr(), |
| 1096 graph()->NewNode(simplified()->NumberShiftLeft(), trail, |
| 1097 jsgraph()->Int32Constant(16)), |
| 1098 lead); |
| 1099 } |
| 1100 |
| 1101 Node* if_false3 = graph()->NewNode(common()->IfFalse(), branch3); |
| 1102 Node* vfalse3 = lead; |
| 1103 if_true2 = graph()->NewNode(common()->Merge(2), if_true3, if_false3); |
| 1104 vtrue2 = |
| 1105 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
| 1106 vtrue3, vfalse3, if_true2); |
| 1107 } |
| 1108 |
| 1109 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
| 1110 Node* vfalse2 = lead; |
| 1111 if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
| 1112 vtrue1 = |
| 1113 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
| 1114 vtrue2, vfalse2, if_true1); |
| 1115 } |
| 1116 |
| 1117 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1118 Node* vfalse1 = lead; |
| 1119 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1120 vtrue0 = |
| 1121 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
| 1122 vtrue1, vfalse1, if_true0); |
| 1123 vtrue0 = graph()->NewNode( |
| 1124 simplified()->StringFromCodePoint(UnicodeEncoding::UTF16), vtrue0); |
| 1125 |
| 1126 // Update iterator.[[NextIndex]] |
| 1127 Node* char_length = etrue0 = graph()->NewNode( |
| 1128 simplified()->LoadField(AccessBuilder::ForStringLength()), vtrue0, |
| 1129 etrue0, if_true0); |
| 1130 index = graph()->NewNode(simplified()->NumberAdd(), index, char_length); |
| 1131 etrue0 = graph()->NewNode( |
| 1132 simplified()->StoreField(AccessBuilder::ForJSStringIteratorIndex()), |
| 1133 receiver, index, etrue0, if_true0); |
| 1134 } |
| 1135 |
| 1136 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1137 Node* done_false; |
| 1138 Node* vfalse0; |
| 1139 { |
| 1140 vfalse0 = jsgraph()->UndefinedConstant(); |
| 1141 done_false = jsgraph()->TrueConstant(); |
| 1142 } |
| 1143 |
| 1144 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1145 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, effect, control); |
| 1146 Node* value_phi = |
| 1147 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 1148 vtrue0, vfalse0, control); |
| 1149 Node* done_phi = |
| 1150 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 1151 done_true, done_false, control); |
| 1152 |
| 1153 Node* native_context = effect = |
| 1154 graph()->NewNode(jsgraph()->javascript()->LoadContext( |
| 1155 0, Context::NATIVE_CONTEXT_INDEX, true), |
| 1156 context, context, effect); |
| 1157 Node* map = effect = |
| 1158 graph()->NewNode(jsgraph()->javascript()->LoadContext( |
| 1159 0, Context::ITERATOR_RESULT_MAP_INDEX, true), |
| 1160 context, native_context, effect); |
| 1161 |
| 1162 // Allocate the IterResultObject. |
| 1163 effect = graph()->NewNode( |
| 1164 common()->BeginRegion(RegionObservability::kNotObservable), effect); |
| 1165 Node* value = effect = graph()->NewNode( |
| 1166 simplified()->Allocate(NOT_TENURED), |
| 1167 jsgraph()->Int32Constant(JSIteratorResult::kSize), effect, control); |
| 1168 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), |
| 1169 value, map, effect, control); |
| 1170 effect = graph()->NewNode( |
| 1171 simplified()->StoreField(AccessBuilder::ForJSObjectProperties()), value, |
| 1172 jsgraph()->EmptyFixedArrayConstant(), effect, control); |
| 1173 effect = graph()->NewNode( |
| 1174 simplified()->StoreField(AccessBuilder::ForJSObjectElements()), value, |
| 1175 jsgraph()->EmptyFixedArrayConstant(), effect, control); |
| 1176 effect = graph()->NewNode( |
| 1177 simplified()->StoreField(AccessBuilder::ForJSIteratorResultDone()), |
| 1178 value, done_phi, effect, control); |
| 1179 effect = graph()->NewNode( |
| 1180 simplified()->StoreField(AccessBuilder::ForJSIteratorResultValue()), |
| 1181 value, value_phi, effect, control); |
| 1182 value = effect = graph()->NewNode(common()->FinishRegion(), value, effect); |
| 1183 ReplaceWithValue(node, value, effect, control); |
| 1184 return Replace(value); |
| 1185 } |
| 1186 return NoChange(); |
| 1187 } |
| 1188 |
1029 Reduction JSBuiltinReducer::ReduceArrayBufferViewAccessor( | 1189 Reduction JSBuiltinReducer::ReduceArrayBufferViewAccessor( |
1030 Node* node, InstanceType instance_type, FieldAccess const& access) { | 1190 Node* node, InstanceType instance_type, FieldAccess const& access) { |
1031 Node* receiver = NodeProperties::GetValueInput(node, 1); | 1191 Node* receiver = NodeProperties::GetValueInput(node, 1); |
1032 Node* effect = NodeProperties::GetEffectInput(node); | 1192 Node* effect = NodeProperties::GetEffectInput(node); |
1033 Node* control = NodeProperties::GetControlInput(node); | 1193 Node* control = NodeProperties::GetControlInput(node); |
1034 if (HasInstanceTypeWitness(receiver, effect, instance_type)) { | 1194 if (HasInstanceTypeWitness(receiver, effect, instance_type)) { |
1035 // Load the {receiver}s field. | 1195 // Load the {receiver}s field. |
1036 Node* receiver_value = effect = graph()->NewNode( | 1196 Node* receiver_value = effect = graph()->NewNode( |
1037 simplified()->LoadField(access), receiver, effect, control); | 1197 simplified()->LoadField(access), receiver, effect, control); |
1038 | 1198 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 case kNumberParseInt: | 1348 case kNumberParseInt: |
1189 reduction = ReduceNumberParseInt(node); | 1349 reduction = ReduceNumberParseInt(node); |
1190 break; | 1350 break; |
1191 case kStringFromCharCode: | 1351 case kStringFromCharCode: |
1192 reduction = ReduceStringFromCharCode(node); | 1352 reduction = ReduceStringFromCharCode(node); |
1193 break; | 1353 break; |
1194 case kStringCharAt: | 1354 case kStringCharAt: |
1195 return ReduceStringCharAt(node); | 1355 return ReduceStringCharAt(node); |
1196 case kStringCharCodeAt: | 1356 case kStringCharCodeAt: |
1197 return ReduceStringCharCodeAt(node); | 1357 return ReduceStringCharCodeAt(node); |
| 1358 case kStringIteratorPrototypeNext: |
| 1359 return ReduceStringIteratorPrototypeNext(node); |
1198 case kDataViewByteLength: | 1360 case kDataViewByteLength: |
1199 return ReduceArrayBufferViewAccessor( | 1361 return ReduceArrayBufferViewAccessor( |
1200 node, JS_DATA_VIEW_TYPE, | 1362 node, JS_DATA_VIEW_TYPE, |
1201 AccessBuilder::ForJSArrayBufferViewByteLength()); | 1363 AccessBuilder::ForJSArrayBufferViewByteLength()); |
1202 case kDataViewByteOffset: | 1364 case kDataViewByteOffset: |
1203 return ReduceArrayBufferViewAccessor( | 1365 return ReduceArrayBufferViewAccessor( |
1204 node, JS_DATA_VIEW_TYPE, | 1366 node, JS_DATA_VIEW_TYPE, |
1205 AccessBuilder::ForJSArrayBufferViewByteOffset()); | 1367 AccessBuilder::ForJSArrayBufferViewByteOffset()); |
1206 case kTypedArrayByteLength: | 1368 case kTypedArrayByteLength: |
1207 return ReduceArrayBufferViewAccessor( | 1369 return ReduceArrayBufferViewAccessor( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1250 } | 1412 } |
1251 | 1413 |
1252 | 1414 |
1253 SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const { | 1415 SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const { |
1254 return jsgraph()->simplified(); | 1416 return jsgraph()->simplified(); |
1255 } | 1417 } |
1256 | 1418 |
1257 } // namespace compiler | 1419 } // namespace compiler |
1258 } // namespace internal | 1420 } // namespace internal |
1259 } // namespace v8 | 1421 } // namespace v8 |
OLD | NEW |