| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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-call-reducer.h" | 5 #include "src/compiler/js-call-reducer.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
| 10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
| (...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 // TODO(bmeurer): Also support proxies here. | 944 // TODO(bmeurer): Also support proxies here. |
| 945 return NoChange(); | 945 return NoChange(); |
| 946 } | 946 } |
| 947 | 947 |
| 948 // Extract feedback from the {node} using the CallICNexus. | 948 // Extract feedback from the {node} using the CallICNexus. |
| 949 if (!p.feedback().IsValid()) return NoChange(); | 949 if (!p.feedback().IsValid()) return NoChange(); |
| 950 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); | 950 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); |
| 951 if (nexus.IsUninitialized()) { | 951 if (nexus.IsUninitialized()) { |
| 952 if (flags() & kBailoutOnUninitialized) { | 952 if (flags() & kBailoutOnUninitialized) { |
| 953 // Introduce a SOFT deopt if the call {node} wasn't executed so far. | 953 // Introduce a SOFT deopt if the call {node} wasn't executed so far. |
| 954 Node* frame_state = NodeProperties::FindFrameStateBefore(node); | 954 return ReduceSoftDeoptimize( |
| 955 Node* deoptimize = graph()->NewNode( | 955 node, DeoptimizeReason::kInsufficientTypeFeedbackForCall); |
| 956 common()->Deoptimize( | |
| 957 DeoptimizeKind::kSoft, | |
| 958 DeoptimizeReason::kInsufficientTypeFeedbackForCall), | |
| 959 frame_state, effect, control); | |
| 960 // TODO(bmeurer): This should be on the AdvancedReducer somehow. | |
| 961 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); | |
| 962 Revisit(graph()->end()); | |
| 963 node->TrimInputCount(0); | |
| 964 NodeProperties::ChangeOp(node, common()->Dead()); | |
| 965 return Changed(node); | |
| 966 } | 956 } |
| 967 return NoChange(); | 957 return NoChange(); |
| 968 } | 958 } |
| 969 | 959 |
| 970 Handle<Object> feedback(nexus.GetFeedback(), isolate()); | 960 Handle<Object> feedback(nexus.GetFeedback(), isolate()); |
| 971 if (feedback->IsAllocationSite()) { | 961 if (feedback->IsAllocationSite()) { |
| 972 // Retrieve the Array function from the {node}. | 962 // Retrieve the Array function from the {node}. |
| 973 Node* array_function = jsgraph()->HeapConstant( | 963 Node* array_function = jsgraph()->HeapConstant( |
| 974 handle(native_context()->array_function(), isolate())); | 964 handle(native_context()->array_function(), isolate())); |
| 975 | 965 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site)); | 1066 NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site)); |
| 1077 return Changed(node); | 1067 return Changed(node); |
| 1078 } | 1068 } |
| 1079 } | 1069 } |
| 1080 | 1070 |
| 1081 // Don't mess with other {node}s that have a constant {target}. | 1071 // Don't mess with other {node}s that have a constant {target}. |
| 1082 // TODO(bmeurer): Also support optimizing bound functions and proxies here. | 1072 // TODO(bmeurer): Also support optimizing bound functions and proxies here. |
| 1083 return NoChange(); | 1073 return NoChange(); |
| 1084 } | 1074 } |
| 1085 | 1075 |
| 1076 // Extract feedback from the {node} using the CallICNexus. |
| 1086 if (!p.feedback().IsValid()) return NoChange(); | 1077 if (!p.feedback().IsValid()) return NoChange(); |
| 1087 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); | 1078 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); |
| 1079 if (nexus.IsUninitialized()) { |
| 1080 if (flags() & kBailoutOnUninitialized) { |
| 1081 // Introduce a SOFT deopt if the construct {node} wasn't executed so far. |
| 1082 return ReduceSoftDeoptimize( |
| 1083 node, DeoptimizeReason::kInsufficientTypeFeedbackForConstruct); |
| 1084 } |
| 1085 return NoChange(); |
| 1086 } |
| 1087 |
| 1088 Handle<Object> feedback(nexus.GetFeedback(), isolate()); | 1088 Handle<Object> feedback(nexus.GetFeedback(), isolate()); |
| 1089 if (feedback->IsAllocationSite()) { | 1089 if (feedback->IsAllocationSite()) { |
| 1090 // The feedback is an AllocationSite, which means we have called the | 1090 // The feedback is an AllocationSite, which means we have called the |
| 1091 // Array function and collected transition (and pretenuring) feedback | 1091 // Array function and collected transition (and pretenuring) feedback |
| 1092 // for the resulting arrays. This has to be kept in sync with the | 1092 // for the resulting arrays. This has to be kept in sync with the |
| 1093 // implementation of the CallConstructStub. | 1093 // implementation of the CallConstructStub. |
| 1094 Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback); | 1094 Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback); |
| 1095 | 1095 |
| 1096 // Retrieve the Array function from the {node}. | 1096 // Retrieve the Array function from the {node}. |
| 1097 Node* array_function = jsgraph()->HeapConstant( | 1097 Node* array_function = jsgraph()->HeapConstant( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 return ReduceCallOrConstructWithArrayLikeOrSpread(node, arity, frequency); | 1160 return ReduceCallOrConstructWithArrayLikeOrSpread(node, arity, frequency); |
| 1161 } | 1161 } |
| 1162 | 1162 |
| 1163 Reduction JSCallReducer::ReduceReturnReceiver(Node* node) { | 1163 Reduction JSCallReducer::ReduceReturnReceiver(Node* node) { |
| 1164 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); | 1164 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
| 1165 Node* receiver = NodeProperties::GetValueInput(node, 1); | 1165 Node* receiver = NodeProperties::GetValueInput(node, 1); |
| 1166 ReplaceWithValue(node, receiver); | 1166 ReplaceWithValue(node, receiver); |
| 1167 return Replace(receiver); | 1167 return Replace(receiver); |
| 1168 } | 1168 } |
| 1169 | 1169 |
| 1170 Reduction JSCallReducer::ReduceSoftDeoptimize(Node* node, |
| 1171 DeoptimizeReason reason) { |
| 1172 Node* effect = NodeProperties::GetEffectInput(node); |
| 1173 Node* control = NodeProperties::GetControlInput(node); |
| 1174 Node* frame_state = NodeProperties::FindFrameStateBefore(node); |
| 1175 Node* deoptimize = |
| 1176 graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kSoft, reason), |
| 1177 frame_state, effect, control); |
| 1178 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| 1179 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
| 1180 Revisit(graph()->end()); |
| 1181 node->TrimInputCount(0); |
| 1182 NodeProperties::ChangeOp(node, common()->Dead()); |
| 1183 return Changed(node); |
| 1184 } |
| 1185 |
| 1170 Graph* JSCallReducer::graph() const { return jsgraph()->graph(); } | 1186 Graph* JSCallReducer::graph() const { return jsgraph()->graph(); } |
| 1171 | 1187 |
| 1172 Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); } | 1188 Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); } |
| 1173 | 1189 |
| 1174 Factory* JSCallReducer::factory() const { return isolate()->factory(); } | 1190 Factory* JSCallReducer::factory() const { return isolate()->factory(); } |
| 1175 | 1191 |
| 1176 Handle<JSGlobalProxy> JSCallReducer::global_proxy() const { | 1192 Handle<JSGlobalProxy> JSCallReducer::global_proxy() const { |
| 1177 return handle(JSGlobalProxy::cast(native_context()->global_proxy()), | 1193 return handle(JSGlobalProxy::cast(native_context()->global_proxy()), |
| 1178 isolate()); | 1194 isolate()); |
| 1179 } | 1195 } |
| 1180 | 1196 |
| 1181 CommonOperatorBuilder* JSCallReducer::common() const { | 1197 CommonOperatorBuilder* JSCallReducer::common() const { |
| 1182 return jsgraph()->common(); | 1198 return jsgraph()->common(); |
| 1183 } | 1199 } |
| 1184 | 1200 |
| 1185 JSOperatorBuilder* JSCallReducer::javascript() const { | 1201 JSOperatorBuilder* JSCallReducer::javascript() const { |
| 1186 return jsgraph()->javascript(); | 1202 return jsgraph()->javascript(); |
| 1187 } | 1203 } |
| 1188 | 1204 |
| 1189 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { | 1205 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { |
| 1190 return jsgraph()->simplified(); | 1206 return jsgraph()->simplified(); |
| 1191 } | 1207 } |
| 1192 | 1208 |
| 1193 } // namespace compiler | 1209 } // namespace compiler |
| 1194 } // namespace internal | 1210 } // namespace internal |
| 1195 } // namespace v8 | 1211 } // namespace v8 |
| OLD | NEW |