| 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/v8.h" | 5 #include "src/v8.h" |
| 6 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
| 7 | 7 |
| 8 #include "src/compiler/graph-inl.h" | 8 #include "src/compiler/graph-inl.h" |
| 9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
| 10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 JSTypedLoweringTester R; | 677 JSTypedLoweringTester R; |
| 678 | 678 |
| 679 const Operator* ops[] = { | 679 const Operator* ops[] = { |
| 680 R.javascript.LessThan(), R.simplified.NumberLessThan(), | 680 R.javascript.LessThan(), R.simplified.NumberLessThan(), |
| 681 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 681 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
| 682 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), | 682 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
| 683 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; | 683 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; |
| 684 | 684 |
| 685 for (size_t i = 0; i < arraysize(kJSTypes); i++) { | 685 for (size_t i = 0; i < arraysize(kJSTypes); i++) { |
| 686 Type* t0 = kJSTypes[i]; | 686 Type* t0 = kJSTypes[i]; |
| 687 if (t0->Is(Type::String())) continue; // skip Type::String | 687 // Skip Type::String and Type::Receiver which might coerce into a string. |
| 688 if (t0->Is(Type::String()) || t0->Is(Type::Receiver())) continue; |
| 688 Node* p0 = R.Parameter(t0, 0); | 689 Node* p0 = R.Parameter(t0, 0); |
| 689 | 690 |
| 690 for (size_t j = 0; j < arraysize(kJSTypes); j++) { | 691 for (size_t j = 0; j < arraysize(kJSTypes); j++) { |
| 691 Type* t1 = kJSTypes[j]; | 692 Type* t1 = kJSTypes[j]; |
| 692 if (t1->Is(Type::String())) continue; // skip Type::String | 693 // Skip Type::String and Type::Receiver which might coerce into a string. |
| 694 if (t1->Is(Type::String()) || t0->Is(Type::Receiver())) continue; |
| 693 Node* p1 = R.Parameter(t1, 1); | 695 Node* p1 = R.Parameter(t1, 1); |
| 694 | 696 |
| 695 for (size_t k = 0; k < arraysize(ops); k += 2) { | 697 for (size_t k = 0; k < arraysize(ops); k += 2) { |
| 696 Node* cmp = R.Binop(ops[k], p0, p1); | 698 Node* cmp = R.Binop(ops[k], p0, p1); |
| 697 Node* r = R.reduce(cmp); | 699 Node* r = R.reduce(cmp); |
| 698 | 700 |
| 699 R.CheckPureBinop(ops[k + 1], r); | 701 R.CheckPureBinop(ops[k + 1], r); |
| 700 if (k >= 4) { | 702 if (k >= 4) { |
| 701 // GreaterThan and GreaterThanOrEqual commute the inputs | 703 // GreaterThan and GreaterThanOrEqual commute the inputs |
| 702 // and use the LessThan and LessThanOrEqual operators. | 704 // and use the LessThan and LessThanOrEqual operators. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 } | 741 } |
| 740 } | 742 } |
| 741 } | 743 } |
| 742 } | 744 } |
| 743 } | 745 } |
| 744 | 746 |
| 745 | 747 |
| 746 TEST(ObjectComparison) { | 748 TEST(ObjectComparison) { |
| 747 JSTypedLoweringTester R; | 749 JSTypedLoweringTester R; |
| 748 | 750 |
| 749 Node* p0 = R.Parameter(Type::Object(), 0); | 751 Node* p0 = R.Parameter(Type::Number(), 0); |
| 750 Node* p1 = R.Parameter(Type::Object(), 1); | 752 Node* p1 = R.Parameter(Type::Object(), 1); |
| 751 | 753 |
| 752 Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1); | 754 Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1); |
| 753 Node* effect_use = R.UseForEffect(cmp); | 755 Node* effect_use = R.UseForEffect(cmp); |
| 754 | 756 |
| 755 R.CheckEffectInput(R.start(), cmp); | 757 R.CheckEffectInput(R.start(), cmp); |
| 756 R.CheckEffectInput(cmp, effect_use); | 758 R.CheckEffectInput(cmp, effect_use); |
| 757 | 759 |
| 758 Node* r = R.reduce(cmp); | 760 Node* r = R.reduce(cmp); |
| 759 | 761 |
| 760 R.CheckPureBinop(R.simplified.NumberLessThan(), r); | 762 R.CheckPureBinop(R.simplified.NumberLessThan(), r); |
| 761 | 763 |
| 762 Node* i0 = r->InputAt(0); | 764 Node* i0 = r->InputAt(0); |
| 763 Node* i1 = r->InputAt(1); | 765 Node* i1 = r->InputAt(1); |
| 764 | 766 |
| 765 CHECK_NE(p0, i0); | 767 CHECK_EQ(p0, i0); |
| 766 CHECK_NE(p1, i1); | 768 CHECK_NE(p1, i1); |
| 767 CHECK_EQ(IrOpcode::kJSToNumber, i0->opcode()); | 769 CHECK_EQ(IrOpcode::kParameter, i0->opcode()); |
| 768 CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode()); | 770 CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode()); |
| 769 | 771 |
| 770 // Check effect chain is correct. | 772 // Check effect chain is correct. |
| 771 R.CheckEffectInput(R.start(), i0); | 773 R.CheckEffectInput(R.start(), i1); |
| 772 R.CheckEffectInput(i0, i1); | |
| 773 R.CheckEffectInput(i1, effect_use); | 774 R.CheckEffectInput(i1, effect_use); |
| 774 } | 775 } |
| 775 | 776 |
| 776 | 777 |
| 777 TEST(UnaryNot) { | 778 TEST(UnaryNot) { |
| 778 JSTypedLoweringTester R; | 779 JSTypedLoweringTester R; |
| 779 const Operator* opnot = R.javascript.UnaryNot(); | 780 const Operator* opnot = R.javascript.UnaryNot(); |
| 780 | 781 |
| 781 for (size_t i = 0; i < arraysize(kJSTypes); i++) { | 782 for (size_t i = 0; i < arraysize(kJSTypes); i++) { |
| 782 Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i])); | 783 Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i])); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 | 1078 |
| 1078 TEST(OrderCompareEffects) { | 1079 TEST(OrderCompareEffects) { |
| 1079 JSTypedLoweringTester R; | 1080 JSTypedLoweringTester R; |
| 1080 | 1081 |
| 1081 const Operator* ops[] = { | 1082 const Operator* ops[] = { |
| 1082 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), | 1083 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
| 1083 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 1084 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
| 1084 }; | 1085 }; |
| 1085 | 1086 |
| 1086 for (size_t j = 0; j < arraysize(ops); j += 2) { | 1087 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1087 BinopEffectsTester B(ops[j], Type::Object(), Type::String()); | 1088 BinopEffectsTester B(ops[j], Type::Boolean(), Type::String()); |
| 1088 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 1089 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
| 1089 | 1090 |
| 1090 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 1091 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
| 1091 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 1092 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
| 1092 | 1093 |
| 1093 // Inputs should be commuted. | 1094 // Inputs should be commuted. |
| 1094 CHECK_EQ(B.p1, i0->InputAt(0)); | 1095 CHECK_EQ(B.p1, i0->InputAt(0)); |
| 1095 CHECK_EQ(B.p0, i1->InputAt(0)); | 1096 CHECK_EQ(B.p0, i1->InputAt(0)); |
| 1096 | 1097 |
| 1097 // But effects should be ordered start -> i1 -> i0 -> effect_use | 1098 // But effects should be ordered start -> i1 -> i0 -> effect_use |
| 1098 B.CheckEffectOrdering(i1, i0); | 1099 B.CheckEffectOrdering(i1, i0); |
| 1099 } | 1100 } |
| 1100 | 1101 |
| 1101 for (size_t j = 0; j < arraysize(ops); j += 2) { | 1102 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1102 BinopEffectsTester B(ops[j], Type::Number(), Type::Object()); | 1103 BinopEffectsTester B(ops[j], Type::Number(), Type::Boolean()); |
| 1103 | 1104 |
| 1104 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 1105 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
| 1105 Node* i1 = B.result->InputAt(1); | 1106 Node* i1 = B.result->InputAt(1); |
| 1106 | 1107 |
| 1107 CHECK_EQ(B.p1, i0->InputAt(0)); // Should be commuted. | 1108 CHECK_EQ(B.p1, i0->InputAt(0)); // Should be commuted. |
| 1108 CHECK_EQ(B.p0, i1); | 1109 CHECK_EQ(B.p0, i1); |
| 1109 | 1110 |
| 1110 // Effects should be ordered start -> i1 -> effect_use | 1111 // Effects should be ordered start -> i1 -> effect_use |
| 1111 B.CheckEffectOrdering(i0); | 1112 B.CheckEffectOrdering(i0); |
| 1112 } | 1113 } |
| 1113 | 1114 |
| 1114 for (size_t j = 0; j < arraysize(ops); j += 2) { | 1115 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1115 BinopEffectsTester B(ops[j], Type::Object(), Type::Number()); | 1116 BinopEffectsTester B(ops[j], Type::Boolean(), Type::Number()); |
| 1116 | 1117 |
| 1117 Node* i0 = B.result->InputAt(0); | 1118 Node* i0 = B.result->InputAt(0); |
| 1118 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 1119 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
| 1119 | 1120 |
| 1120 CHECK_EQ(B.p1, i0); // Should be commuted. | 1121 CHECK_EQ(B.p1, i0); // Should be commuted. |
| 1121 CHECK_EQ(B.p0, i1->InputAt(0)); | 1122 CHECK_EQ(B.p0, i1->InputAt(0)); |
| 1122 | 1123 |
| 1123 // Effects should be ordered start -> i0 -> effect_use | 1124 // Effects should be ordered start -> i0 -> effect_use |
| 1124 B.CheckEffectOrdering(i1); | 1125 B.CheckEffectOrdering(i1); |
| 1125 } | 1126 } |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1367 CHECK_EQ(p1, r->InputAt(0)); | 1368 CHECK_EQ(p1, r->InputAt(0)); |
| 1368 CHECK_EQ(p0, r->InputAt(1)); | 1369 CHECK_EQ(p0, r->InputAt(1)); |
| 1369 } else { | 1370 } else { |
| 1370 CHECK_EQ(p0, r->InputAt(0)); | 1371 CHECK_EQ(p0, r->InputAt(0)); |
| 1371 CHECK_EQ(p1, r->InputAt(1)); | 1372 CHECK_EQ(p1, r->InputAt(1)); |
| 1372 } | 1373 } |
| 1373 } | 1374 } |
| 1374 } | 1375 } |
| 1375 } | 1376 } |
| 1376 } | 1377 } |
| OLD | NEW |