| 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 |