| 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/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
| 7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
| 8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1103 NodeProperties::GetValueInput(node, 0), effect, control)); | 1103 NodeProperties::GetValueInput(node, 0), effect, control)); |
| 1104 } | 1104 } |
| 1105 node->RemoveInput(2); | 1105 node->RemoveInput(2); |
| 1106 NodeProperties::ChangeOp( | 1106 NodeProperties::ChangeOp( |
| 1107 node, | 1107 node, |
| 1108 simplified()->StoreField(AccessBuilder::ForContextSlot(access.index()))); | 1108 simplified()->StoreField(AccessBuilder::ForContextSlot(access.index()))); |
| 1109 return Changed(node); | 1109 return Changed(node); |
| 1110 } | 1110 } |
| 1111 | 1111 |
| 1112 | 1112 |
| 1113 Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) { | |
| 1114 DCHECK_EQ(IrOpcode::kJSLoadDynamicGlobal, node->opcode()); | |
| 1115 DynamicGlobalAccess const& access = DynamicGlobalAccessOf(node->op()); | |
| 1116 Node* const vector = NodeProperties::GetValueInput(node, 0); | |
| 1117 Node* const context = NodeProperties::GetContextInput(node); | |
| 1118 Node* const state1 = NodeProperties::GetFrameStateInput(node, 0); | |
| 1119 Node* const state2 = NodeProperties::GetFrameStateInput(node, 1); | |
| 1120 Node* const effect = NodeProperties::GetEffectInput(node); | |
| 1121 Node* const control = NodeProperties::GetControlInput(node); | |
| 1122 if (access.RequiresFullCheck()) return NoChange(); | |
| 1123 | |
| 1124 // Perform checks whether the fast mode applies, by looking for any extension | |
| 1125 // object which might shadow the optimistic declaration. | |
| 1126 uint32_t bitset = access.check_bitset(); | |
| 1127 Node* check_true = control; | |
| 1128 Node* check_false = graph()->NewNode(common()->Merge(0)); | |
| 1129 for (int depth = 0; bitset != 0; bitset >>= 1, depth++) { | |
| 1130 if ((bitset & 1) == 0) continue; | |
| 1131 Node* load = graph()->NewNode( | |
| 1132 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | |
| 1133 context, context, effect); | |
| 1134 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), | |
| 1135 load, jsgraph()->ZeroConstant()); | |
| 1136 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, | |
| 1137 check_true); | |
| 1138 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
| 1139 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 1140 check_false->AppendInput(graph()->zone(), if_false); | |
| 1141 NodeProperties::ChangeOp(check_false, | |
| 1142 common()->Merge(check_false->InputCount())); | |
| 1143 check_true = if_true; | |
| 1144 } | |
| 1145 | |
| 1146 // Fast case, because variable is not shadowed. Perform global object load. | |
| 1147 Node* fast = graph()->NewNode( | |
| 1148 javascript()->LoadGlobal(access.name(), access.feedback(), | |
| 1149 access.typeof_mode()), | |
| 1150 vector, context, state1, state2, effect, check_true); | |
| 1151 | |
| 1152 // Slow case, because variable potentially shadowed. Perform dynamic lookup. | |
| 1153 uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; | |
| 1154 Node* slow = graph()->NewNode( | |
| 1155 javascript()->LoadDynamicGlobal(access.name(), check_bitset, | |
| 1156 access.feedback(), access.typeof_mode()), | |
| 1157 vector, context, context, state1, state2, effect, check_false); | |
| 1158 | |
| 1159 // Replace value, effect and control uses accordingly. | |
| 1160 Node* new_control = | |
| 1161 graph()->NewNode(common()->Merge(2), check_true, check_false); | |
| 1162 Node* new_effect = | |
| 1163 graph()->NewNode(common()->EffectPhi(2), fast, slow, new_control); | |
| 1164 Node* new_value = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fast, | |
| 1165 slow, new_control); | |
| 1166 ReplaceWithValue(node, new_value, new_effect, new_control); | |
| 1167 return Changed(new_value); | |
| 1168 } | |
| 1169 | |
| 1170 | |
| 1171 Reduction JSTypedLowering::ReduceJSLoadDynamicContext(Node* node) { | |
| 1172 DCHECK_EQ(IrOpcode::kJSLoadDynamicContext, node->opcode()); | |
| 1173 DynamicContextAccess const& access = DynamicContextAccessOf(node->op()); | |
| 1174 ContextAccess const& context_access = access.context_access(); | |
| 1175 Node* const context = NodeProperties::GetContextInput(node); | |
| 1176 Node* const state = NodeProperties::GetFrameStateInput(node, 0); | |
| 1177 Node* const effect = NodeProperties::GetEffectInput(node); | |
| 1178 Node* const control = NodeProperties::GetControlInput(node); | |
| 1179 if (access.RequiresFullCheck()) return NoChange(); | |
| 1180 | |
| 1181 // Perform checks whether the fast mode applies, by looking for any extension | |
| 1182 // object which might shadow the optimistic declaration. | |
| 1183 uint32_t bitset = access.check_bitset(); | |
| 1184 Node* check_true = control; | |
| 1185 Node* check_false = graph()->NewNode(common()->Merge(0)); | |
| 1186 for (int depth = 0; bitset != 0; bitset >>= 1, depth++) { | |
| 1187 if ((bitset & 1) == 0) continue; | |
| 1188 Node* load = graph()->NewNode( | |
| 1189 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | |
| 1190 context, context, effect); | |
| 1191 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), | |
| 1192 load, jsgraph()->ZeroConstant()); | |
| 1193 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, | |
| 1194 check_true); | |
| 1195 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
| 1196 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 1197 check_false->AppendInput(graph()->zone(), if_false); | |
| 1198 NodeProperties::ChangeOp(check_false, | |
| 1199 common()->Merge(check_false->InputCount())); | |
| 1200 check_true = if_true; | |
| 1201 } | |
| 1202 | |
| 1203 // Fast case, because variable is not shadowed. Perform context slot load. | |
| 1204 Node* fast = | |
| 1205 graph()->NewNode(javascript()->LoadContext(context_access.depth(), | |
| 1206 context_access.index(), false), | |
| 1207 context, context, effect); | |
| 1208 | |
| 1209 // Slow case, because variable potentially shadowed. Perform dynamic lookup. | |
| 1210 uint32_t check_bitset = DynamicContextAccess::kFullCheckRequired; | |
| 1211 Node* slow = | |
| 1212 graph()->NewNode(javascript()->LoadDynamicContext( | |
| 1213 access.name(), check_bitset, context_access.depth(), | |
| 1214 context_access.index()), | |
| 1215 context, context, state, effect, check_false); | |
| 1216 | |
| 1217 // Replace value, effect and control uses accordingly. | |
| 1218 Node* new_control = | |
| 1219 graph()->NewNode(common()->Merge(2), check_true, check_false); | |
| 1220 Node* new_effect = | |
| 1221 graph()->NewNode(common()->EffectPhi(2), fast, slow, new_control); | |
| 1222 Node* new_value = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), fast, | |
| 1223 slow, new_control); | |
| 1224 ReplaceWithValue(node, new_value, new_effect, new_control); | |
| 1225 return Changed(new_value); | |
| 1226 } | |
| 1227 | |
| 1228 | |
| 1229 Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { | 1113 Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { |
| 1230 DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode()); | 1114 DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode()); |
| 1231 ConvertReceiverMode mode = ConvertReceiverModeOf(node->op()); | 1115 ConvertReceiverMode mode = ConvertReceiverModeOf(node->op()); |
| 1232 Node* receiver = NodeProperties::GetValueInput(node, 0); | 1116 Node* receiver = NodeProperties::GetValueInput(node, 0); |
| 1233 Type* receiver_type = NodeProperties::GetType(receiver); | 1117 Type* receiver_type = NodeProperties::GetType(receiver); |
| 1234 Node* context = NodeProperties::GetContextInput(node); | 1118 Node* context = NodeProperties::GetContextInput(node); |
| 1235 Type* context_type = NodeProperties::GetType(context); | 1119 Type* context_type = NodeProperties::GetType(context); |
| 1236 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | 1120 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 1237 Node* effect = NodeProperties::GetEffectInput(node); | 1121 Node* effect = NodeProperties::GetEffectInput(node); |
| 1238 Node* control = NodeProperties::GetControlInput(node); | 1122 Node* control = NodeProperties::GetControlInput(node); |
| (...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2085 case IrOpcode::kJSLoadNamed: | 1969 case IrOpcode::kJSLoadNamed: |
| 2086 return ReduceJSLoadNamed(node); | 1970 return ReduceJSLoadNamed(node); |
| 2087 case IrOpcode::kJSLoadProperty: | 1971 case IrOpcode::kJSLoadProperty: |
| 2088 return ReduceJSLoadProperty(node); | 1972 return ReduceJSLoadProperty(node); |
| 2089 case IrOpcode::kJSStoreProperty: | 1973 case IrOpcode::kJSStoreProperty: |
| 2090 return ReduceJSStoreProperty(node); | 1974 return ReduceJSStoreProperty(node); |
| 2091 case IrOpcode::kJSLoadContext: | 1975 case IrOpcode::kJSLoadContext: |
| 2092 return ReduceJSLoadContext(node); | 1976 return ReduceJSLoadContext(node); |
| 2093 case IrOpcode::kJSStoreContext: | 1977 case IrOpcode::kJSStoreContext: |
| 2094 return ReduceJSStoreContext(node); | 1978 return ReduceJSStoreContext(node); |
| 2095 case IrOpcode::kJSLoadDynamicGlobal: | |
| 2096 return ReduceJSLoadDynamicGlobal(node); | |
| 2097 case IrOpcode::kJSLoadDynamicContext: | |
| 2098 return ReduceJSLoadDynamicContext(node); | |
| 2099 case IrOpcode::kJSConvertReceiver: | 1979 case IrOpcode::kJSConvertReceiver: |
| 2100 return ReduceJSConvertReceiver(node); | 1980 return ReduceJSConvertReceiver(node); |
| 2101 case IrOpcode::kJSCreateArguments: | 1981 case IrOpcode::kJSCreateArguments: |
| 2102 return ReduceJSCreateArguments(node); | 1982 return ReduceJSCreateArguments(node); |
| 2103 case IrOpcode::kJSCreateClosure: | 1983 case IrOpcode::kJSCreateClosure: |
| 2104 return ReduceJSCreateClosure(node); | 1984 return ReduceJSCreateClosure(node); |
| 2105 case IrOpcode::kJSCreateLiteralArray: | 1985 case IrOpcode::kJSCreateLiteralArray: |
| 2106 return ReduceJSCreateLiteralArray(node); | 1986 return ReduceJSCreateLiteralArray(node); |
| 2107 case IrOpcode::kJSCreateLiteralObject: | 1987 case IrOpcode::kJSCreateLiteralObject: |
| 2108 return ReduceJSCreateLiteralObject(node); | 1988 return ReduceJSCreateLiteralObject(node); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2235 } | 2115 } |
| 2236 | 2116 |
| 2237 | 2117 |
| 2238 MachineOperatorBuilder* JSTypedLowering::machine() const { | 2118 MachineOperatorBuilder* JSTypedLowering::machine() const { |
| 2239 return jsgraph()->machine(); | 2119 return jsgraph()->machine(); |
| 2240 } | 2120 } |
| 2241 | 2121 |
| 2242 } // namespace compiler | 2122 } // namespace compiler |
| 2243 } // namespace internal | 2123 } // namespace internal |
| 2244 } // namespace v8 | 2124 } // namespace v8 |
| OLD | NEW |