[turbofan] Make TyperCache global and thread safe.
This way we need the common types only once per process and we don't need to recreate them for every compilation. It uses the same pattern that we already apply to caching operators. This simplifies the type cache a lot. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/1209513002 Cr-Commit-Position: refs/heads/master@{#29251}
This commit is contained in:
parent
7a675e0e3b
commit
db4101ef81
@ -2,177 +2,120 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/compiler/typer.h"
|
||||
|
||||
#include "src/base/flags.h"
|
||||
#include "src/base/lazy-instance.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/compiler/graph-reducer.h"
|
||||
#include "src/compiler/js-operator.h"
|
||||
#include "src/compiler/node.h"
|
||||
#include "src/compiler/node-properties.h"
|
||||
#include "src/compiler/simplified-operator.h"
|
||||
#include "src/compiler/typer.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
#define NATIVE_TYPES(V) \
|
||||
V(Int8) \
|
||||
V(Uint8) \
|
||||
V(Int16) \
|
||||
V(Uint16) \
|
||||
V(Int32) \
|
||||
V(Uint32) \
|
||||
V(Float32) \
|
||||
V(Float64)
|
||||
class TyperCache final {
|
||||
private:
|
||||
// This has to be first for the initialization magic to work.
|
||||
Zone zone_;
|
||||
|
||||
enum LazyCachedType {
|
||||
kInteger,
|
||||
kWeakint,
|
||||
kWeakintFunc1,
|
||||
kRandomFunc0,
|
||||
kAnyFunc0,
|
||||
kAnyFunc1,
|
||||
kAnyFunc2,
|
||||
kAnyFunc3,
|
||||
kNumberFunc0,
|
||||
kNumberFunc1,
|
||||
kNumberFunc2,
|
||||
kImulFunc,
|
||||
kClz32Func,
|
||||
kArrayBufferFunc,
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
|
||||
k##Type, k##Type##Array, k##Type##ArrayFunc,
|
||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
||||
#undef TYPED_ARRAY_CASE
|
||||
kNumLazyCachedTypes
|
||||
};
|
||||
|
||||
|
||||
// Constructs and caches types lazily.
|
||||
// TODO(turbofan): these types could be globally cached or cached per isolate.
|
||||
class LazyTypeCache final : public ZoneObject {
|
||||
public:
|
||||
explicit LazyTypeCache(Isolate* isolate, Zone* zone)
|
||||
: isolate_(isolate), zone_(zone) {
|
||||
memset(cache_, 0, sizeof(cache_));
|
||||
}
|
||||
TyperCache() = default;
|
||||
|
||||
V8_INLINE Type* Get(LazyCachedType type) {
|
||||
int const index = static_cast<int>(type);
|
||||
DCHECK_LT(index, kNumLazyCachedTypes);
|
||||
if (cache_[index] == NULL) cache_[index] = Create(type);
|
||||
return cache_[index];
|
||||
}
|
||||
Type* const kInt8 =
|
||||
CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8());
|
||||
Type* const kUint8 =
|
||||
CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8());
|
||||
Type* const kUint8Clamped = kUint8;
|
||||
Type* const kInt16 =
|
||||
CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16());
|
||||
Type* const kUint16 =
|
||||
CreateNative(CreateRange<uint16_t>(), Type::UntaggedUnsigned16());
|
||||
Type* const kInt32 = CreateNative(Type::Signed32(), Type::UntaggedSigned32());
|
||||
Type* const kUint32 =
|
||||
CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32());
|
||||
Type* const kFloat32 = CreateNative(Type::Number(), Type::UntaggedFloat32());
|
||||
Type* const kFloat64 = CreateNative(Type::Number(), Type::UntaggedFloat64());
|
||||
|
||||
Type* const kSingletonZero = CreateRange(0.0, 0.0);
|
||||
Type* const kSingletonOne = CreateRange(1.0, 1.0);
|
||||
Type* const kZeroOrOne = CreateRange(0.0, 1.0);
|
||||
Type* const kZeroish =
|
||||
Type::Union(kSingletonZero, Type::MinusZeroOrNaN(), zone());
|
||||
Type* const kInteger = CreateRange(-V8_INFINITY, V8_INFINITY);
|
||||
Type* const kWeakint = Type::Union(kInteger, Type::MinusZeroOrNaN(), zone());
|
||||
Type* const kWeakintFunc1 = Type::Function(kWeakint, Type::Number(), zone());
|
||||
|
||||
Type* const kRandomFunc0 = Type::Function(Type::OrderedNumber(), zone());
|
||||
Type* const kAnyFunc0 = Type::Function(Type::Any(), zone());
|
||||
Type* const kAnyFunc1 = Type::Function(Type::Any(), Type::Any(), zone());
|
||||
Type* const kAnyFunc2 =
|
||||
Type::Function(Type::Any(), Type::Any(), Type::Any(), zone());
|
||||
Type* const kAnyFunc3 = Type::Function(Type::Any(), Type::Any(), Type::Any(),
|
||||
Type::Any(), zone());
|
||||
Type* const kNumberFunc0 = Type::Function(Type::Number(), zone());
|
||||
Type* const kNumberFunc1 =
|
||||
Type::Function(Type::Number(), Type::Number(), zone());
|
||||
Type* const kNumberFunc2 =
|
||||
Type::Function(Type::Number(), Type::Number(), Type::Number(), zone());
|
||||
Type* const kImulFunc = Type::Function(Type::Signed32(), Type::Integral32(),
|
||||
Type::Integral32(), zone());
|
||||
Type* const kClz32Func =
|
||||
Type::Function(CreateRange(0, 32), Type::Number(), zone());
|
||||
Type* const kArrayBufferFunc =
|
||||
Type::Function(Type::Object(zone()), Type::Unsigned32(), zone());
|
||||
|
||||
#define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
|
||||
Type* const k##TypeName##Array = CreateArray(k##TypeName); \
|
||||
Type* const k##TypeName##ArrayFunc = CreateArrayFunction(k##TypeName##Array);
|
||||
TYPED_ARRAYS(TYPED_ARRAY)
|
||||
#undef TYPED_ARRAY
|
||||
|
||||
private:
|
||||
Type* Create(LazyCachedType type) {
|
||||
switch (type) {
|
||||
case kInt8:
|
||||
return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8());
|
||||
case kUint8:
|
||||
return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8());
|
||||
case kInt16:
|
||||
return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16());
|
||||
case kUint16:
|
||||
return CreateNative(CreateRange<uint16_t>(),
|
||||
Type::UntaggedUnsigned16());
|
||||
case kInt32:
|
||||
return CreateNative(Type::Signed32(), Type::UntaggedSigned32());
|
||||
case kUint32:
|
||||
return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32());
|
||||
case kFloat32:
|
||||
return CreateNative(Type::Number(), Type::UntaggedFloat32());
|
||||
case kFloat64:
|
||||
return CreateNative(Type::Number(), Type::UntaggedFloat64());
|
||||
case kUint8Clamped:
|
||||
return Get(kUint8);
|
||||
case kInteger:
|
||||
return CreateRange(-V8_INFINITY, V8_INFINITY);
|
||||
case kWeakint:
|
||||
return Type::Union(Get(kInteger), Type::MinusZeroOrNaN(), zone());
|
||||
case kWeakintFunc1:
|
||||
return Type::Function(Get(kWeakint), Type::Number(), zone());
|
||||
case kRandomFunc0:
|
||||
return Type::Function(Type::OrderedNumber(), zone());
|
||||
case kAnyFunc0:
|
||||
return Type::Function(Type::Any(), zone());
|
||||
case kAnyFunc1:
|
||||
return Type::Function(Type::Any(), Type::Any(), zone());
|
||||
case kAnyFunc2:
|
||||
return Type::Function(Type::Any(), Type::Any(), Type::Any(), zone());
|
||||
case kAnyFunc3:
|
||||
return Type::Function(Type::Any(), Type::Any(), Type::Any(),
|
||||
Type::Any(), zone());
|
||||
case kNumberFunc0:
|
||||
return Type::Function(Type::Number(), zone());
|
||||
case kNumberFunc1:
|
||||
return Type::Function(Type::Number(), Type::Number(), zone());
|
||||
case kNumberFunc2:
|
||||
return Type::Function(Type::Number(), Type::Number(), Type::Number(),
|
||||
zone());
|
||||
case kImulFunc:
|
||||
return Type::Function(Type::Signed32(), Type::Integral32(),
|
||||
Type::Integral32(), zone());
|
||||
case kClz32Func:
|
||||
return Type::Function(CreateRange(0, 32), Type::Number(), zone());
|
||||
case kArrayBufferFunc:
|
||||
return Type::Function(Type::Object(zone()), Type::Unsigned32(), zone());
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
|
||||
case k##Type##Array: \
|
||||
return CreateArray(Get(k##Type)); \
|
||||
case k##Type##ArrayFunc: \
|
||||
return CreateArrayFunction(Get(k##Type##Array));
|
||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
||||
#undef TYPED_ARRAY_CASE
|
||||
case kNumLazyCachedTypes:
|
||||
break;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
Type* CreateArray(Type* element) { return Type::Array(element, zone()); }
|
||||
|
||||
Type* CreateArray(Type* element) const {
|
||||
return Type::Array(element, zone());
|
||||
}
|
||||
|
||||
Type* CreateArrayFunction(Type* array) const {
|
||||
Type* CreateArrayFunction(Type* array) {
|
||||
Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone());
|
||||
Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone());
|
||||
Type* arg3 = arg2;
|
||||
return Type::Function(array, arg1, arg2, arg3, zone());
|
||||
}
|
||||
|
||||
Type* CreateNative(Type* semantic, Type* representation) const {
|
||||
Type* CreateNative(Type* semantic, Type* representation) {
|
||||
return Type::Intersect(semantic, representation, zone());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Type* CreateRange() const {
|
||||
Type* CreateRange() {
|
||||
return CreateRange(std::numeric_limits<T>::min(),
|
||||
std::numeric_limits<T>::max());
|
||||
}
|
||||
|
||||
Type* CreateRange(double min, double max) const {
|
||||
Type* CreateRange(double min, double max) {
|
||||
return Type::Range(min, max, zone());
|
||||
}
|
||||
|
||||
Factory* factory() const { return isolate()->factory(); }
|
||||
Isolate* isolate() const { return isolate_; }
|
||||
Zone* zone() const { return zone_; }
|
||||
|
||||
Type* cache_[kNumLazyCachedTypes];
|
||||
Isolate* isolate_;
|
||||
Zone* zone_;
|
||||
Zone* zone() { return &zone_; }
|
||||
};
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
base::LazyInstance<TyperCache>::type kCache = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
class Typer::Decorator final : public GraphDecorator {
|
||||
public:
|
||||
explicit Decorator(Typer* typer) : typer_(typer) {}
|
||||
void Decorate(Node* node) final;
|
||||
|
||||
private:
|
||||
Typer* typer_;
|
||||
Typer* const typer_;
|
||||
};
|
||||
|
||||
|
||||
@ -182,8 +125,8 @@ Typer::Typer(Isolate* isolate, Graph* graph, Type::FunctionType* function_type,
|
||||
graph_(graph),
|
||||
function_type_(function_type),
|
||||
context_(context),
|
||||
decorator_(NULL),
|
||||
cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())) {
|
||||
decorator_(nullptr),
|
||||
cache_(kCache.Get()) {
|
||||
Zone* zone = this->zone();
|
||||
Factory* const factory = isolate->factory();
|
||||
|
||||
@ -195,17 +138,13 @@ Typer::Typer(Isolate* isolate, Graph* graph, Type::FunctionType* function_type,
|
||||
|
||||
singleton_false_ = Type::Constant(factory->false_value(), zone);
|
||||
singleton_true_ = Type::Constant(factory->true_value(), zone);
|
||||
singleton_zero_ = Type::Range(0.0, 0.0, zone);
|
||||
singleton_one_ = Type::Range(1.0, 1.0, zone);
|
||||
zero_or_one_ = Type::Range(0.0, 1.0, zone);
|
||||
zeroish_ = Type::Union(singleton_zero_, Type::MinusZeroOrNaN(), zone);
|
||||
signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
|
||||
unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
|
||||
falsish_ =
|
||||
Type::Union(Type::Undetectable(),
|
||||
Type::Union(Type::Union(singleton_false_, zeroish_, zone),
|
||||
Type::NullOrUndefined(), zone),
|
||||
zone);
|
||||
falsish_ = Type::Union(
|
||||
Type::Undetectable(),
|
||||
Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
|
||||
Type::NullOrUndefined(), zone),
|
||||
zone);
|
||||
truish_ = Type::Union(
|
||||
singleton_true_,
|
||||
Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
|
||||
@ -527,7 +466,7 @@ Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
|
||||
|
||||
Type* Typer::Visitor::Rangify(Type* type, Typer* t) {
|
||||
if (type->IsRange()) return type; // Shortcut.
|
||||
if (!type->Is(t->cache_->Get(kInteger))) {
|
||||
if (!type->Is(t->cache_.kInteger)) {
|
||||
return type; // Give up on non-integer types.
|
||||
}
|
||||
double min = type->Min();
|
||||
@ -567,20 +506,20 @@ Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
|
||||
Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
|
||||
if (type->Is(Type::Number())) return type;
|
||||
if (type->Is(Type::NullOrUndefined())) {
|
||||
if (type->Is(Type::Null())) return t->singleton_zero_;
|
||||
if (type->Is(Type::Null())) return t->cache_.kSingletonZero;
|
||||
if (type->Is(Type::Undefined())) return Type::NaN();
|
||||
return Type::Union(Type::NaN(), t->singleton_zero_, t->zone());
|
||||
return Type::Union(Type::NaN(), t->cache_.kSingletonZero, t->zone());
|
||||
}
|
||||
if (type->Is(Type::NumberOrUndefined())) {
|
||||
return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
|
||||
Type::NaN(), t->zone());
|
||||
}
|
||||
if (type->Is(t->singleton_false_)) return t->singleton_zero_;
|
||||
if (type->Is(t->singleton_true_)) return t->singleton_one_;
|
||||
if (type->Is(Type::Boolean())) return t->zero_or_one_;
|
||||
if (type->Is(t->singleton_false_)) return t->cache_.kSingletonZero;
|
||||
if (type->Is(t->singleton_true_)) return t->cache_.kSingletonOne;
|
||||
if (type->Is(Type::Boolean())) return t->cache_.kZeroOrOne;
|
||||
if (type->Is(Type::BooleanOrNumber())) {
|
||||
return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
|
||||
t->zero_or_one_, t->zone());
|
||||
t->cache_.kZeroOrOne, t->zone());
|
||||
}
|
||||
return Type::Number();
|
||||
}
|
||||
@ -595,10 +534,11 @@ Type* Typer::Visitor::ToString(Type* type, Typer* t) {
|
||||
Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
|
||||
// TODO(neis): DCHECK(type->Is(Type::Number()));
|
||||
if (type->Is(Type::Signed32())) return type;
|
||||
if (type->Is(t->zeroish_)) return t->singleton_zero_;
|
||||
if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero;
|
||||
if (type->Is(t->signed32ish_)) {
|
||||
return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()),
|
||||
Type::Signed32(), t->zone());
|
||||
return Type::Intersect(
|
||||
Type::Union(type, t->cache_.kSingletonZero, t->zone()),
|
||||
Type::Signed32(), t->zone());
|
||||
}
|
||||
return Type::Signed32();
|
||||
}
|
||||
@ -607,10 +547,11 @@ Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
|
||||
Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
|
||||
// TODO(neis): DCHECK(type->Is(Type::Number()));
|
||||
if (type->Is(Type::Unsigned32())) return type;
|
||||
if (type->Is(t->zeroish_)) return t->singleton_zero_;
|
||||
if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero;
|
||||
if (type->Is(t->unsigned32ish_)) {
|
||||
return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()),
|
||||
Type::Unsigned32(), t->zone());
|
||||
return Type::Intersect(
|
||||
Type::Union(type, t->cache_.kSingletonZero, t->zone()),
|
||||
Type::Unsigned32(), t->zone());
|
||||
}
|
||||
return Type::Unsigned32();
|
||||
}
|
||||
@ -1165,13 +1106,13 @@ Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
|
||||
// the discontinuity makes it too complicated. Note that even if none of the
|
||||
// "results" above is nan, the actual result may still be, so we have to do a
|
||||
// different check:
|
||||
bool maybe_nan = (lhs->Maybe(t->singleton_zero_) &&
|
||||
bool maybe_nan = (lhs->Maybe(t->cache_.kSingletonZero) &&
|
||||
(rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
|
||||
(rhs->Maybe(t->singleton_zero_) &&
|
||||
(rhs->Maybe(t->cache_.kSingletonZero) &&
|
||||
(lmin == -V8_INFINITY || lmax == +V8_INFINITY));
|
||||
if (maybe_nan) return t->cache_->Get(kWeakint); // Giving up.
|
||||
bool maybe_minuszero = (lhs->Maybe(t->singleton_zero_) && rmin < 0) ||
|
||||
(rhs->Maybe(t->singleton_zero_) && lmin < 0);
|
||||
if (maybe_nan) return t->cache_.kWeakint; // Giving up.
|
||||
bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) ||
|
||||
(rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0);
|
||||
Type* range =
|
||||
Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
|
||||
return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
|
||||
@ -1197,7 +1138,7 @@ Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
|
||||
// Division is tricky, so all we do is try ruling out nan.
|
||||
// TODO(neis): try ruling out -0 as well?
|
||||
bool maybe_nan =
|
||||
lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) ||
|
||||
lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
|
||||
((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
|
||||
(rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
|
||||
return maybe_nan ? Type::Number() : Type::OrderedNumber();
|
||||
@ -1242,7 +1183,7 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
|
||||
rhs = ToNumber(rhs, t);
|
||||
if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
|
||||
|
||||
if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) ||
|
||||
if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
|
||||
lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
|
||||
// Result maybe NaN.
|
||||
return Type::Number();
|
||||
@ -1375,7 +1316,7 @@ Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
|
||||
STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
|
||||
|
||||
// If the types have nothing to do with integers, return the types.
|
||||
Type* const integer = typer_->cache_->Get(kInteger);
|
||||
Type* const integer = typer_->cache_.kInteger;
|
||||
if (!previous_type->Maybe(integer)) {
|
||||
return current_type;
|
||||
}
|
||||
@ -1839,7 +1780,7 @@ Bounds Typer::Visitor::TypeLoadBuffer(Node* node) {
|
||||
switch (BufferAccessOf(node->op()).external_array_type()) {
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
|
||||
case kExternal##Type##Array: \
|
||||
return Bounds(typer_->cache_->Get(k##Type));
|
||||
return Bounds(typer_->cache_.k##Type);
|
||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
||||
#undef TYPED_ARRAY_CASE
|
||||
}
|
||||
@ -2346,11 +2287,11 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
|
||||
if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) {
|
||||
switch (JSFunction::cast(*value)->shared()->builtin_function_id()) {
|
||||
case kMathRandom:
|
||||
return typer_->cache_->Get(kRandomFunc0);
|
||||
return typer_->cache_.kRandomFunc0;
|
||||
case kMathFloor:
|
||||
case kMathRound:
|
||||
case kMathCeil:
|
||||
return typer_->cache_->Get(kWeakintFunc1);
|
||||
return typer_->cache_.kWeakintFunc1;
|
||||
// Unary math functions.
|
||||
case kMathAbs: // TODO(rossberg): can't express overloading
|
||||
case kMathLog:
|
||||
@ -2363,17 +2304,17 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
|
||||
case kMathAsin:
|
||||
case kMathAtan:
|
||||
case kMathFround:
|
||||
return typer_->cache_->Get(kNumberFunc1);
|
||||
return typer_->cache_.kNumberFunc1;
|
||||
// Binary math functions.
|
||||
case kMathAtan2:
|
||||
case kMathPow:
|
||||
case kMathMax:
|
||||
case kMathMin:
|
||||
return typer_->cache_->Get(kNumberFunc2);
|
||||
return typer_->cache_.kNumberFunc2;
|
||||
case kMathImul:
|
||||
return typer_->cache_->Get(kImulFunc);
|
||||
return typer_->cache_.kImulFunc;
|
||||
case kMathClz32:
|
||||
return typer_->cache_->Get(kClz32Func);
|
||||
return typer_->cache_.kClz32Func;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2381,23 +2322,23 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
|
||||
Handle<Context> native =
|
||||
handle(context().ToHandleChecked()->native_context(), isolate());
|
||||
if (*value == native->array_buffer_fun()) {
|
||||
return typer_->cache_->Get(kArrayBufferFunc);
|
||||
return typer_->cache_.kArrayBufferFunc;
|
||||
} else if (*value == native->int8_array_fun()) {
|
||||
return typer_->cache_->Get(kInt8ArrayFunc);
|
||||
return typer_->cache_.kInt8ArrayFunc;
|
||||
} else if (*value == native->int16_array_fun()) {
|
||||
return typer_->cache_->Get(kInt16ArrayFunc);
|
||||
return typer_->cache_.kInt16ArrayFunc;
|
||||
} else if (*value == native->int32_array_fun()) {
|
||||
return typer_->cache_->Get(kInt32ArrayFunc);
|
||||
return typer_->cache_.kInt32ArrayFunc;
|
||||
} else if (*value == native->uint8_array_fun()) {
|
||||
return typer_->cache_->Get(kUint8ArrayFunc);
|
||||
return typer_->cache_.kUint8ArrayFunc;
|
||||
} else if (*value == native->uint16_array_fun()) {
|
||||
return typer_->cache_->Get(kUint16ArrayFunc);
|
||||
return typer_->cache_.kUint16ArrayFunc;
|
||||
} else if (*value == native->uint32_array_fun()) {
|
||||
return typer_->cache_->Get(kUint32ArrayFunc);
|
||||
return typer_->cache_.kUint32ArrayFunc;
|
||||
} else if (*value == native->float32_array_fun()) {
|
||||
return typer_->cache_->Get(kFloat32ArrayFunc);
|
||||
return typer_->cache_.kFloat32ArrayFunc;
|
||||
} else if (*value == native->float64_array_fun()) {
|
||||
return typer_->cache_->Get(kFloat64ArrayFunc);
|
||||
return typer_->cache_.kFloat64ArrayFunc;
|
||||
}
|
||||
}
|
||||
int const arity =
|
||||
@ -2407,13 +2348,13 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
|
||||
// Some smart optimization at work... &%$!&@+$!
|
||||
return Type::Any(zone());
|
||||
case 0:
|
||||
return typer_->cache_->Get(kAnyFunc0);
|
||||
return typer_->cache_.kAnyFunc0;
|
||||
case 1:
|
||||
return typer_->cache_->Get(kAnyFunc1);
|
||||
return typer_->cache_.kAnyFunc1;
|
||||
case 2:
|
||||
return typer_->cache_->Get(kAnyFunc2);
|
||||
return typer_->cache_.kAnyFunc2;
|
||||
case 3:
|
||||
return typer_->cache_->Get(kAnyFunc3);
|
||||
return typer_->cache_.kAnyFunc3;
|
||||
default: {
|
||||
DCHECK_LT(3, arity);
|
||||
Type** const params = zone()->NewArray<Type*>(arity);
|
||||
@ -2425,7 +2366,7 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
|
||||
switch (JSTypedArray::cast(*value)->type()) {
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
|
||||
case kExternal##Type##Array: \
|
||||
return typer_->cache_->Get(k##Type##Array);
|
||||
return typer_->cache_.k##Type##Array;
|
||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
||||
#undef TYPED_ARRAY_CASE
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
// Forward declarations.
|
||||
class LazyTypeCache;
|
||||
class TyperCache;
|
||||
|
||||
|
||||
class Typer {
|
||||
@ -41,18 +41,14 @@ class Typer {
|
||||
Type::FunctionType* function_type_;
|
||||
MaybeHandle<Context> const context_;
|
||||
Decorator* decorator_;
|
||||
TyperCache const& cache_;
|
||||
|
||||
Type* singleton_false_;
|
||||
Type* singleton_true_;
|
||||
Type* singleton_zero_;
|
||||
Type* singleton_one_;
|
||||
Type* zero_or_one_;
|
||||
Type* zeroish_;
|
||||
Type* signed32ish_;
|
||||
Type* unsigned32ish_;
|
||||
Type* falsish_;
|
||||
Type* truish_;
|
||||
LazyTypeCache* const cache_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Typer);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user