| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) | 52 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) |
| 53 #undef DEFINE_COMPILE | 53 #undef DEFINE_COMPILE |
| 54 | 54 |
| 55 | 55 |
| 56 const char* Representation::Mnemonic() const { | 56 const char* Representation::Mnemonic() const { |
| 57 switch (kind_) { | 57 switch (kind_) { |
| 58 case kNone: return "v"; | 58 case kNone: return "v"; |
| 59 case kTagged: return "t"; | 59 case kTagged: return "t"; |
| 60 case kDouble: return "d"; | 60 case kDouble: return "d"; |
| 61 case kInteger32: return "i"; | 61 case kInteger32: return "i"; |
| 62 case kTruncatedInteger32: return "ti"; |
| 63 case kClampedRoundedUInteger8: return "cri"; |
| 62 case kExternal: return "x"; | 64 case kExternal: return "x"; |
| 63 case kNumRepresentations: | 65 case kNumRepresentations: |
| 64 UNREACHABLE(); | 66 UNREACHABLE(); |
| 65 return NULL; | 67 return NULL; |
| 66 } | 68 } |
| 67 UNREACHABLE(); | 69 UNREACHABLE(); |
| 68 return NULL; | 70 return NULL; |
| 69 } | 71 } |
| 70 | 72 |
| 71 | 73 |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 void HTypeofIs::PrintDataTo(StringStream* stream) { | 722 void HTypeofIs::PrintDataTo(StringStream* stream) { |
| 721 value()->PrintNameTo(stream); | 723 value()->PrintNameTo(stream); |
| 722 stream->Add(" == "); | 724 stream->Add(" == "); |
| 723 stream->Add(type_literal_->ToAsciiVector()); | 725 stream->Add(type_literal_->ToAsciiVector()); |
| 724 } | 726 } |
| 725 | 727 |
| 726 | 728 |
| 727 void HChange::PrintDataTo(StringStream* stream) { | 729 void HChange::PrintDataTo(StringStream* stream) { |
| 728 HUnaryOperation::PrintDataTo(stream); | 730 HUnaryOperation::PrintDataTo(stream); |
| 729 stream->Add(" %s to %s", from_.Mnemonic(), to().Mnemonic()); | 731 stream->Add(" %s to %s", from_.Mnemonic(), to().Mnemonic()); |
| 730 | |
| 731 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); | |
| 732 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 732 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
| 733 } | 733 } |
| 734 | 734 |
| 735 | 735 |
| 736 HCheckInstanceType* HCheckInstanceType::NewIsJSObjectOrJSFunction( | 736 HCheckInstanceType* HCheckInstanceType::NewIsJSObjectOrJSFunction( |
| 737 HValue* value) { | 737 HValue* value) { |
| 738 STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE); | 738 STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE); |
| 739 return new HCheckInstanceType(value, FIRST_JS_OBJECT_TYPE, JS_FUNCTION_TYPE); | 739 return new HCheckInstanceType(value, FIRST_JS_OBJECT_TYPE, JS_FUNCTION_TYPE); |
| 740 } | 740 } |
| 741 | 741 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 if (has_int32_value_) { | 789 if (has_int32_value_) { |
| 790 Range* result = new Range(int32_value_, int32_value_); | 790 Range* result = new Range(int32_value_, int32_value_); |
| 791 result->set_can_be_minus_zero(false); | 791 result->set_can_be_minus_zero(false); |
| 792 return result; | 792 return result; |
| 793 } | 793 } |
| 794 return HValue::InferRange(); | 794 return HValue::InferRange(); |
| 795 } | 795 } |
| 796 | 796 |
| 797 | 797 |
| 798 Range* HPhi::InferRange() { | 798 Range* HPhi::InferRange() { |
| 799 if (representation().IsInteger32()) { | 799 if (representation().IsInteger()) { |
| 800 if (block()->IsLoopHeader()) { | 800 if (block()->IsLoopHeader()) { |
| 801 Range* range = new Range(kMinInt, kMaxInt); | 801 Range* range = representation().IsClampedRoundedInteger8() |
| 802 ? new Range(0, 255) |
| 803 : new Range(kMinInt, kMaxInt); |
| 802 return range; | 804 return range; |
| 803 } else { | 805 } else { |
| 804 Range* range = OperandAt(0)->range()->Copy(); | 806 Range* range = OperandAt(0)->range()->Copy(); |
| 805 for (int i = 1; i < OperandCount(); ++i) { | 807 for (int i = 1; i < OperandCount(); ++i) { |
| 806 range->Union(OperandAt(i)->range()); | 808 range->Union(OperandAt(i)->range()); |
| 807 } | 809 } |
| 808 return range; | 810 return range; |
| 809 } | 811 } |
| 810 } else { | 812 } else { |
| 811 return HValue::InferRange(); | 813 return HValue::InferRange(); |
| 812 } | 814 } |
| 813 } | 815 } |
| 814 | 816 |
| 815 | 817 |
| 816 Range* HAdd::InferRange() { | 818 Range* HAdd::InferRange() { |
| 817 if (representation().IsInteger32()) { | 819 if (representation().IsInteger()) { |
| 818 Range* a = left()->range(); | 820 Range* a = left()->range(); |
| 819 Range* b = right()->range(); | 821 Range* b = right()->range(); |
| 820 Range* res = a->Copy(); | 822 Range* res = a->Copy(); |
| 821 if (!res->AddAndCheckOverflow(b)) { | 823 if (!res->AddAndCheckOverflow(b)) { |
| 822 ClearFlag(kCanOverflow); | 824 ClearFlag(kCanOverflow); |
| 823 } | 825 } |
| 824 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); | 826 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); |
| 825 res->set_can_be_minus_zero(m0); | 827 res->set_can_be_minus_zero(m0); |
| 826 return res; | 828 return res; |
| 827 } else { | 829 } else { |
| 828 return HValue::InferRange(); | 830 return HValue::InferRange(); |
| 829 } | 831 } |
| 830 } | 832 } |
| 831 | 833 |
| 832 | 834 |
| 833 Range* HSub::InferRange() { | 835 Range* HSub::InferRange() { |
| 834 if (representation().IsInteger32()) { | 836 if (representation().IsInteger()) { |
| 835 Range* a = left()->range(); | 837 Range* a = left()->range(); |
| 836 Range* b = right()->range(); | 838 Range* b = right()->range(); |
| 837 Range* res = a->Copy(); | 839 Range* res = a->Copy(); |
| 838 if (!res->SubAndCheckOverflow(b)) { | 840 if (!res->SubAndCheckOverflow(b)) { |
| 839 ClearFlag(kCanOverflow); | 841 ClearFlag(kCanOverflow); |
| 840 } | 842 } |
| 841 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); | 843 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); |
| 842 return res; | 844 return res; |
| 843 } else { | 845 } else { |
| 844 return HValue::InferRange(); | 846 return HValue::InferRange(); |
| 845 } | 847 } |
| 846 } | 848 } |
| 847 | 849 |
| 848 | 850 |
| 849 Range* HMul::InferRange() { | 851 Range* HMul::InferRange() { |
| 850 if (representation().IsInteger32()) { | 852 if (representation().IsInteger()) { |
| 851 Range* a = left()->range(); | 853 Range* a = left()->range(); |
| 852 Range* b = right()->range(); | 854 Range* b = right()->range(); |
| 853 Range* res = a->Copy(); | 855 Range* res = a->Copy(); |
| 854 if (!res->MulAndCheckOverflow(b)) { | 856 if (!res->MulAndCheckOverflow(b)) { |
| 855 ClearFlag(kCanOverflow); | 857 ClearFlag(kCanOverflow); |
| 856 } | 858 } |
| 857 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || | 859 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || |
| 858 (a->CanBeNegative() && b->CanBeZero()); | 860 (a->CanBeNegative() && b->CanBeZero()); |
| 859 res->set_can_be_minus_zero(m0); | 861 res->set_can_be_minus_zero(m0); |
| 860 return res; | 862 return res; |
| 861 } else { | 863 } else { |
| 862 return HValue::InferRange(); | 864 return HValue::InferRange(); |
| 863 } | 865 } |
| 864 } | 866 } |
| 865 | 867 |
| 866 | 868 |
| 867 Range* HDiv::InferRange() { | 869 Range* HDiv::InferRange() { |
| 868 if (representation().IsInteger32()) { | 870 if (representation().IsInteger()) { |
| 869 Range* result = new Range(); | 871 Range* result = new Range(); |
| 870 if (left()->range()->CanBeMinusZero()) { | 872 if (left()->range()->CanBeMinusZero()) { |
| 871 result->set_can_be_minus_zero(true); | 873 result->set_can_be_minus_zero(true); |
| 872 } | 874 } |
| 873 | 875 |
| 874 if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) { | 876 if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) { |
| 875 result->set_can_be_minus_zero(true); | 877 result->set_can_be_minus_zero(true); |
| 876 } | 878 } |
| 877 | 879 |
| 878 if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) { | 880 if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) { |
| 879 SetFlag(HValue::kCanOverflow); | 881 SetFlag(HValue::kCanOverflow); |
| 880 } | 882 } |
| 881 | 883 |
| 882 if (!right()->range()->CanBeZero()) { | 884 if (!right()->range()->CanBeZero()) { |
| 883 ClearFlag(HValue::kCanBeDivByZero); | 885 ClearFlag(HValue::kCanBeDivByZero); |
| 884 } | 886 } |
| 885 return result; | 887 return result; |
| 886 } else { | 888 } else { |
| 887 return HValue::InferRange(); | 889 return HValue::InferRange(); |
| 888 } | 890 } |
| 889 } | 891 } |
| 890 | 892 |
| 891 | 893 |
| 892 Range* HMod::InferRange() { | 894 Range* HMod::InferRange() { |
| 893 if (representation().IsInteger32()) { | 895 if (representation().IsInteger()) { |
| 894 Range* a = left()->range(); | 896 Range* a = left()->range(); |
| 895 Range* result = new Range(); | 897 Range* result = new Range(); |
| 896 if (a->CanBeMinusZero() || a->CanBeNegative()) { | 898 if (a->CanBeMinusZero() || a->CanBeNegative()) { |
| 897 result->set_can_be_minus_zero(true); | 899 result->set_can_be_minus_zero(true); |
| 898 } | 900 } |
| 899 if (!right()->range()->CanBeZero()) { | 901 if (!right()->range()->CanBeZero()) { |
| 900 ClearFlag(HValue::kCanBeDivByZero); | 902 ClearFlag(HValue::kCanBeDivByZero); |
| 901 } | 903 } |
| 902 return result; | 904 return result; |
| 903 } else { | 905 } else { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 double roundtrip_value = static_cast<double>(static_cast<int32_t>(n)); | 1030 double roundtrip_value = static_cast<double>(static_cast<int32_t>(n)); |
| 1029 has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n); | 1031 has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n); |
| 1030 if (has_int32_value_) int32_value_ = static_cast<int32_t>(n); | 1032 if (has_int32_value_) int32_value_ = static_cast<int32_t>(n); |
| 1031 double_value_ = n; | 1033 double_value_ = n; |
| 1032 has_double_value_ = true; | 1034 has_double_value_ = true; |
| 1033 } | 1035 } |
| 1034 } | 1036 } |
| 1035 | 1037 |
| 1036 | 1038 |
| 1037 HConstant* HConstant::CopyToRepresentation(Representation r) const { | 1039 HConstant* HConstant::CopyToRepresentation(Representation r) const { |
| 1038 if (r.IsInteger32() && !has_int32_value_) return NULL; | 1040 if (r.IsInteger() && !has_int32_value_) return NULL; |
| 1041 if (r.IsClampedRoundedInteger8() && |
| 1042 (int32_value_ > 255 || int32_value_ < 0)) return NULL; |
| 1039 if (r.IsDouble() && !has_double_value_) return NULL; | 1043 if (r.IsDouble() && !has_double_value_) return NULL; |
| 1040 return new HConstant(handle_, r); | 1044 return new HConstant(handle_, r); |
| 1041 } | 1045 } |
| 1042 | 1046 |
| 1043 | 1047 |
| 1044 HConstant* HConstant::CopyToTruncatedInt32() const { | 1048 HConstant* HConstant::CopyToTruncatedInt32() const { |
| 1045 if (!has_double_value_) return NULL; | 1049 if (!has_double_value_) return NULL; |
| 1046 int32_t truncated = NumberToInt32(*handle_); | 1050 int32_t truncated = NumberToInt32(*handle_); |
| 1047 return new HConstant(FACTORY->NewNumberFromInt(truncated), | 1051 return new HConstant(FACTORY->NewNumberFromInt(truncated), |
| 1048 Representation::Integer32()); | 1052 Representation::TruncatedInteger32()); |
| 1049 } | 1053 } |
| 1050 | 1054 |
| 1051 | 1055 |
| 1056 HConstant* HConstant::CopyToClampedRoundedUInt8() const { |
| 1057 if (!has_double_value_) return NULL; |
| 1058 int32_t clamped_rounded = NumberToClampedUInt8(*handle_); |
| 1059 return new HConstant(FACTORY->NewNumberFromInt(clamped_rounded), |
| 1060 Representation::ClampedRoundedUInteger8()); |
| 1061 } |
| 1062 |
| 1063 |
| 1052 bool HConstant::ToBoolean() const { | 1064 bool HConstant::ToBoolean() const { |
| 1053 // Converts the constant's boolean value according to | 1065 // Converts the constant's boolean value according to |
| 1054 // ECMAScript section 9.2 ToBoolean conversion. | 1066 // ECMAScript section 9.2 ToBoolean conversion. |
| 1055 if (HasInteger32Value()) return Integer32Value() != 0; | 1067 if (HasInteger32Value()) return Integer32Value() != 0; |
| 1056 if (HasDoubleValue()) { | 1068 if (HasDoubleValue()) { |
| 1057 double v = DoubleValue(); | 1069 double v = DoubleValue(); |
| 1058 return v != 0 && !isnan(v); | 1070 return v != 0 && !isnan(v); |
| 1059 } | 1071 } |
| 1060 if (handle()->IsTrue()) return true; | 1072 if (handle()->IsTrue()) return true; |
| 1061 if (handle()->IsFalse()) return false; | 1073 if (handle()->IsFalse()) return false; |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 | 1516 |
| 1505 | 1517 |
| 1506 HType HSar::CalculateInferredType() { | 1518 HType HSar::CalculateInferredType() { |
| 1507 return HType::TaggedNumber(); | 1519 return HType::TaggedNumber(); |
| 1508 } | 1520 } |
| 1509 | 1521 |
| 1510 | 1522 |
| 1511 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( | 1523 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( |
| 1512 BitVector* visited) { | 1524 BitVector* visited) { |
| 1513 visited->Add(id()); | 1525 visited->Add(id()); |
| 1514 if (representation().IsInteger32() && | 1526 if (representation().IsInteger() && |
| 1515 !value()->representation().IsInteger32()) { | 1527 !value()->representation().IsInteger()) { |
| 1516 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | 1528 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
| 1517 SetFlag(kBailoutOnMinusZero); | 1529 SetFlag(kBailoutOnMinusZero); |
| 1518 } | 1530 } |
| 1519 } | 1531 } |
| 1520 if (RequiredInputRepresentation(0).IsInteger32() && | 1532 if (RequiredInputRepresentation(0).IsInteger() && |
| 1521 representation().IsInteger32()) { | 1533 representation().IsInteger()) { |
| 1522 return value(); | 1534 return value(); |
| 1523 } | 1535 } |
| 1524 return NULL; | 1536 return NULL; |
| 1525 } | 1537 } |
| 1526 | 1538 |
| 1527 | 1539 |
| 1528 | 1540 |
| 1529 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { | 1541 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { |
| 1530 visited->Add(id()); | 1542 visited->Add(id()); |
| 1531 if (from().IsInteger32()) return NULL; | 1543 if (from().IsInteger()) return NULL; |
| 1532 if (CanTruncateToInt32()) return NULL; | 1544 if (to().IsTruncatedInteger32() || to().IsClampedRoundedInteger8()) { |
| 1545 return NULL; |
| 1546 } |
| 1533 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | 1547 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
| 1534 SetFlag(kBailoutOnMinusZero); | 1548 SetFlag(kBailoutOnMinusZero); |
| 1535 } | 1549 } |
| 1536 ASSERT(!from().IsInteger32() || !to().IsInteger32()); | 1550 ASSERT(!from().IsInteger() || !to().IsInteger()); |
| 1537 return NULL; | 1551 return NULL; |
| 1538 } | 1552 } |
| 1539 | 1553 |
| 1540 | 1554 |
| 1541 HValue* HMod::EnsureAndPropagateNotMinusZero(BitVector* visited) { | 1555 HValue* HMod::EnsureAndPropagateNotMinusZero(BitVector* visited) { |
| 1542 visited->Add(id()); | 1556 visited->Add(id()); |
| 1543 if (range() == NULL || range()->CanBeMinusZero()) { | 1557 if (range() == NULL || range()->CanBeMinusZero()) { |
| 1544 SetFlag(kBailoutOnMinusZero); | 1558 SetFlag(kBailoutOnMinusZero); |
| 1545 return left(); | 1559 return left(); |
| 1546 } | 1560 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1646 | 1660 |
| 1647 | 1661 |
| 1648 void HCheckPrototypeMaps::Verify() { | 1662 void HCheckPrototypeMaps::Verify() { |
| 1649 HInstruction::Verify(); | 1663 HInstruction::Verify(); |
| 1650 ASSERT(HasNoUses()); | 1664 ASSERT(HasNoUses()); |
| 1651 } | 1665 } |
| 1652 | 1666 |
| 1653 #endif | 1667 #endif |
| 1654 | 1668 |
| 1655 } } // namespace v8::internal | 1669 } } // namespace v8::internal |
| OLD | NEW |