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 |