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/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" |
8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
11 #include "src/compiler/simplified-operator.h" | 11 #include "src/compiler/simplified-operator.h" |
12 #include "src/compiler/typer.h" | 12 #include "src/compiler/typer.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
| 18 enum LazyCachedType { |
| 19 kNumberFunc0, |
| 20 kNumberFunc1, |
| 21 kNumberFunc2, |
| 22 kImulFunc, |
| 23 kClz32Func, |
| 24 kArrayBufferFunc, |
| 25 kInt8ArrayFunc, |
| 26 kInt16ArrayFunc, |
| 27 kInt32ArrayFunc, |
| 28 kUint8ArrayFunc, |
| 29 kUint16ArrayFunc, |
| 30 kUint32ArrayFunc, |
| 31 kFloat32ArrayFunc, |
| 32 kFloat64ArrayFunc, |
| 33 kNumLazyCachedTypes |
| 34 }; |
| 35 |
| 36 |
| 37 // Constructs and caches types lazily. |
| 38 // TODO(turbofan): these types could be globally cached or cached per isolate. |
| 39 struct LazyTypeCache : public ZoneObject { |
| 40 Zone* zone; |
| 41 Type* cache_[kNumLazyCachedTypes]; |
| 42 |
| 43 explicit LazyTypeCache(Zone* z) : zone(z) { |
| 44 memset(cache_, 0, sizeof(cache_)); |
| 45 } |
| 46 |
| 47 inline Type* Get(LazyCachedType type) { |
| 48 int index = static_cast<int>(type); |
| 49 DCHECK(index < kNumLazyCachedTypes); |
| 50 if (cache_[index] == NULL) cache_[index] = Create(type); |
| 51 return cache_[index]; |
| 52 } |
| 53 |
| 54 Type* Create(LazyCachedType type) { |
| 55 Factory* f = zone->isolate()->factory(); |
| 56 Handle<Smi> zero(Smi::FromInt(0), zone->isolate()); |
| 57 |
| 58 #define NATIVE_TYPE(sem, rep) Type::Intersect(Type::sem(), Type::rep(), zone) |
| 59 switch (type) { |
| 60 case kNumberFunc0: { |
| 61 return Type::Function(Type::Number(), zone); |
| 62 } |
| 63 case kNumberFunc1: { |
| 64 return Type::Function(Type::Number(), Type::Number(), zone); |
| 65 } |
| 66 case kNumberFunc2: { |
| 67 return Type::Function(Type::Number(), Type::Number(), Type::Number(), |
| 68 zone); |
| 69 } |
| 70 case kImulFunc: { |
| 71 return Type::Function(Type::Signed32(), Type::Integral32(), |
| 72 Type::Integral32(), zone); |
| 73 } |
| 74 case kClz32Func: { |
| 75 return Type::Function(Type::Range(zero, f->NewNumber(32), zone), |
| 76 Type::Number(), zone); |
| 77 } |
| 78 case kArrayBufferFunc: { |
| 79 return Type::Function(Type::Buffer(zone), Type::Unsigned32(), zone); |
| 80 } |
| 81 case kInt8ArrayFunc: { |
| 82 return GetArrayFunc(Type::Intersect( |
| 83 Type::Range(f->NewNumber(kMinInt8), f->NewNumber(kMaxInt8), zone), |
| 84 Type::UntaggedInt8(), zone)); |
| 85 } |
| 86 case kInt16ArrayFunc: { |
| 87 return GetArrayFunc(Type::Intersect( |
| 88 Type::Range(f->NewNumber(kMinInt16), f->NewNumber(kMaxInt16), zone), |
| 89 Type::UntaggedInt16(), zone)); |
| 90 } |
| 91 case kInt32ArrayFunc: { |
| 92 return GetArrayFunc(NATIVE_TYPE(Signed32, UntaggedInt32)); |
| 93 } |
| 94 case kUint8ArrayFunc: { |
| 95 return GetArrayFunc( |
| 96 Type::Intersect(Type::Range(zero, f->NewNumber(kMaxUInt8), zone), |
| 97 Type::UntaggedInt8(), zone)); |
| 98 } |
| 99 case kUint16ArrayFunc: { |
| 100 return GetArrayFunc( |
| 101 Type::Intersect(Type::Range(zero, f->NewNumber(kMaxUInt16), zone), |
| 102 Type::UntaggedInt16(), zone)); |
| 103 } |
| 104 case kUint32ArrayFunc: { |
| 105 return GetArrayFunc(NATIVE_TYPE(Unsigned32, UntaggedInt32)); |
| 106 } |
| 107 case kFloat32ArrayFunc: { |
| 108 return GetArrayFunc(NATIVE_TYPE(Number, UntaggedFloat32)); |
| 109 } |
| 110 case kFloat64ArrayFunc: { |
| 111 return GetArrayFunc(NATIVE_TYPE(Number, UntaggedFloat64)); |
| 112 } |
| 113 default: |
| 114 break; |
| 115 } |
| 116 #undef NATIVE_TYPE |
| 117 |
| 118 UNREACHABLE(); |
| 119 return NULL; |
| 120 } |
| 121 |
| 122 Type* GetArrayFunc(Type* element) { |
| 123 Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone); |
| 124 Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone); |
| 125 Type* arg3 = arg2; |
| 126 return Type::Function(Type::Array(element, zone), arg1, arg2, arg3, zone); |
| 127 } |
| 128 }; |
| 129 |
18 class Typer::Decorator : public GraphDecorator { | 130 class Typer::Decorator : public GraphDecorator { |
19 public: | 131 public: |
20 explicit Decorator(Typer* typer) : typer_(typer) {} | 132 explicit Decorator(Typer* typer) : typer_(typer) {} |
21 virtual void Decorate(Node* node); | 133 virtual void Decorate(Node* node); |
22 | 134 |
23 private: | 135 private: |
24 Typer* typer_; | 136 Typer* typer_; |
25 }; | 137 }; |
26 | 138 |
27 | 139 |
28 Typer::Typer(Graph* graph, MaybeHandle<Context> context) | 140 Typer::Typer(Graph* graph, MaybeHandle<Context> context) |
29 : graph_(graph), | 141 : graph_(graph), |
30 context_(context), | 142 context_(context), |
31 decorator_(NULL), | 143 decorator_(NULL), |
| 144 cache_(new (graph->zone()) LazyTypeCache(graph->zone())), |
32 weaken_min_limits_(graph->zone()), | 145 weaken_min_limits_(graph->zone()), |
33 weaken_max_limits_(graph->zone()) { | 146 weaken_max_limits_(graph->zone()) { |
34 Zone* zone = this->zone(); | 147 Zone* zone = this->zone(); |
35 Factory* f = zone->isolate()->factory(); | 148 Factory* f = zone->isolate()->factory(); |
36 | 149 |
37 Handle<Object> zero = f->NewNumber(0); | 150 Handle<Object> zero = f->NewNumber(0); |
38 Handle<Object> one = f->NewNumber(1); | 151 Handle<Object> one = f->NewNumber(1); |
39 Handle<Object> infinity = f->NewNumber(+V8_INFINITY); | 152 Handle<Object> infinity = f->NewNumber(+V8_INFINITY); |
40 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY); | 153 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY); |
41 | 154 |
42 Type* number = Type::Number(); | 155 Type* number = Type::Number(); |
43 Type* signed32 = Type::Signed32(); | 156 Type* signed32 = Type::Signed32(); |
44 Type* unsigned32 = Type::Unsigned32(); | 157 Type* unsigned32 = Type::Unsigned32(); |
45 Type* integral32 = Type::Integral32(); | |
46 Type* object = Type::Object(); | |
47 Type* undefined = Type::Undefined(); | |
48 Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone); | 158 Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone); |
49 Type* truncating_to_zero = | 159 Type* truncating_to_zero = |
50 Type::Union(Type::Union(Type::Constant(infinity, zone), | 160 Type::Union(Type::Union(Type::Constant(infinity, zone), |
51 Type::Constant(minusinfinity, zone), zone), | 161 Type::Constant(minusinfinity, zone), zone), |
52 nan_or_minuszero, zone); | 162 nan_or_minuszero, zone); |
53 | 163 |
54 negative_signed32 = Type::Union( | 164 negative_signed32 = Type::Union( |
55 Type::SignedSmall(), Type::OtherSigned32(), zone); | 165 Type::SignedSmall(), Type::OtherSigned32(), zone); |
56 non_negative_signed32 = Type::Union( | 166 non_negative_signed32 = Type::Union( |
57 Type::UnsignedSmall(), Type::OtherUnsigned31(), zone); | 167 Type::UnsignedSmall(), Type::OtherUnsigned31(), zone); |
(...skipping 13 matching lines...) Expand all Loading... |
71 | 181 |
72 signed8_ = Type::Range(f->NewNumber(kMinInt8), f->NewNumber(kMaxInt8), zone); | 182 signed8_ = Type::Range(f->NewNumber(kMinInt8), f->NewNumber(kMaxInt8), zone); |
73 unsigned8_ = Type::Range(zero, f->NewNumber(kMaxUInt8), zone); | 183 unsigned8_ = Type::Range(zero, f->NewNumber(kMaxUInt8), zone); |
74 signed16_ = | 184 signed16_ = |
75 Type::Range(f->NewNumber(kMinInt16), f->NewNumber(kMaxInt16), zone); | 185 Type::Range(f->NewNumber(kMinInt16), f->NewNumber(kMaxInt16), zone); |
76 unsigned16_ = Type::Range(zero, f->NewNumber(kMaxUInt16), zone); | 186 unsigned16_ = Type::Range(zero, f->NewNumber(kMaxUInt16), zone); |
77 | 187 |
78 number_fun0_ = Type::Function(number, zone); | 188 number_fun0_ = Type::Function(number, zone); |
79 number_fun1_ = Type::Function(number, number, zone); | 189 number_fun1_ = Type::Function(number, number, zone); |
80 number_fun2_ = Type::Function(number, number, number, zone); | 190 number_fun2_ = Type::Function(number, number, number, zone); |
| 191 |
81 weakint_fun1_ = Type::Function(weakint, number, zone); | 192 weakint_fun1_ = Type::Function(weakint, number, zone); |
82 imul_fun_ = Type::Function(signed32, integral32, integral32, zone); | |
83 clz32_fun_ = Type::Function( | |
84 Type::Range(zero, f->NewNumber(32), zone), number, zone); | |
85 random_fun_ = Type::Function(Type::Union( | 193 random_fun_ = Type::Function(Type::Union( |
86 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); | 194 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); |
87 | 195 |
88 #define NATIVE_TYPE(sem, rep) Type::Intersect(sem, rep, zone) | |
89 Type* int8 = NATIVE_TYPE(signed8_, Type::UntaggedInt8()); | |
90 Type* uint8 = NATIVE_TYPE(unsigned8_, Type::UntaggedInt8()); | |
91 Type* int16 = NATIVE_TYPE(signed16_, Type::UntaggedInt16()); | |
92 Type* uint16 = NATIVE_TYPE(unsigned16_, Type::UntaggedInt16()); | |
93 Type* int32 = NATIVE_TYPE(Type::Signed32(), Type::UntaggedInt32()); | |
94 Type* uint32 = NATIVE_TYPE(Type::Unsigned32(), Type::UntaggedInt32()); | |
95 Type* float32 = NATIVE_TYPE(Type::Number(), Type::UntaggedFloat32()); | |
96 Type* float64 = NATIVE_TYPE(Type::Number(), Type::UntaggedFloat64()); | |
97 #undef NATIVE_TYPE | |
98 | |
99 Type* buffer = Type::Buffer(zone); | |
100 Type* int8_array = Type::Array(int8, zone); | |
101 Type* int16_array = Type::Array(int16, zone); | |
102 Type* int32_array = Type::Array(int32, zone); | |
103 Type* uint8_array = Type::Array(uint8, zone); | |
104 Type* uint16_array = Type::Array(uint16, zone); | |
105 Type* uint32_array = Type::Array(uint32, zone); | |
106 Type* float32_array = Type::Array(float32, zone); | |
107 Type* float64_array = Type::Array(float64, zone); | |
108 Type* arg1 = Type::Union(unsigned32, object, zone); | |
109 Type* arg2 = Type::Union(unsigned32, undefined, zone); | |
110 Type* arg3 = arg2; | |
111 array_buffer_fun_ = Type::Function(buffer, unsigned32, zone); | |
112 int8_array_fun_ = Type::Function(int8_array, arg1, arg2, arg3, zone); | |
113 int16_array_fun_ = Type::Function(int16_array, arg1, arg2, arg3, zone); | |
114 int32_array_fun_ = Type::Function(int32_array, arg1, arg2, arg3, zone); | |
115 uint8_array_fun_ = Type::Function(uint8_array, arg1, arg2, arg3, zone); | |
116 uint16_array_fun_ = Type::Function(uint16_array, arg1, arg2, arg3, zone); | |
117 uint32_array_fun_ = Type::Function(uint32_array, arg1, arg2, arg3, zone); | |
118 float32_array_fun_ = Type::Function(float32_array, arg1, arg2, arg3, zone); | |
119 float64_array_fun_ = Type::Function(float64_array, arg1, arg2, arg3, zone); | |
120 | |
121 const int limits_count = 20; | 196 const int limits_count = 20; |
122 | 197 |
123 weaken_min_limits_.reserve(limits_count + 1); | 198 weaken_min_limits_.reserve(limits_count + 1); |
124 weaken_max_limits_.reserve(limits_count + 1); | 199 weaken_max_limits_.reserve(limits_count + 1); |
125 | 200 |
126 double limit = 1 << 30; | 201 double limit = 1 << 30; |
127 weaken_min_limits_.push_back(f->NewNumber(0)); | 202 weaken_min_limits_.push_back(f->NewNumber(0)); |
128 weaken_max_limits_.push_back(f->NewNumber(0)); | 203 weaken_max_limits_.push_back(f->NewNumber(0)); |
129 for (int i = 0; i < limits_count; i++) { | 204 for (int i = 0; i < limits_count; i++) { |
130 weaken_min_limits_.push_back(f->NewNumber(-limit)); | 205 weaken_min_limits_.push_back(f->NewNumber(-limit)); |
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1943 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { | 2018 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { |
1944 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { | 2019 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { |
1945 case kMathRandom: | 2020 case kMathRandom: |
1946 return typer_->random_fun_; | 2021 return typer_->random_fun_; |
1947 case kMathFloor: | 2022 case kMathFloor: |
1948 return typer_->weakint_fun1_; | 2023 return typer_->weakint_fun1_; |
1949 case kMathRound: | 2024 case kMathRound: |
1950 return typer_->weakint_fun1_; | 2025 return typer_->weakint_fun1_; |
1951 case kMathCeil: | 2026 case kMathCeil: |
1952 return typer_->weakint_fun1_; | 2027 return typer_->weakint_fun1_; |
1953 case kMathAbs: | 2028 // Unary math functions. |
1954 // TODO(rossberg): can't express overloading | 2029 case kMathAbs: // TODO(rossberg): can't express overloading |
1955 return typer_->number_fun1_; | |
1956 case kMathLog: | 2030 case kMathLog: |
1957 return typer_->number_fun1_; | |
1958 case kMathExp: | 2031 case kMathExp: |
1959 return typer_->number_fun1_; | |
1960 case kMathSqrt: | 2032 case kMathSqrt: |
1961 return typer_->number_fun1_; | 2033 case kMathCos: |
| 2034 case kMathSin: |
| 2035 case kMathTan: |
| 2036 case kMathAcos: |
| 2037 case kMathAsin: |
| 2038 case kMathAtan: |
| 2039 case kMathFround: |
| 2040 return typer_->cache_->Get(kNumberFunc1); |
| 2041 // Binary math functions. |
| 2042 case kMathAtan2: |
1962 case kMathPow: | 2043 case kMathPow: |
1963 return typer_->number_fun2_; | |
1964 case kMathMax: | 2044 case kMathMax: |
1965 return typer_->number_fun2_; | |
1966 case kMathMin: | 2045 case kMathMin: |
1967 return typer_->number_fun2_; | 2046 return typer_->cache_->Get(kNumberFunc2); |
1968 case kMathCos: | |
1969 return typer_->number_fun1_; | |
1970 case kMathSin: | |
1971 return typer_->number_fun1_; | |
1972 case kMathTan: | |
1973 return typer_->number_fun1_; | |
1974 case kMathAcos: | |
1975 return typer_->number_fun1_; | |
1976 case kMathAsin: | |
1977 return typer_->number_fun1_; | |
1978 case kMathAtan: | |
1979 return typer_->number_fun1_; | |
1980 case kMathAtan2: | |
1981 return typer_->number_fun2_; | |
1982 case kMathImul: | 2047 case kMathImul: |
1983 return typer_->imul_fun_; | 2048 return typer_->cache_->Get(kImulFunc); |
1984 case kMathClz32: | 2049 case kMathClz32: |
1985 return typer_->clz32_fun_; | 2050 return typer_->cache_->Get(kClz32Func); |
1986 case kMathFround: | |
1987 return typer_->number_fun1_; | |
1988 default: | 2051 default: |
1989 break; | 2052 break; |
1990 } | 2053 } |
1991 } else if (JSFunction::cast(*value)->IsBuiltin() && !context().is_null()) { | 2054 } else if (JSFunction::cast(*value)->IsBuiltin() && !context().is_null()) { |
1992 Handle<Context> native = | 2055 Handle<Context> native = |
1993 handle(context().ToHandleChecked()->native_context(), isolate()); | 2056 handle(context().ToHandleChecked()->native_context(), isolate()); |
1994 if (*value == native->array_buffer_fun()) { | 2057 if (*value == native->array_buffer_fun()) { |
1995 return typer_->array_buffer_fun_; | 2058 return typer_->cache_->Get(kArrayBufferFunc); |
1996 } else if (*value == native->int8_array_fun()) { | 2059 } else if (*value == native->int8_array_fun()) { |
1997 return typer_->int8_array_fun_; | 2060 return typer_->cache_->Get(kInt8ArrayFunc); |
1998 } else if (*value == native->int16_array_fun()) { | 2061 } else if (*value == native->int16_array_fun()) { |
1999 return typer_->int16_array_fun_; | 2062 return typer_->cache_->Get(kInt16ArrayFunc); |
2000 } else if (*value == native->int32_array_fun()) { | 2063 } else if (*value == native->int32_array_fun()) { |
2001 return typer_->int32_array_fun_; | 2064 return typer_->cache_->Get(kInt32ArrayFunc); |
2002 } else if (*value == native->uint8_array_fun()) { | 2065 } else if (*value == native->uint8_array_fun()) { |
2003 return typer_->uint8_array_fun_; | 2066 return typer_->cache_->Get(kUint8ArrayFunc); |
2004 } else if (*value == native->uint16_array_fun()) { | 2067 } else if (*value == native->uint16_array_fun()) { |
2005 return typer_->uint16_array_fun_; | 2068 return typer_->cache_->Get(kUint16ArrayFunc); |
2006 } else if (*value == native->uint32_array_fun()) { | 2069 } else if (*value == native->uint32_array_fun()) { |
2007 return typer_->uint32_array_fun_; | 2070 return typer_->cache_->Get(kUint32ArrayFunc); |
2008 } else if (*value == native->float32_array_fun()) { | 2071 } else if (*value == native->float32_array_fun()) { |
2009 return typer_->float32_array_fun_; | 2072 return typer_->cache_->Get(kFloat32ArrayFunc); |
2010 } else if (*value == native->float64_array_fun()) { | 2073 } else if (*value == native->float64_array_fun()) { |
2011 return typer_->float64_array_fun_; | 2074 return typer_->cache_->Get(kFloat64ArrayFunc); |
2012 } | 2075 } |
2013 } | 2076 } |
2014 } | 2077 } |
2015 return Type::Constant(value, zone()); | 2078 return Type::Constant(value, zone()); |
2016 } | 2079 } |
2017 | 2080 |
2018 } // namespace compiler | 2081 } // namespace compiler |
2019 } // namespace internal | 2082 } // namespace internal |
2020 } // namespace v8 | 2083 } // namespace v8 |
OLD | NEW |