Index: src/compiler/typer.cc |
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc |
index 56a440c8d99f2509d322ab2c50c8f7ca79c900db..69d95fb72b582a9671efdc8a341304fae76cd22b 100644 |
--- a/src/compiler/typer.cc |
+++ b/src/compiler/typer.cc |
@@ -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) |
- |
-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 |
-}; |
- |
+class TyperCache final { |
+ private: |
+ // This has to be first for the initialization magic to work. |
+ Zone zone_; |
-// 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_)); |
- } |
- |
- 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]; |
- } |
+ TyperCache() = default; |
+ |
+ 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 |
} |