[turbofan] Initialize less frequently used types in typer.cc lazily.
authortitzer <titzer@chromium.org>
Tue, 2 Dec 2014 10:43:00 +0000 (02:43 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 2 Dec 2014 10:43:13 +0000 (10:43 +0000)
R=jarin@chromium.org
BUG=

Review URL: https://codereview.chromium.org/771683002

Cr-Commit-Position: refs/heads/master@{#25602}

src/compiler/typer.cc
src/compiler/typer.h

index 35664ed..67b73eb 100644 (file)
@@ -15,6 +15,118 @@ namespace v8 {
 namespace internal {
 namespace compiler {
 
+enum LazyCachedType {
+  kNumberFunc0,
+  kNumberFunc1,
+  kNumberFunc2,
+  kImulFunc,
+  kClz32Func,
+  kArrayBufferFunc,
+  kInt8ArrayFunc,
+  kInt16ArrayFunc,
+  kInt32ArrayFunc,
+  kUint8ArrayFunc,
+  kUint16ArrayFunc,
+  kUint32ArrayFunc,
+  kFloat32ArrayFunc,
+  kFloat64ArrayFunc,
+  kNumLazyCachedTypes
+};
+
+
+// Constructs and caches types lazily.
+// TODO(turbofan): these types could be globally cached or cached per isolate.
+struct LazyTypeCache : public ZoneObject {
+  Zone* zone;
+  Type* cache_[kNumLazyCachedTypes];
+
+  explicit LazyTypeCache(Zone* z) : zone(z) {
+    memset(cache_, 0, sizeof(cache_));
+  }
+
+  inline Type* Get(LazyCachedType type) {
+    int index = static_cast<int>(type);
+    DCHECK(index < kNumLazyCachedTypes);
+    if (cache_[index] == NULL) cache_[index] = Create(type);
+    return cache_[index];
+  }
+
+  Type* Create(LazyCachedType type) {
+    Factory* f = zone->isolate()->factory();
+    Handle<Smi> zero(Smi::FromInt(0), zone->isolate());
+
+#define NATIVE_TYPE(sem, rep) Type::Intersect(Type::sem(), Type::rep(), zone)
+    switch (type) {
+      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(Type::Range(zero, f->NewNumber(32), zone),
+                              Type::Number(), zone);
+      }
+      case kArrayBufferFunc: {
+        return Type::Function(Type::Buffer(zone), Type::Unsigned32(), zone);
+      }
+      case kInt8ArrayFunc: {
+        return GetArrayFunc(Type::Intersect(
+            Type::Range(f->NewNumber(kMinInt8), f->NewNumber(kMaxInt8), zone),
+            Type::UntaggedInt8(), zone));
+      }
+      case kInt16ArrayFunc: {
+        return GetArrayFunc(Type::Intersect(
+            Type::Range(f->NewNumber(kMinInt16), f->NewNumber(kMaxInt16), zone),
+            Type::UntaggedInt16(), zone));
+      }
+      case kInt32ArrayFunc: {
+        return GetArrayFunc(NATIVE_TYPE(Signed32, UntaggedInt32));
+      }
+      case kUint8ArrayFunc: {
+        return GetArrayFunc(
+            Type::Intersect(Type::Range(zero, f->NewNumber(kMaxUInt8), zone),
+                            Type::UntaggedInt8(), zone));
+      }
+      case kUint16ArrayFunc: {
+        return GetArrayFunc(
+            Type::Intersect(Type::Range(zero, f->NewNumber(kMaxUInt16), zone),
+                            Type::UntaggedInt16(), zone));
+      }
+      case kUint32ArrayFunc: {
+        return GetArrayFunc(NATIVE_TYPE(Unsigned32, UntaggedInt32));
+      }
+      case kFloat32ArrayFunc: {
+        return GetArrayFunc(NATIVE_TYPE(Number, UntaggedFloat32));
+      }
+      case kFloat64ArrayFunc: {
+        return GetArrayFunc(NATIVE_TYPE(Number, UntaggedFloat64));
+      }
+      default:
+        break;
+    }
+#undef NATIVE_TYPE
+
+    UNREACHABLE();
+    return NULL;
+  }
+
+  Type* GetArrayFunc(Type* element) {
+    Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone);
+    Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone);
+    Type* arg3 = arg2;
+    return Type::Function(Type::Array(element, zone), arg1, arg2, arg3, zone);
+  }
+};
+
 class Typer::Decorator : public GraphDecorator {
  public:
   explicit Decorator(Typer* typer) : typer_(typer) {}
@@ -29,6 +141,7 @@ Typer::Typer(Graph* graph, MaybeHandle<Context> context)
     : graph_(graph),
       context_(context),
       decorator_(NULL),
+      cache_(new (graph->zone()) LazyTypeCache(graph->zone())),
       weaken_min_limits_(graph->zone()),
       weaken_max_limits_(graph->zone()) {
   Zone* zone = this->zone();
@@ -42,9 +155,6 @@ Typer::Typer(Graph* graph, MaybeHandle<Context> context)
   Type* number = Type::Number();
   Type* signed32 = Type::Signed32();
   Type* unsigned32 = Type::Unsigned32();
-  Type* integral32 = Type::Integral32();
-  Type* object = Type::Object();
-  Type* undefined = Type::Undefined();
   Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone);
   Type* truncating_to_zero =
       Type::Union(Type::Union(Type::Constant(infinity, zone),
@@ -78,46 +188,11 @@ Typer::Typer(Graph* graph, MaybeHandle<Context> context)
   number_fun0_ = Type::Function(number, zone);
   number_fun1_ = Type::Function(number, number, zone);
   number_fun2_ = Type::Function(number, number, number, zone);
+
   weakint_fun1_ = Type::Function(weakint, number, zone);
-  imul_fun_ = Type::Function(signed32, integral32, integral32, zone);
-  clz32_fun_ = Type::Function(
-      Type::Range(zero, f->NewNumber(32), zone), number, zone);
   random_fun_ = Type::Function(Type::Union(
       Type::UnsignedSmall(), Type::OtherNumber(), zone), zone);
 
-#define NATIVE_TYPE(sem, rep) Type::Intersect(sem, rep, zone)
-  Type* int8 = NATIVE_TYPE(signed8_, Type::UntaggedInt8());
-  Type* uint8 = NATIVE_TYPE(unsigned8_, Type::UntaggedInt8());
-  Type* int16 = NATIVE_TYPE(signed16_, Type::UntaggedInt16());
-  Type* uint16 = NATIVE_TYPE(unsigned16_, Type::UntaggedInt16());
-  Type* int32 = NATIVE_TYPE(Type::Signed32(), Type::UntaggedInt32());
-  Type* uint32 = NATIVE_TYPE(Type::Unsigned32(), Type::UntaggedInt32());
-  Type* float32 = NATIVE_TYPE(Type::Number(), Type::UntaggedFloat32());
-  Type* float64 = NATIVE_TYPE(Type::Number(), Type::UntaggedFloat64());
-#undef NATIVE_TYPE
-
-  Type* buffer = Type::Buffer(zone);
-  Type* int8_array = Type::Array(int8, zone);
-  Type* int16_array = Type::Array(int16, zone);
-  Type* int32_array = Type::Array(int32, zone);
-  Type* uint8_array = Type::Array(uint8, zone);
-  Type* uint16_array = Type::Array(uint16, zone);
-  Type* uint32_array = Type::Array(uint32, zone);
-  Type* float32_array = Type::Array(float32, zone);
-  Type* float64_array = Type::Array(float64, zone);
-  Type* arg1 = Type::Union(unsigned32, object, zone);
-  Type* arg2 = Type::Union(unsigned32, undefined, zone);
-  Type* arg3 = arg2;
-  array_buffer_fun_ = Type::Function(buffer, unsigned32, zone);
-  int8_array_fun_ = Type::Function(int8_array, arg1, arg2, arg3, zone);
-  int16_array_fun_ = Type::Function(int16_array, arg1, arg2, arg3, zone);
-  int32_array_fun_ = Type::Function(int32_array, arg1, arg2, arg3, zone);
-  uint8_array_fun_ = Type::Function(uint8_array, arg1, arg2, arg3, zone);
-  uint16_array_fun_ = Type::Function(uint16_array, arg1, arg2, arg3, zone);
-  uint32_array_fun_ = Type::Function(uint32_array, arg1, arg2, arg3, zone);
-  float32_array_fun_ = Type::Function(float32_array, arg1, arg2, arg3, zone);
-  float64_array_fun_ = Type::Function(float64_array, arg1, arg2, arg3, zone);
-
   const int limits_count = 20;
 
   weaken_min_limits_.reserve(limits_count + 1);
@@ -1950,41 +2025,29 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
           return typer_->weakint_fun1_;
         case kMathCeil:
           return typer_->weakint_fun1_;
-        case kMathAbs:
-          // TODO(rossberg): can't express overloading
-          return typer_->number_fun1_;
+        // Unary math functions.
+        case kMathAbs:  // TODO(rossberg): can't express overloading
         case kMathLog:
-          return typer_->number_fun1_;
         case kMathExp:
-          return typer_->number_fun1_;
         case kMathSqrt:
-          return typer_->number_fun1_;
-        case kMathPow:
-          return typer_->number_fun2_;
-        case kMathMax:
-          return typer_->number_fun2_;
-        case kMathMin:
-          return typer_->number_fun2_;
         case kMathCos:
-          return typer_->number_fun1_;
         case kMathSin:
-          return typer_->number_fun1_;
         case kMathTan:
-          return typer_->number_fun1_;
         case kMathAcos:
-          return typer_->number_fun1_;
         case kMathAsin:
-          return typer_->number_fun1_;
         case kMathAtan:
-          return typer_->number_fun1_;
+        case kMathFround:
+          return typer_->cache_->Get(kNumberFunc1);
+        // Binary math functions.
         case kMathAtan2:
-          return typer_->number_fun2_;
+        case kMathPow:
+        case kMathMax:
+        case kMathMin:
+          return typer_->cache_->Get(kNumberFunc2);
         case kMathImul:
-          return typer_->imul_fun_;
+          return typer_->cache_->Get(kImulFunc);
         case kMathClz32:
-          return typer_->clz32_fun_;
-        case kMathFround:
-          return typer_->number_fun1_;
+          return typer_->cache_->Get(kClz32Func);
         default:
           break;
       }
@@ -1992,23 +2055,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_->array_buffer_fun_;
+        return typer_->cache_->Get(kArrayBufferFunc);
       } else if (*value == native->int8_array_fun()) {
-        return typer_->int8_array_fun_;
+        return typer_->cache_->Get(kInt8ArrayFunc);
       } else if (*value == native->int16_array_fun()) {
-        return typer_->int16_array_fun_;
+        return typer_->cache_->Get(kInt16ArrayFunc);
       } else if (*value == native->int32_array_fun()) {
-        return typer_->int32_array_fun_;
+        return typer_->cache_->Get(kInt32ArrayFunc);
       } else if (*value == native->uint8_array_fun()) {
-        return typer_->uint8_array_fun_;
+        return typer_->cache_->Get(kUint8ArrayFunc);
       } else if (*value == native->uint16_array_fun()) {
-        return typer_->uint16_array_fun_;
+        return typer_->cache_->Get(kUint16ArrayFunc);
       } else if (*value == native->uint32_array_fun()) {
-        return typer_->uint32_array_fun_;
+        return typer_->cache_->Get(kUint32ArrayFunc);
       } else if (*value == native->float32_array_fun()) {
-        return typer_->float32_array_fun_;
+        return typer_->cache_->Get(kFloat32ArrayFunc);
       } else if (*value == native->float64_array_fun()) {
-        return typer_->float64_array_fun_;
+        return typer_->cache_->Get(kFloat64ArrayFunc);
       }
     }
   }
index 2cd9597..6c5bc1e 100644 (file)
@@ -15,6 +15,8 @@ namespace v8 {
 namespace internal {
 namespace compiler {
 
+struct LazyTypeCache;
+
 class Typer {
  public:
   explicit Typer(Graph* graph, MaybeHandle<Context> context);
@@ -60,18 +62,8 @@ class Typer {
   Type* number_fun1_;
   Type* number_fun2_;
   Type* weakint_fun1_;
-  Type* imul_fun_;
-  Type* clz32_fun_;
   Type* random_fun_;
-  Type* array_buffer_fun_;
-  Type* int8_array_fun_;
-  Type* int16_array_fun_;
-  Type* int32_array_fun_;
-  Type* uint8_array_fun_;
-  Type* uint16_array_fun_;
-  Type* uint32_array_fun_;
-  Type* float32_array_fun_;
-  Type* float64_array_fun_;
+  LazyTypeCache* cache_;
 
   ZoneVector<Handle<Object> > weaken_min_limits_;
   ZoneVector<Handle<Object> > weaken_max_limits_;