OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 | 6 |
7 #include "src/double.h" | 7 #include "src/double.h" |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
9 #include "src/hydrogen-infer-representation.h" | 9 #include "src/hydrogen-infer-representation.h" |
10 #include "src/property-details-inl.h" | 10 #include "src/property-details-inl.h" |
(...skipping 1904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1915 if (!b->CanBeZero()) { | 1915 if (!b->CanBeZero()) { |
1916 ClearFlag(kCanBeDivByZero); | 1916 ClearFlag(kCanBeDivByZero); |
1917 } | 1917 } |
1918 return result; | 1918 return result; |
1919 } else { | 1919 } else { |
1920 return HValue::InferRange(zone); | 1920 return HValue::InferRange(zone); |
1921 } | 1921 } |
1922 } | 1922 } |
1923 | 1923 |
1924 | 1924 |
| 1925 // Returns the absolute value of its argument minus one, avoiding undefined |
| 1926 // behavior at kMinInt. |
| 1927 static int32_t AbsMinus1(int32_t a) { return a < 0 ? -(a + 1) : (a - 1); } |
| 1928 |
| 1929 |
1925 Range* HMod::InferRange(Zone* zone) { | 1930 Range* HMod::InferRange(Zone* zone) { |
1926 if (representation().IsInteger32()) { | 1931 if (representation().IsInteger32()) { |
1927 Range* a = left()->range(); | 1932 Range* a = left()->range(); |
1928 Range* b = right()->range(); | 1933 Range* b = right()->range(); |
1929 | 1934 |
1930 // The magnitude of the modulus is bounded by the right operand. Note that | 1935 // The magnitude of the modulus is bounded by the right operand. |
1931 // apart for the cases involving kMinInt, the calculation below is the same | 1936 int32_t positive_bound = Max(AbsMinus1(b->lower()), AbsMinus1(b->upper())); |
1932 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. | |
1933 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); | |
1934 | 1937 |
1935 // The result of the modulo operation has the sign of its left operand. | 1938 // The result of the modulo operation has the sign of its left operand. |
1936 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); | 1939 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); |
1937 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, | 1940 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, |
1938 a->CanBePositive() ? positive_bound : 0); | 1941 a->CanBePositive() ? positive_bound : 0); |
1939 | 1942 |
1940 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && | 1943 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
1941 left_can_be_negative); | 1944 left_can_be_negative); |
1942 | 1945 |
1943 if (!a->CanBeNegative()) { | 1946 if (!a->CanBeNegative()) { |
(...skipping 2825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4769 break; | 4772 break; |
4770 case HObjectAccess::kExternalMemory: | 4773 case HObjectAccess::kExternalMemory: |
4771 os << "[external-memory]"; | 4774 os << "[external-memory]"; |
4772 break; | 4775 break; |
4773 } | 4776 } |
4774 | 4777 |
4775 return os << "@" << access.offset(); | 4778 return os << "@" << access.offset(); |
4776 } | 4779 } |
4777 | 4780 |
4778 } } // namespace v8::internal | 4781 } } // namespace v8::internal |
OLD | NEW |