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/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compilation-dependencies.h" | 8 #include "src/compilation-dependencies.h" |
9 #include "src/compiler/access-builder.h" | 9 #include "src/compiler/access-builder.h" |
10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 } | 659 } |
660 | 660 |
661 Reduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) { | 661 Reduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) { |
662 HeapObjectBinopMatcher m(node); | 662 HeapObjectBinopMatcher m(node); |
663 if (m.left().IsJSTypeOf() && m.right().HasValue() && | 663 if (m.left().IsJSTypeOf() && m.right().HasValue() && |
664 m.right().Value()->IsString()) { | 664 m.right().Value()->IsString()) { |
665 Node* replacement; | 665 Node* replacement; |
666 Node* input = m.left().InputAt(0); | 666 Node* input = m.left().InputAt(0); |
667 Handle<String> value = Handle<String>::cast(m.right().Value()); | 667 Handle<String> value = Handle<String>::cast(m.right().Value()); |
668 if (String::Equals(value, factory()->boolean_string())) { | 668 if (String::Equals(value, factory()->boolean_string())) { |
669 replacement = graph()->NewNode( | 669 replacement = |
670 common()->Select(MachineRepresentation::kTagged), | 670 graph()->NewNode(common()->Select(MachineRepresentation::kTagged), |
671 graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), input, | 671 graph()->NewNode(simplified()->ReferenceEqual(), |
672 jsgraph()->TrueConstant()), | 672 input, jsgraph()->TrueConstant()), |
673 jsgraph()->TrueConstant(), | 673 jsgraph()->TrueConstant(), |
674 graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), input, | 674 graph()->NewNode(simplified()->ReferenceEqual(), |
675 jsgraph()->FalseConstant())); | 675 input, jsgraph()->FalseConstant())); |
676 } else if (String::Equals(value, factory()->function_string())) { | 676 } else if (String::Equals(value, factory()->function_string())) { |
677 replacement = graph()->NewNode(simplified()->ObjectIsCallable(), input); | 677 replacement = graph()->NewNode(simplified()->ObjectIsCallable(), input); |
678 } else if (String::Equals(value, factory()->number_string())) { | 678 } else if (String::Equals(value, factory()->number_string())) { |
679 replacement = graph()->NewNode(simplified()->ObjectIsNumber(), input); | 679 replacement = graph()->NewNode(simplified()->ObjectIsNumber(), input); |
680 } else if (String::Equals(value, factory()->string_string())) { | 680 } else if (String::Equals(value, factory()->string_string())) { |
681 replacement = graph()->NewNode(simplified()->ObjectIsString(), input); | 681 replacement = graph()->NewNode(simplified()->ObjectIsString(), input); |
682 } else if (String::Equals(value, factory()->undefined_string())) { | 682 } else if (String::Equals(value, factory()->undefined_string())) { |
683 replacement = graph()->NewNode( | 683 replacement = graph()->NewNode( |
684 common()->Select(MachineRepresentation::kTagged), | 684 common()->Select(MachineRepresentation::kTagged), |
685 graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), input, | 685 graph()->NewNode(simplified()->ReferenceEqual(), input, |
686 jsgraph()->NullConstant()), | 686 jsgraph()->NullConstant()), |
687 jsgraph()->FalseConstant(), | 687 jsgraph()->FalseConstant(), |
688 graph()->NewNode(simplified()->ObjectIsUndetectable(), input)); | 688 graph()->NewNode(simplified()->ObjectIsUndetectable(), input)); |
689 } else { | 689 } else { |
690 return NoChange(); | 690 return NoChange(); |
691 } | 691 } |
692 if (invert) { | 692 if (invert) { |
693 replacement = graph()->NewNode(simplified()->BooleanNot(), replacement); | 693 replacement = graph()->NewNode(simplified()->BooleanNot(), replacement); |
694 } | 694 } |
695 ReplaceWithValue(node, replacement); | 695 ReplaceWithValue(node, replacement); |
696 return Replace(replacement); | 696 return Replace(replacement); |
697 } | 697 } |
698 return NoChange(); | 698 return NoChange(); |
699 } | 699 } |
700 | 700 |
701 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { | 701 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { |
702 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); | 702 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); |
703 if (reduction.Changed()) return reduction; | 703 if (reduction.Changed()) return reduction; |
704 | 704 |
705 JSBinopReduction r(this, node); | 705 JSBinopReduction r(this, node); |
706 | 706 |
707 if (r.BothInputsAre(Type::String())) { | 707 if (r.BothInputsAre(Type::String())) { |
708 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); | 708 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); |
709 } | 709 } |
710 if (r.BothInputsAre(Type::Boolean())) { | 710 if (r.BothInputsAre(Type::Boolean())) { |
711 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()), | 711 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
712 invert); | |
713 } | 712 } |
714 if (r.BothInputsAre(Type::Receiver())) { | 713 if (r.BothInputsAre(Type::Receiver())) { |
715 return r.ChangeToPureOperator( | 714 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
716 simplified()->ReferenceEqual(Type::Receiver()), invert); | |
717 } | 715 } |
718 if (r.OneInputIs(Type::Undetectable())) { | 716 if (r.OneInputIs(Type::Undetectable())) { |
719 RelaxEffectsAndControls(node); | 717 RelaxEffectsAndControls(node); |
720 node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1); | 718 node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1); |
721 node->TrimInputCount(1); | 719 node->TrimInputCount(1); |
722 NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable()); | 720 NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable()); |
723 if (invert) { | 721 if (invert) { |
724 // Insert an boolean not to invert the value. | 722 // Insert an boolean not to invert the value. |
725 Node* value = graph()->NewNode(simplified()->BooleanNot(), node); | 723 Node* value = graph()->NewNode(simplified()->BooleanNot(), node); |
726 node->ReplaceUses(value); | 724 node->ReplaceUses(value); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 Node* replacement = jsgraph()->BooleanConstant(invert); | 761 Node* replacement = jsgraph()->BooleanConstant(invert); |
764 ReplaceWithValue(node, replacement); | 762 ReplaceWithValue(node, replacement); |
765 return Replace(replacement); | 763 return Replace(replacement); |
766 } | 764 } |
767 } | 765 } |
768 | 766 |
769 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); | 767 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); |
770 if (reduction.Changed()) return reduction; | 768 if (reduction.Changed()) return reduction; |
771 | 769 |
772 if (r.OneInputIs(the_hole_type_)) { | 770 if (r.OneInputIs(the_hole_type_)) { |
773 return r.ChangeToPureOperator(simplified()->ReferenceEqual(the_hole_type_), | 771 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
774 invert); | |
775 } | 772 } |
776 if (r.OneInputIs(Type::Undefined())) { | 773 if (r.OneInputIs(Type::Undefined())) { |
777 return r.ChangeToPureOperator( | 774 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
778 simplified()->ReferenceEqual(Type::Undefined()), invert); | |
779 } | 775 } |
780 if (r.OneInputIs(Type::Null())) { | 776 if (r.OneInputIs(Type::Null())) { |
781 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()), | 777 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
782 invert); | |
783 } | 778 } |
784 if (r.OneInputIs(Type::Boolean())) { | 779 if (r.OneInputIs(Type::Boolean())) { |
785 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()), | 780 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
786 invert); | |
787 } | 781 } |
788 if (r.OneInputIs(Type::Object())) { | 782 if (r.OneInputIs(Type::Object())) { |
789 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Object()), | 783 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
790 invert); | |
791 } | 784 } |
792 if (r.OneInputIs(Type::Receiver())) { | 785 if (r.OneInputIs(Type::Receiver())) { |
793 return r.ChangeToPureOperator( | 786 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
794 simplified()->ReferenceEqual(Type::Receiver()), invert); | |
795 } | 787 } |
796 if (r.BothInputsAre(Type::Unique())) { | 788 if (r.BothInputsAre(Type::Unique())) { |
797 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()), | 789 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); |
798 invert); | |
799 } | 790 } |
800 if (r.BothInputsAre(Type::String())) { | 791 if (r.BothInputsAre(Type::String())) { |
801 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); | 792 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); |
802 } | 793 } |
803 | 794 |
804 NumberOperationHint hint; | 795 NumberOperationHint hint; |
805 if (r.BothInputsAre(Type::Signed32()) || | 796 if (r.BothInputsAre(Type::Signed32()) || |
806 r.BothInputsAre(Type::Unsigned32())) { | 797 r.BothInputsAre(Type::Unsigned32())) { |
807 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 798 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
808 } else if (r.GetCompareNumberOperationHint(&hint)) { | 799 } else if (r.GetCompareNumberOperationHint(&hint)) { |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 prototype, context, frame_state, effect, control); | 1295 prototype, context, frame_state, effect, control); |
1305 | 1296 |
1306 control = graph()->NewNode(common()->IfFalse(), branch_is_proxy); | 1297 control = graph()->NewNode(common()->IfFalse(), branch_is_proxy); |
1307 | 1298 |
1308 Node* object_prototype = effect = graph()->NewNode( | 1299 Node* object_prototype = effect = graph()->NewNode( |
1309 simplified()->LoadField(AccessBuilder::ForMapPrototype()), | 1300 simplified()->LoadField(AccessBuilder::ForMapPrototype()), |
1310 loop_object_map, loop_effect, control); | 1301 loop_object_map, loop_effect, control); |
1311 | 1302 |
1312 // If not, check if object prototype is the null prototype. | 1303 // If not, check if object prototype is the null prototype. |
1313 Node* null_proto = | 1304 Node* null_proto = |
1314 graph()->NewNode(simplified()->ReferenceEqual(r.right_type()), | 1305 graph()->NewNode(simplified()->ReferenceEqual(), object_prototype, |
1315 object_prototype, jsgraph()->NullConstant()); | 1306 jsgraph()->NullConstant()); |
1316 Node* branch_null_proto = graph()->NewNode( | 1307 Node* branch_null_proto = graph()->NewNode( |
1317 common()->Branch(BranchHint::kFalse), null_proto, control); | 1308 common()->Branch(BranchHint::kFalse), null_proto, control); |
1318 Node* if_null_proto = graph()->NewNode(common()->IfTrue(), branch_null_proto); | 1309 Node* if_null_proto = graph()->NewNode(common()->IfTrue(), branch_null_proto); |
1319 Node* e_null_proto = effect; | 1310 Node* e_null_proto = effect; |
1320 | 1311 |
1321 control = graph()->NewNode(common()->IfFalse(), branch_null_proto); | 1312 control = graph()->NewNode(common()->IfFalse(), branch_null_proto); |
1322 | 1313 |
1323 // Check if object prototype is equal to function prototype. | 1314 // Check if object prototype is equal to function prototype. |
1324 Node* eq_proto = | 1315 Node* eq_proto = graph()->NewNode(simplified()->ReferenceEqual(), |
1325 graph()->NewNode(simplified()->ReferenceEqual(r.right_type()), | 1316 object_prototype, prototype); |
1326 object_prototype, prototype); | |
1327 Node* branch_eq_proto = | 1317 Node* branch_eq_proto = |
1328 graph()->NewNode(common()->Branch(BranchHint::kFalse), eq_proto, control); | 1318 graph()->NewNode(common()->Branch(BranchHint::kFalse), eq_proto, control); |
1329 Node* if_eq_proto = graph()->NewNode(common()->IfTrue(), branch_eq_proto); | 1319 Node* if_eq_proto = graph()->NewNode(common()->IfTrue(), branch_eq_proto); |
1330 Node* e_eq_proto = effect; | 1320 Node* e_eq_proto = effect; |
1331 | 1321 |
1332 control = graph()->NewNode(common()->IfFalse(), branch_eq_proto); | 1322 control = graph()->NewNode(common()->IfFalse(), branch_eq_proto); |
1333 | 1323 |
1334 Node* load_object_map = effect = | 1324 Node* load_object_map = effect = |
1335 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), | 1325 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
1336 object_prototype, effect, control); | 1326 object_prototype, effect, control); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true), | 1423 javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true), |
1434 native_context, native_context, effect); | 1424 native_context, native_context, effect); |
1435 } | 1425 } |
1436 } else if (!receiver_type->Maybe(Type::NullOrUndefined()) || | 1426 } else if (!receiver_type->Maybe(Type::NullOrUndefined()) || |
1437 mode == ConvertReceiverMode::kNotNullOrUndefined) { | 1427 mode == ConvertReceiverMode::kNotNullOrUndefined) { |
1438 receiver = effect = | 1428 receiver = effect = |
1439 graph()->NewNode(javascript()->ToObject(), receiver, context, | 1429 graph()->NewNode(javascript()->ToObject(), receiver, context, |
1440 frame_state, effect, control); | 1430 frame_state, effect, control); |
1441 } else { | 1431 } else { |
1442 // Check {receiver} for undefined. | 1432 // Check {receiver} for undefined. |
1443 Node* check0 = | 1433 Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(), receiver, |
1444 graph()->NewNode(simplified()->ReferenceEqual(receiver_type), | 1434 jsgraph()->UndefinedConstant()); |
1445 receiver, jsgraph()->UndefinedConstant()); | |
1446 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 1435 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
1447 check0, control); | 1436 check0, control); |
1448 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1437 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
1449 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 1438 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
1450 | 1439 |
1451 // Check {receiver} for null. | 1440 // Check {receiver} for null. |
1452 Node* check1 = | 1441 Node* check1 = graph()->NewNode(simplified()->ReferenceEqual(), receiver, |
1453 graph()->NewNode(simplified()->ReferenceEqual(receiver_type), | 1442 jsgraph()->NullConstant()); |
1454 receiver, jsgraph()->NullConstant()); | |
1455 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 1443 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
1456 check1, if_false0); | 1444 check1, if_false0); |
1457 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | 1445 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
1458 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | 1446 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
1459 | 1447 |
1460 // Convert {receiver} using ToObject. | 1448 // Convert {receiver} using ToObject. |
1461 Node* if_convert = if_false1; | 1449 Node* if_convert = if_false1; |
1462 Node* econvert = effect; | 1450 Node* econvert = effect; |
1463 Node* rconvert; | 1451 Node* rconvert; |
1464 { | 1452 { |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 Node* key = effect = graph()->NewNode( | 1683 Node* key = effect = graph()->NewNode( |
1696 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), | 1684 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), |
1697 cache_array, index, effect, control); | 1685 cache_array, index, effect, control); |
1698 | 1686 |
1699 // Load the map of the {receiver}. | 1687 // Load the map of the {receiver}. |
1700 Node* receiver_map = effect = | 1688 Node* receiver_map = effect = |
1701 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), | 1689 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
1702 receiver, effect, control); | 1690 receiver, effect, control); |
1703 | 1691 |
1704 // Check if the expected map still matches that of the {receiver}. | 1692 // Check if the expected map still matches that of the {receiver}. |
1705 Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), | 1693 Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(), receiver_map, |
1706 receiver_map, cache_type); | 1694 cache_type); |
1707 Node* branch0 = | 1695 Node* branch0 = |
1708 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); | 1696 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
1709 | 1697 |
1710 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1698 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
1711 Node* etrue0; | 1699 Node* etrue0; |
1712 Node* vtrue0; | 1700 Node* vtrue0; |
1713 { | 1701 { |
1714 // Don't need filtering since expected map still matches that of the | 1702 // Don't need filtering since expected map still matches that of the |
1715 // {receiver}. | 1703 // {receiver}. |
1716 etrue0 = effect; | 1704 etrue0 = effect; |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2126 } | 2114 } |
2127 | 2115 |
2128 | 2116 |
2129 CompilationDependencies* JSTypedLowering::dependencies() const { | 2117 CompilationDependencies* JSTypedLowering::dependencies() const { |
2130 return dependencies_; | 2118 return dependencies_; |
2131 } | 2119 } |
2132 | 2120 |
2133 } // namespace compiler | 2121 } // namespace compiler |
2134 } // namespace internal | 2122 } // namespace internal |
2135 } // namespace v8 | 2123 } // namespace v8 |
OLD | NEW |