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 |