| 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/compiler/js-typed-lowering.h" | 5 #include "src/compiler/js-typed-lowering.h" |
| 6 | 6 |
| 7 #include "src/ast/modules.h" | 7 #include "src/ast/modules.h" |
| 8 #include "src/builtins/builtins-utils.h" | 8 #include "src/builtins/builtins-utils.h" |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/compilation-dependencies.h" | 10 #include "src/compilation-dependencies.h" |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 simplified()->LoadField(AccessBuilder::ForStringLength()), | 619 simplified()->LoadField(AccessBuilder::ForStringLength()), |
| 620 second, effect, control); | 620 second, effect, control); |
| 621 | 621 |
| 622 // Compute the resulting length. | 622 // Compute the resulting length. |
| 623 Node* length = | 623 Node* length = |
| 624 graph()->NewNode(simplified()->NumberAdd(), first_length, second_length); | 624 graph()->NewNode(simplified()->NumberAdd(), first_length, second_length); |
| 625 | 625 |
| 626 // Check if we would overflow the allowed maximum string length. | 626 // Check if we would overflow the allowed maximum string length. |
| 627 Node* check = graph()->NewNode(simplified()->NumberLessThanOrEqual(), length, | 627 Node* check = graph()->NewNode(simplified()->NumberLessThanOrEqual(), length, |
| 628 jsgraph()->Constant(String::kMaxLength)); | 628 jsgraph()->Constant(String::kMaxLength)); |
| 629 Node* branch = | 629 if (isolate()->IsStringLengthOverflowIntact()) { |
| 630 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 630 // Add a code dependency on the string length overflow protector. |
| 631 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 631 dependencies()->AssumePropertyCell(factory()->string_length_protector()); |
| 632 Node* efalse = effect; | |
| 633 { | |
| 634 // Throw a RangeError in case of overflow. | |
| 635 Node* vfalse = efalse = graph()->NewNode( | |
| 636 javascript()->CallRuntime(Runtime::kThrowInvalidStringLength), context, | |
| 637 frame_state, efalse, if_false); | |
| 638 if_false = graph()->NewNode(common()->IfSuccess(), vfalse); | |
| 639 if_false = graph()->NewNode(common()->Throw(), vfalse, efalse, if_false); | |
| 640 // TODO(bmeurer): This should be on the AdvancedReducer somehow. | |
| 641 NodeProperties::MergeControlToEnd(graph(), common(), if_false); | |
| 642 Revisit(graph()->end()); | |
| 643 | 632 |
| 644 // Update potential {IfException} uses of {node} to point to the | 633 // We can just deoptimize if the {check} fails. Besides generating a |
| 645 // %ThrowInvalidStringLength runtime call node instead. | 634 // shorter code sequence than the version below, this has the additional |
| 646 for (Edge edge : node->use_edges()) { | 635 // benefit of not holding on to the lazy {frame_state} and thus potentially |
| 647 if (edge.from()->opcode() == IrOpcode::kIfException) { | 636 // reduces the number of live ranges and allows for more truncations. |
| 648 DCHECK(NodeProperties::IsControlEdge(edge) || | 637 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); |
| 649 NodeProperties::IsEffectEdge(edge)); | 638 } else { |
| 650 edge.UpdateTo(vfalse); | 639 Node* branch = |
| 651 Revisit(edge.from()); | 640 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 641 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 642 Node* efalse = effect; |
| 643 { |
| 644 // Throw a RangeError in case of overflow. |
| 645 Node* vfalse = efalse = graph()->NewNode( |
| 646 javascript()->CallRuntime(Runtime::kThrowInvalidStringLength), |
| 647 context, frame_state, efalse, if_false); |
| 648 if_false = graph()->NewNode(common()->IfSuccess(), vfalse); |
| 649 if_false = graph()->NewNode(common()->Throw(), vfalse, efalse, if_false); |
| 650 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| 651 NodeProperties::MergeControlToEnd(graph(), common(), if_false); |
| 652 Revisit(graph()->end()); |
| 653 |
| 654 // Update potential {IfException} uses of {node} to point to the |
| 655 // %ThrowInvalidStringLength runtime call node instead. |
| 656 for (Edge edge : node->use_edges()) { |
| 657 if (edge.from()->opcode() == IrOpcode::kIfException) { |
| 658 DCHECK(NodeProperties::IsControlEdge(edge) || |
| 659 NodeProperties::IsEffectEdge(edge)); |
| 660 edge.UpdateTo(vfalse); |
| 661 Revisit(edge.from()); |
| 662 } |
| 652 } | 663 } |
| 653 } | 664 } |
| 665 control = graph()->NewNode(common()->IfTrue(), branch); |
| 654 } | 666 } |
| 655 control = graph()->NewNode(common()->IfTrue(), branch); | |
| 656 | 667 |
| 657 // Figure out the map for the resulting ConsString. | 668 // Figure out the map for the resulting ConsString. |
| 658 // TODO(turbofan): We currently just use the cons_string_map here for | 669 // TODO(turbofan): We currently just use the cons_string_map here for |
| 659 // the sake of simplicity; we could also try to be smarter here and | 670 // the sake of simplicity; we could also try to be smarter here and |
| 660 // use the one_byte_cons_string_map instead when the resulting ConsString | 671 // use the one_byte_cons_string_map instead when the resulting ConsString |
| 661 // contains only one byte characters. | 672 // contains only one byte characters. |
| 662 Node* value_map = jsgraph()->HeapConstant(factory()->cons_string_map()); | 673 Node* value_map = jsgraph()->HeapConstant(factory()->cons_string_map()); |
| 663 | 674 |
| 664 // Allocate the resulting ConsString. | 675 // Allocate the resulting ConsString. |
| 665 effect = graph()->NewNode( | 676 effect = graph()->NewNode( |
| (...skipping 1584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2250 } | 2261 } |
| 2251 | 2262 |
| 2252 | 2263 |
| 2253 CompilationDependencies* JSTypedLowering::dependencies() const { | 2264 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 2254 return dependencies_; | 2265 return dependencies_; |
| 2255 } | 2266 } |
| 2256 | 2267 |
| 2257 } // namespace compiler | 2268 } // namespace compiler |
| 2258 } // namespace internal | 2269 } // namespace internal |
| 2259 } // namespace v8 | 2270 } // namespace v8 |
| OLD | NEW |