| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 case kTagged: return "t"; | 57 case kTagged: return "t"; |
| 58 case kDouble: return "d"; | 58 case kDouble: return "d"; |
| 59 case kInteger32: return "i"; | 59 case kInteger32: return "i"; |
| 60 default: | 60 default: |
| 61 UNREACHABLE(); | 61 UNREACHABLE(); |
| 62 return NULL; | 62 return NULL; |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 static int32_t AddAssertNoOverflow(int32_t a, int32_t b) { | 67 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { |
| 68 ASSERT(static_cast<int64_t>(a + b) == (static_cast<int64_t>(a) + | 68 if (result > kMaxInt) { |
| 69 static_cast<int64_t>(b))); | 69 *overflow = true; |
| 70 return a + b; | 70 return kMaxInt; |
| 71 } |
| 72 if (result < kMinInt) { |
| 73 *overflow = true; |
| 74 return kMinInt; |
| 75 } |
| 76 return static_cast<int32_t>(result); |
| 71 } | 77 } |
| 72 | 78 |
| 73 | 79 |
| 74 static int32_t SubAssertNoOverflow(int32_t a, int32_t b) { | 80 static int32_t AddWithoutOverflow(int32_t a, int32_t b, bool* overflow) { |
| 75 ASSERT(static_cast<int64_t>(a - b) == (static_cast<int64_t>(a) - | 81 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b); |
| 76 static_cast<int64_t>(b))); | 82 return ConvertAndSetOverflow(result, overflow); |
| 77 return a - b; | |
| 78 } | 83 } |
| 79 | 84 |
| 80 | 85 |
| 81 static int32_t MulAssertNoOverflow(int32_t a, int32_t b) { | 86 static int32_t SubWithoutOverflow(int32_t a, int32_t b, bool* overflow) { |
| 82 ASSERT(static_cast<int64_t>(a * b) == (static_cast<int64_t>(a) * | 87 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b); |
| 83 static_cast<int64_t>(b))); | 88 return ConvertAndSetOverflow(result, overflow); |
| 84 return a * b; | |
| 85 } | |
| 86 | |
| 87 | |
| 88 static int32_t AddWithoutOverflow(int32_t a, int32_t b) { | |
| 89 if (b > 0) { | |
| 90 if (a <= kMaxInt - b) return AddAssertNoOverflow(a, b); | |
| 91 return kMaxInt; | |
| 92 } else { | |
| 93 if (a >= kMinInt - b) return AddAssertNoOverflow(a, b); | |
| 94 return kMinInt; | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 | |
| 99 static int32_t SubWithoutOverflow(int32_t a, int32_t b) { | |
| 100 if (b < 0) { | |
| 101 if (a <= kMaxInt + b) return SubAssertNoOverflow(a, b); | |
| 102 return kMaxInt; | |
| 103 } else { | |
| 104 if (a >= kMinInt + b) return SubAssertNoOverflow(a, b); | |
| 105 return kMinInt; | |
| 106 } | |
| 107 } | 89 } |
| 108 | 90 |
| 109 | 91 |
| 110 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { | 92 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { |
| 111 if (b == 0 || a == 0) return 0; | 93 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); |
| 112 if (a == 1) return b; | 94 return ConvertAndSetOverflow(result, overflow); |
| 113 if (b == 1) return a; | |
| 114 | |
| 115 int sign = 1; | |
| 116 if ((a < 0 && b > 0) || (a > 0 && b < 0)) sign = -1; | |
| 117 if (a < 0) a = -a; | |
| 118 if (b < 0) b = -b; | |
| 119 | |
| 120 if (kMaxInt / b > a && a != kMinInt && b != kMinInt) { | |
| 121 return MulAssertNoOverflow(a, b) * sign; | |
| 122 } | |
| 123 | |
| 124 *overflow = true; | |
| 125 if (sign == 1) { | |
| 126 return kMaxInt; | |
| 127 } else { | |
| 128 return kMinInt; | |
| 129 } | |
| 130 } | 95 } |
| 131 | 96 |
| 132 | 97 |
| 133 int32_t Range::Mask() const { | 98 int32_t Range::Mask() const { |
| 134 if (lower_ == upper_) return lower_; | 99 if (lower_ == upper_) return lower_; |
| 135 if (lower_ >= 0) { | 100 if (lower_ >= 0) { |
| 136 int32_t res = 1; | 101 int32_t res = 1; |
| 137 while (res < upper_) { | 102 while (res < upper_) { |
| 138 res = (res << 1) | 1; | 103 res = (res << 1) | 1; |
| 139 } | 104 } |
| 140 return res; | 105 return res; |
| 141 } | 106 } |
| 142 return 0xffffffff; | 107 return 0xffffffff; |
| 143 } | 108 } |
| 144 | 109 |
| 145 | 110 |
| 146 void Range::Add(int32_t value) { | 111 void Range::AddConstant(int32_t value) { |
| 147 if (value == 0) return; | 112 if (value == 0) return; |
| 148 lower_ = AddWithoutOverflow(lower_, value); | 113 bool may_overflow = false; // Overflow is ignored here. |
| 149 upper_ = AddWithoutOverflow(upper_, value); | 114 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); |
| 115 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); |
| 150 Verify(); | 116 Verify(); |
| 151 } | 117 } |
| 152 | 118 |
| 153 | 119 |
| 154 // Returns whether the add may overflow. | |
| 155 bool Range::AddAndCheckOverflow(Range* other) { | 120 bool Range::AddAndCheckOverflow(Range* other) { |
| 156 int old_lower = lower_; | 121 bool may_overflow = false; |
| 157 int old_upper = upper_; | 122 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); |
| 158 lower_ = AddWithoutOverflow(lower_, other->lower()); | 123 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); |
| 159 upper_ = AddWithoutOverflow(upper_, other->upper()); | |
| 160 bool r = (old_lower + other->lower() != lower_ || | |
| 161 old_upper + other->upper() != upper_); | |
| 162 KeepOrder(); | 124 KeepOrder(); |
| 163 Verify(); | 125 Verify(); |
| 164 return r; | 126 return may_overflow; |
| 165 } | 127 } |
| 166 | 128 |
| 167 | 129 |
| 168 // Returns whether the sub may overflow. | |
| 169 bool Range::SubAndCheckOverflow(Range* other) { | 130 bool Range::SubAndCheckOverflow(Range* other) { |
| 170 int old_lower = lower_; | 131 bool may_overflow = false; |
| 171 int old_upper = upper_; | 132 lower_ = SubWithoutOverflow(lower_, other->upper(), &may_overflow); |
| 172 lower_ = SubWithoutOverflow(lower_, other->lower()); | 133 upper_ = SubWithoutOverflow(upper_, other->lower(), &may_overflow); |
| 173 upper_ = SubWithoutOverflow(upper_, other->upper()); | |
| 174 bool r = (old_lower - other->lower() != lower_ || | |
| 175 old_upper - other->upper() != upper_); | |
| 176 KeepOrder(); | 134 KeepOrder(); |
| 177 Verify(); | 135 Verify(); |
| 178 return r; | 136 return may_overflow; |
| 179 } | 137 } |
| 180 | 138 |
| 181 | 139 |
| 182 void Range::KeepOrder() { | 140 void Range::KeepOrder() { |
| 183 if (lower_ > upper_) { | 141 if (lower_ > upper_) { |
| 184 int32_t tmp = lower_; | 142 int32_t tmp = lower_; |
| 185 lower_ = upper_; | 143 lower_ = upper_; |
| 186 upper_ = tmp; | 144 upper_ = tmp; |
| 187 } | 145 } |
| 188 } | 146 } |
| 189 | 147 |
| 190 | 148 |
| 191 void Range::Verify() const { | 149 void Range::Verify() const { |
| 192 ASSERT(lower_ <= upper_); | 150 ASSERT(lower_ <= upper_); |
| 193 } | 151 } |
| 194 | 152 |
| 195 | 153 |
| 196 // Returns whether the mul may overflow. | |
| 197 bool Range::MulAndCheckOverflow(Range* other) { | 154 bool Range::MulAndCheckOverflow(Range* other) { |
| 198 bool may_overflow = false; | 155 bool may_overflow = false; |
| 199 int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow); | 156 int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow); |
| 200 int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow); | 157 int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow); |
| 201 int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow); | 158 int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow); |
| 202 int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow); | 159 int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow); |
| 203 lower_ = Min(Min(v1, v2), Min(v3, v4)); | 160 lower_ = Min(Min(v1, v2), Min(v3, v4)); |
| 204 upper_ = Max(Max(v1, v2), Max(v3, v4)); | 161 upper_ = Max(Max(v1, v2), Max(v3, v4)); |
| 205 Verify(); | 162 Verify(); |
| 206 return may_overflow; | 163 return may_overflow; |
| (...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 | 1430 |
| 1474 | 1431 |
| 1475 void HCheckPrototypeMaps::Verify() const { | 1432 void HCheckPrototypeMaps::Verify() const { |
| 1476 HInstruction::Verify(); | 1433 HInstruction::Verify(); |
| 1477 ASSERT(HasNoUses()); | 1434 ASSERT(HasNoUses()); |
| 1478 } | 1435 } |
| 1479 | 1436 |
| 1480 #endif | 1437 #endif |
| 1481 | 1438 |
| 1482 } } // namespace v8::internal | 1439 } } // namespace v8::internal |
| OLD | NEW |