Index: src/compiler/js-typed-lowering.cc |
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc |
index 35c6797a019fd8ab731e0be891b5ab0c290ca252..e644292f8591feec602db0e83a3c7264ab941c90 100644 |
--- a/src/compiler/js-typed-lowering.cc |
+++ b/src/compiler/js-typed-lowering.cc |
@@ -626,33 +626,44 @@ Reduction JSTypedLowering::ReduceCreateConsString(Node* node) { |
// Check if we would overflow the allowed maximum string length. |
Node* check = graph()->NewNode(simplified()->NumberLessThanOrEqual(), length, |
jsgraph()->Constant(String::kMaxLength)); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- { |
- // Throw a RangeError in case of overflow. |
- Node* vfalse = efalse = graph()->NewNode( |
- javascript()->CallRuntime(Runtime::kThrowInvalidStringLength), context, |
- frame_state, efalse, if_false); |
- if_false = graph()->NewNode(common()->IfSuccess(), vfalse); |
- if_false = graph()->NewNode(common()->Throw(), vfalse, efalse, if_false); |
- // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
- NodeProperties::MergeControlToEnd(graph(), common(), if_false); |
- Revisit(graph()->end()); |
- |
- // Update potential {IfException} uses of {node} to point to the |
- // %ThrowInvalidStringLength runtime call node instead. |
- for (Edge edge : node->use_edges()) { |
- if (edge.from()->opcode() == IrOpcode::kIfException) { |
- DCHECK(NodeProperties::IsControlEdge(edge) || |
- NodeProperties::IsEffectEdge(edge)); |
- edge.UpdateTo(vfalse); |
- Revisit(edge.from()); |
+ if (isolate()->IsStringLengthOverflowIntact()) { |
+ // Add a code dependency on the string length overflow protector. |
+ dependencies()->AssumePropertyCell(factory()->string_length_protector()); |
+ |
+ // We can just deoptimize if the {check} fails. Besides generating a |
+ // shorter code sequence than the version below, this has the additional |
+ // benefit of not holding on to the lazy {frame_state} and thus potentially |
+ // reduces the number of live ranges and allows for more truncations. |
+ effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); |
+ } else { |
+ Node* branch = |
+ graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
+ Node* efalse = effect; |
+ { |
+ // Throw a RangeError in case of overflow. |
+ Node* vfalse = efalse = graph()->NewNode( |
+ javascript()->CallRuntime(Runtime::kThrowInvalidStringLength), |
+ context, frame_state, efalse, if_false); |
+ if_false = graph()->NewNode(common()->IfSuccess(), vfalse); |
+ if_false = graph()->NewNode(common()->Throw(), vfalse, efalse, if_false); |
+ // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
+ NodeProperties::MergeControlToEnd(graph(), common(), if_false); |
+ Revisit(graph()->end()); |
+ |
+ // Update potential {IfException} uses of {node} to point to the |
+ // %ThrowInvalidStringLength runtime call node instead. |
+ for (Edge edge : node->use_edges()) { |
+ if (edge.from()->opcode() == IrOpcode::kIfException) { |
+ DCHECK(NodeProperties::IsControlEdge(edge) || |
+ NodeProperties::IsEffectEdge(edge)); |
+ edge.UpdateTo(vfalse); |
+ Revisit(edge.from()); |
+ } |
} |
} |
+ control = graph()->NewNode(common()->IfTrue(), branch); |
} |
- control = graph()->NewNode(common()->IfTrue(), branch); |
// Figure out the map for the resulting ConsString. |
// TODO(turbofan): We currently just use the cons_string_map here for |