Chromium Code Reviews| 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/base/flags.h" | 5 #include "src/base/flags.h" |
| 6 #include "src/bootstrapper.h" | 6 #include "src/bootstrapper.h" |
| 7 #include "src/compiler/graph-reducer.h" | 7 #include "src/compiler/graph-reducer.h" |
| 8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
| 9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
| (...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 867 // JS bitwise operators. | 867 // JS bitwise operators. |
| 868 | 868 |
| 869 | 869 |
| 870 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { | 870 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { |
| 871 lhs = NumberToInt32(ToNumber(lhs, t), t); | 871 lhs = NumberToInt32(ToNumber(lhs, t), t); |
| 872 rhs = NumberToInt32(ToNumber(rhs, t), t); | 872 rhs = NumberToInt32(ToNumber(rhs, t), t); |
| 873 double lmin = lhs->Min(); | 873 double lmin = lhs->Min(); |
| 874 double rmin = rhs->Min(); | 874 double rmin = rhs->Min(); |
| 875 double lmax = lhs->Max(); | 875 double lmax = lhs->Max(); |
| 876 double rmax = rhs->Max(); | 876 double rmax = rhs->Max(); |
| 877 | |
|
titzer
2015/03/10 07:47:13
Please add unit tests for the typer and mjsunit te
| |
| 878 // Or-ing with 0 is essentially a conversion to int32, and or-ing | |
| 879 // with -1 returns -1. | |
| 880 if (rmin == rmax) { | |
| 881 if (rmin == 0) { | |
| 882 return Type::Range(lmin, lmax, t->zone()); | |
| 883 } | |
| 884 if (rmin == -1) { | |
| 885 return Type::Range(rmin, rmax, t->zone()); | |
| 886 } | |
| 887 } | |
| 888 if (lmin == lmax) { | |
| 889 if (lmin == 0) { | |
| 890 return Type::Range(rmin, rmax, t->zone()); | |
| 891 } | |
| 892 if (lmin == -1) { | |
| 893 return Type::Range(lmin, lmax, t->zone()); | |
| 894 } | |
| 895 } | |
| 896 | |
| 897 if (lmin >= 0 && rmin >= 0) { | |
| 898 // Precise calculation of the result range for positive ranges. | |
| 899 double min, max; | |
| 900 int32_t lmin2, lmax2, rmin2, rmax2, bit, mask; | |
| 901 | |
| 902 // Calculate the result minimum. | |
| 903 lmin2 = lmin, lmax2 = lmax, rmin2 = rmin, rmax2 = rmax; | |
| 904 bit = 0x40000000, mask = 0x3fffffff; | |
| 905 for (; lmin2 != lmax2 || rmin2 != rmax2; bit >>= 1, mask >>= 1) { | |
| 906 int32_t lminb = lmin2 & bit; | |
| 907 int32_t lmaxb = lmax2 & bit; | |
| 908 int32_t rminb = rmin2 & bit; | |
| 909 int32_t rmaxb = rmax2 & bit; | |
| 910 if (lminb != lmaxb || rminb != rmaxb) { | |
| 911 if (lminb == lmaxb) { | |
| 912 if (lminb) { | |
| 913 rmin2 = (rmin2 & ~mask) | bit; | |
| 914 } else { | |
| 915 rmax2 = (rmax2 & ~bit) | mask; | |
| 916 } | |
| 917 } else if (rminb == rmaxb) { | |
| 918 if (rminb) { | |
| 919 lmin2 = (lmin2 & ~mask) | bit; | |
| 920 } else { | |
| 921 lmax2 = (lmax2 & ~bit) | mask; | |
| 922 } | |
| 923 } else { | |
| 924 lmax2 = (lmax2 & ~bit) | mask; | |
| 925 rmax2 = (rmax2 & ~bit) | mask; | |
| 926 } | |
| 927 } | |
| 928 } | |
| 929 min = lmin2 | rmin2; | |
| 930 | |
| 931 // Calculate the result maximum. | |
| 932 lmin2 = lmin, lmax2 = lmax, rmin2 = rmin, rmax2 = rmax; | |
| 933 bit = 0x40000000, mask = 0x3fffffff; | |
| 934 for (; lmin2 != lmax2 || rmin2 != rmax2; bit >>= 1, mask >>= 1) { | |
| 935 int32_t lminb = lmin2 & bit; | |
| 936 int32_t lmaxb = lmax2 & bit; | |
| 937 int32_t rminb = rmin2 & bit; | |
| 938 int32_t rmaxb = rmax2 & bit; | |
| 939 if (lminb != lmaxb || rminb != rmaxb) { | |
| 940 if (lminb == lmaxb) { | |
| 941 if (lminb) { | |
| 942 rmax2 = (rmax2 & ~bit) | mask; | |
| 943 } else { | |
| 944 rmin2 = (rmin2 & ~mask) | bit; | |
| 945 } | |
| 946 } else if (rminb == rmaxb) { | |
| 947 if (rminb) { | |
| 948 lmax2 = (lmax2 & ~bit) | mask; | |
| 949 } else { | |
| 950 lmin2 = (lmin2 & ~mask) | bit; | |
| 951 } | |
| 952 } else { | |
| 953 lmax2 = lmax2 | mask; | |
| 954 break; | |
| 955 } | |
| 956 } | |
| 957 } | |
| 958 max = lmax2 | rmax2; | |
| 959 | |
| 960 return Type::Range(min, max, t->zone()); | |
| 961 } | |
| 962 | |
| 877 // Or-ing any two values results in a value no smaller than their minimum. | 963 // Or-ing any two values results in a value no smaller than their minimum. |
| 878 // Even no smaller than their maximum if both values are non-negative. | 964 double min = std::min(lmin, rmin); |
| 879 double min = | |
| 880 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); | |
| 881 double max = Type::Signed32()->Max(); | 965 double max = Type::Signed32()->Max(); |
| 882 | 966 |
| 883 // Or-ing with 0 is essentially a conversion to int32. | |
| 884 if (rmin == 0 && rmax == 0) { | |
| 885 min = lmin; | |
| 886 max = lmax; | |
| 887 } | |
| 888 if (lmin == 0 && lmax == 0) { | |
| 889 min = rmin; | |
| 890 max = rmax; | |
| 891 } | |
| 892 | |
| 893 if (lmax < 0 || rmax < 0) { | 967 if (lmax < 0 || rmax < 0) { |
| 894 // Or-ing two values of which at least one is negative results in a negative | 968 // Or-ing two values of which at least one is negative results in a negative |
| 895 // value. | 969 // value. |
| 896 max = std::min(max, -1.0); | 970 max = std::min(max, -1.0); |
| 897 } | 971 } |
| 898 return Type::Range(min, max, t->zone()); | 972 return Type::Range(min, max, t->zone()); |
| 899 // TODO(neis): Be precise for singleton inputs, here and elsewhere. | 973 // TODO(neis): Be precise for singleton inputs, here and elsewhere. |
| 900 } | 974 } |
| 901 | 975 |
| 902 | 976 |
| (...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2211 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2285 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 2212 #undef TYPED_ARRAY_CASE | 2286 #undef TYPED_ARRAY_CASE |
| 2213 } | 2287 } |
| 2214 } | 2288 } |
| 2215 return Type::Constant(value, zone()); | 2289 return Type::Constant(value, zone()); |
| 2216 } | 2290 } |
| 2217 | 2291 |
| 2218 } // namespace compiler | 2292 } // namespace compiler |
| 2219 } // namespace internal | 2293 } // namespace internal |
| 2220 } // namespace v8 | 2294 } // namespace v8 |
| OLD | NEW |