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 |