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/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 return Changed(node); | 1093 return Changed(node); |
1094 } | 1094 } |
1095 } | 1095 } |
1096 } | 1096 } |
1097 return NoChange(); | 1097 return NoChange(); |
1098 } | 1098 } |
1099 | 1099 |
1100 | 1100 |
1101 Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) { | 1101 Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) { |
1102 DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode()); | 1102 DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode()); |
| 1103 Node* const context = NodeProperties::GetContextInput(node); |
| 1104 Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0); |
1103 | 1105 |
1104 // If deoptimization is disabled, we cannot optimize. | 1106 // If deoptimization is disabled, we cannot optimize. |
1105 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | 1107 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
1106 | 1108 |
| 1109 // If we are in a try block, don't optimize since the runtime call |
| 1110 // in the proxy case can throw. |
| 1111 if (NodeProperties::IsExceptionalCall(node)) return NoChange(); |
| 1112 |
1107 JSBinopReduction r(this, node); | 1113 JSBinopReduction r(this, node); |
1108 Node* effect = r.effect(); | 1114 Node* effect = r.effect(); |
1109 Node* control = r.control(); | 1115 Node* control = r.control(); |
1110 | 1116 |
1111 if (r.right_type()->IsConstant() && | 1117 if (r.right_type()->IsConstant() && |
1112 r.right_type()->AsConstant()->Value()->IsJSFunction()) { | 1118 r.right_type()->AsConstant()->Value()->IsJSFunction()) { |
1113 Handle<JSFunction> function = | 1119 Handle<JSFunction> function = |
1114 Handle<JSFunction>::cast(r.right_type()->AsConstant()->Value()); | 1120 Handle<JSFunction>::cast(r.right_type()->AsConstant()->Value()); |
1115 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); | 1121 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); |
1116 if (function->IsConstructor() && | 1122 if (function->IsConstructor() && |
(...skipping 25 matching lines...) Expand all Loading... |
1142 Node* loop = control = | 1148 Node* loop = control = |
1143 graph()->NewNode(common()->Loop(2), control, control); | 1149 graph()->NewNode(common()->Loop(2), control, control); |
1144 | 1150 |
1145 Node* loop_effect = effect = | 1151 Node* loop_effect = effect = |
1146 graph()->NewNode(common()->EffectPhi(2), effect, effect, loop); | 1152 graph()->NewNode(common()->EffectPhi(2), effect, effect, loop); |
1147 | 1153 |
1148 Node* loop_object_map = | 1154 Node* loop_object_map = |
1149 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 1155 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
1150 object_map, r.left(), loop); | 1156 object_map, r.left(), loop); |
1151 | 1157 |
| 1158 // Check if the lhs is a proxy. |
| 1159 Node* map_instance_type = effect = graph()->NewNode( |
| 1160 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), |
| 1161 loop_object_map, loop_effect, control); |
| 1162 Node* is_proxy = |
| 1163 graph()->NewNode(machine()->Word32Equal(), map_instance_type, |
| 1164 jsgraph()->Uint32Constant(JS_PROXY_TYPE)); |
| 1165 Node* branch_is_proxy = graph()->NewNode( |
| 1166 common()->Branch(BranchHint::kFalse), is_proxy, control); |
| 1167 Node* if_is_proxy = graph()->NewNode(common()->IfTrue(), branch_is_proxy); |
| 1168 Node* e_is_proxy = effect; |
| 1169 |
| 1170 // If it is, make a runtime call to finish the lowering. |
| 1171 Node* bool_result = e_is_proxy = graph()->NewNode( |
| 1172 javascript()->CallRuntime(Runtime::kHasInPrototypeChain, 2), r.left(), |
| 1173 prototype, context, frame_state, e_is_proxy, if_is_proxy); |
| 1174 |
| 1175 control = graph()->NewNode(common()->IfFalse(), branch_is_proxy); |
1152 | 1176 |
1153 Node* object_prototype = effect = graph()->NewNode( | 1177 Node* object_prototype = effect = graph()->NewNode( |
1154 simplified()->LoadField(AccessBuilder::ForMapPrototype()), | 1178 simplified()->LoadField(AccessBuilder::ForMapPrototype()), |
1155 loop_object_map, loop_effect, control); | 1179 loop_object_map, loop_effect, control); |
1156 | 1180 |
1157 // Check if object prototype is equal to function prototype. | 1181 // Check if object prototype is equal to function prototype. |
1158 Node* eq_proto = | 1182 Node* eq_proto = |
1159 graph()->NewNode(simplified()->ReferenceEqual(r.right_type()), | 1183 graph()->NewNode(simplified()->ReferenceEqual(r.right_type()), |
1160 object_prototype, prototype); | 1184 object_prototype, prototype); |
1161 Node* branch_eq_proto = graph()->NewNode( | 1185 Node* branch_eq_proto = graph()->NewNode( |
(...skipping 15 matching lines...) Expand all Loading... |
1177 | 1201 |
1178 control = graph()->NewNode(common()->IfFalse(), branch_null_proto); | 1202 control = graph()->NewNode(common()->IfFalse(), branch_null_proto); |
1179 Node* load_object_map = effect = | 1203 Node* load_object_map = effect = |
1180 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), | 1204 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
1181 object_prototype, effect, control); | 1205 object_prototype, effect, control); |
1182 // Close the loop. | 1206 // Close the loop. |
1183 loop_effect->ReplaceInput(1, effect); | 1207 loop_effect->ReplaceInput(1, effect); |
1184 loop_object_map->ReplaceInput(1, load_object_map); | 1208 loop_object_map->ReplaceInput(1, load_object_map); |
1185 loop->ReplaceInput(1, control); | 1209 loop->ReplaceInput(1, control); |
1186 | 1210 |
1187 control = | 1211 control = graph()->NewNode(common()->Merge(3), if_is_proxy, if_eq_proto, |
1188 graph()->NewNode(common()->Merge(2), if_eq_proto, if_null_proto); | 1212 if_null_proto); |
1189 effect = graph()->NewNode(common()->EffectPhi(2), e_eq_proto, | 1213 effect = graph()->NewNode(common()->EffectPhi(3), e_is_proxy, e_eq_proto, |
1190 e_null_proto, control); | 1214 e_null_proto, control); |
1191 | 1215 |
1192 | 1216 |
1193 Node* result = graph()->NewNode( | 1217 Node* result = graph()->NewNode( |
1194 common()->Phi(MachineRepresentation::kTagged, 2), | 1218 common()->Phi(MachineRepresentation::kTagged, 3), bool_result, |
1195 jsgraph()->TrueConstant(), jsgraph()->FalseConstant(), control); | 1219 jsgraph()->TrueConstant(), jsgraph()->FalseConstant(), control); |
1196 | 1220 |
1197 if (if_is_smi != nullptr) { | 1221 if (if_is_smi != nullptr) { |
1198 DCHECK(e_is_smi != nullptr); | 1222 DCHECK(e_is_smi != nullptr); |
1199 control = graph()->NewNode(common()->Merge(2), if_is_smi, control); | 1223 control = graph()->NewNode(common()->Merge(2), if_is_smi, control); |
1200 effect = | 1224 effect = |
1201 graph()->NewNode(common()->EffectPhi(2), e_is_smi, effect, control); | 1225 graph()->NewNode(common()->EffectPhi(2), e_is_smi, effect, control); |
1202 result = | 1226 result = |
1203 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 1227 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
1204 jsgraph()->FalseConstant(), result, control); | 1228 jsgraph()->FalseConstant(), result, control); |
(...skipping 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2689 } | 2713 } |
2690 | 2714 |
2691 | 2715 |
2692 CompilationDependencies* JSTypedLowering::dependencies() const { | 2716 CompilationDependencies* JSTypedLowering::dependencies() const { |
2693 return dependencies_; | 2717 return dependencies_; |
2694 } | 2718 } |
2695 | 2719 |
2696 } // namespace compiler | 2720 } // namespace compiler |
2697 } // namespace internal | 2721 } // namespace internal |
2698 } // namespace v8 | 2722 } // namespace v8 |
OLD | NEW |