| 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 |