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 |