Revision: 17796
Author:   [email protected]
Date:     Fri Nov 15 15:14:09 2013 UTC
Log:      Provide Type::Of and Type::CurrentOf operators

[email protected]
BUG=

Review URL: https://codereview.chromium.org/73193004
http://code.google.com/p/v8/source/detail?r=17796

Modified:
 /branches/bleeding_edge/src/types.cc
 /branches/bleeding_edge/src/types.h

=======================================
--- /branches/bleeding_edge/src/types.cc        Mon Oct 14 12:14:42 2013 UTC
+++ /branches/bleeding_edge/src/types.cc        Fri Nov 15 15:14:09 2013 UTC
@@ -70,23 +70,23 @@
 }

 template<>
-Handle<Map> Type::Iterator<Map>::Current() {
+Handle<i::Map> Type::Iterator<i::Map>::Current() {
   return get_type()->as_class();
 }

 template<>
-Handle<v8::internal::Object> Type::Iterator<v8::internal::Object>::Current() {
+Handle<i::Object> Type::Iterator<i::Object>::Current() {
   return get_type()->as_constant();
 }


 template<>
-bool Type::Iterator<Map>::matches(Handle<Type> type) {
+bool Type::Iterator<i::Map>::matches(Handle<Type> type) {
   return type->is_class();
 }

 template<>
-bool Type::Iterator<v8::internal::Object>::matches(Handle<Type> type) {
+bool Type::Iterator<i::Object>::matches(Handle<Type> type) {
   return type->is_constant();
 }

@@ -105,8 +105,8 @@
   index_ = -1;
 }

-template class Type::Iterator<Map>;
-template class Type::Iterator<v8::internal::Object>;
+template class Type::Iterator<i::Map>;
+template class Type::Iterator<i::Object>;


 // Get the smallest bitset subsuming this type.
@@ -120,106 +120,112 @@
       bitset |= union_get(unioned, i)->LubBitset();
     }
     return bitset;
+  } else if (this->is_class()) {
+    return LubBitset(*this->as_class());
   } else {
-    Map* map = NULL;
-    if (this->is_class()) {
-      map = *this->as_class();
-    } else {
-      Handle<v8::internal::Object> value = this->as_constant();
-      if (value->IsSmi()) return kSmi;
-      map = HeapObject::cast(*value)->map();
-      if (map->instance_type() == HEAP_NUMBER_TYPE) {
-        int32_t i;
-        uint32_t u;
- if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32;
-        if (value->ToUint32(&u)) return kUnsigned32;
-        return kDouble;
-      }
-      if (map->instance_type() == ODDBALL_TYPE) {
-        if (value->IsUndefined()) return kUndefined;
-        if (value->IsNull()) return kNull;
-        if (value->IsTrue() || value->IsFalse()) return kBoolean;
-        if (value->IsTheHole()) return kAny;  // TODO(rossberg): kNone?
-        UNREACHABLE();
-      }
-    }
-    switch (map->instance_type()) {
-      case STRING_TYPE:
-      case ASCII_STRING_TYPE:
-      case CONS_STRING_TYPE:
-      case CONS_ASCII_STRING_TYPE:
-      case SLICED_STRING_TYPE:
-      case SLICED_ASCII_STRING_TYPE:
-      case EXTERNAL_STRING_TYPE:
-      case EXTERNAL_ASCII_STRING_TYPE:
-      case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
-      case SHORT_EXTERNAL_STRING_TYPE:
-      case SHORT_EXTERNAL_ASCII_STRING_TYPE:
-      case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
-      case INTERNALIZED_STRING_TYPE:
-      case ASCII_INTERNALIZED_STRING_TYPE:
-      case CONS_INTERNALIZED_STRING_TYPE:
-      case CONS_ASCII_INTERNALIZED_STRING_TYPE:
-      case EXTERNAL_INTERNALIZED_STRING_TYPE:
-      case EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
-      case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
-      case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
-      case SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
-      case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
-        return kString;
-      case SYMBOL_TYPE:
-        return kSymbol;
-      case ODDBALL_TYPE:
-        return kOddball;
-      case HEAP_NUMBER_TYPE:
-        return kDouble;
-      case JS_VALUE_TYPE:
-      case JS_DATE_TYPE:
-      case JS_OBJECT_TYPE:
-      case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
-      case JS_GENERATOR_OBJECT_TYPE:
-      case JS_MODULE_TYPE:
-      case JS_GLOBAL_OBJECT_TYPE:
-      case JS_BUILTINS_OBJECT_TYPE:
-      case JS_GLOBAL_PROXY_TYPE:
-      case JS_ARRAY_BUFFER_TYPE:
-      case JS_TYPED_ARRAY_TYPE:
-      case JS_DATA_VIEW_TYPE:
-      case JS_SET_TYPE:
-      case JS_MAP_TYPE:
-      case JS_WEAK_MAP_TYPE:
-      case JS_WEAK_SET_TYPE:
-        if (map->is_undetectable()) return kUndetectable;
-        return kOtherObject;
-      case JS_ARRAY_TYPE:
-        return kArray;
-      case JS_FUNCTION_TYPE:
-        return kFunction;
-      case JS_REGEXP_TYPE:
-        return kRegExp;
-      case JS_PROXY_TYPE:
-      case JS_FUNCTION_PROXY_TYPE:
-        return kProxy;
-      case MAP_TYPE:
- // When compiling stub templates, the meta map is used as a place holder - // for the actual map with which the template is later instantiated.
-        // We treat it as a kind of type variable whose upper bound is Any.
- // TODO(rossberg): for caching of CompareNilIC stubs to work correctly,
-        // we must exclude Undetectable here. This makes no sense, really,
-        // because it means that the template isn't actually parametric.
-        // Also, it doesn't apply elsewhere. 8-(
- // We ought to find a cleaner solution for compiling stubs parameterised
-        // over type or class variables, esp ones with bounds...
-        return kDetectable;
-      case DECLARED_ACCESSOR_INFO_TYPE:
-      case EXECUTABLE_ACCESSOR_INFO_TYPE:
-      case ACCESSOR_PAIR_TYPE:
-      case FIXED_ARRAY_TYPE:
-        return kInternal;
-      default:
-        UNREACHABLE();
-        return kNone;
-    }
+    return LubBitset(*this->as_constant());
+  }
+}
+
+
+int Type::LubBitset(i::Object* value) {
+  if (value->IsSmi()) return kSmi;
+  i::Map* map = i::HeapObject::cast(value)->map();
+  if (map->instance_type() == HEAP_NUMBER_TYPE) {
+    int32_t i;
+    uint32_t u;
+    if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32;
+    if (value->ToUint32(&u)) return kUnsigned32;
+    return kDouble;
+  }
+  if (map->instance_type() == ODDBALL_TYPE) {
+    if (value->IsUndefined()) return kUndefined;
+    if (value->IsNull()) return kNull;
+    if (value->IsBoolean()) return kBoolean;
+    if (value->IsTheHole()) return kAny;  // TODO(rossberg): kNone?
+    UNREACHABLE();
+  }
+  return Type::LubBitset(map);
+}
+
+
+int Type::LubBitset(i::Map* map) {
+  switch (map->instance_type()) {
+    case STRING_TYPE:
+    case ASCII_STRING_TYPE:
+    case CONS_STRING_TYPE:
+    case CONS_ASCII_STRING_TYPE:
+    case SLICED_STRING_TYPE:
+    case SLICED_ASCII_STRING_TYPE:
+    case EXTERNAL_STRING_TYPE:
+    case EXTERNAL_ASCII_STRING_TYPE:
+    case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
+    case SHORT_EXTERNAL_STRING_TYPE:
+    case SHORT_EXTERNAL_ASCII_STRING_TYPE:
+    case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
+    case INTERNALIZED_STRING_TYPE:
+    case ASCII_INTERNALIZED_STRING_TYPE:
+    case CONS_INTERNALIZED_STRING_TYPE:
+    case CONS_ASCII_INTERNALIZED_STRING_TYPE:
+    case EXTERNAL_INTERNALIZED_STRING_TYPE:
+    case EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
+    case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
+    case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
+    case SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
+    case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
+      return kString;
+    case SYMBOL_TYPE:
+      return kSymbol;
+    case ODDBALL_TYPE:
+      return kOddball;
+    case HEAP_NUMBER_TYPE:
+      return kDouble;
+    case JS_VALUE_TYPE:
+    case JS_DATE_TYPE:
+    case JS_OBJECT_TYPE:
+    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
+    case JS_GENERATOR_OBJECT_TYPE:
+    case JS_MODULE_TYPE:
+    case JS_GLOBAL_OBJECT_TYPE:
+    case JS_BUILTINS_OBJECT_TYPE:
+    case JS_GLOBAL_PROXY_TYPE:
+    case JS_ARRAY_BUFFER_TYPE:
+    case JS_TYPED_ARRAY_TYPE:
+    case JS_DATA_VIEW_TYPE:
+    case JS_SET_TYPE:
+    case JS_MAP_TYPE:
+    case JS_WEAK_MAP_TYPE:
+    case JS_WEAK_SET_TYPE:
+      if (map->is_undetectable()) return kUndetectable;
+      return kOtherObject;
+    case JS_ARRAY_TYPE:
+      return kArray;
+    case JS_FUNCTION_TYPE:
+      return kFunction;
+    case JS_REGEXP_TYPE:
+      return kRegExp;
+    case JS_PROXY_TYPE:
+    case JS_FUNCTION_PROXY_TYPE:
+      return kProxy;
+    case MAP_TYPE:
+ // When compiling stub templates, the meta map is used as a place holder
+      // for the actual map with which the template is later instantiated.
+      // We treat it as a kind of type variable whose upper bound is Any.
+ // TODO(rossberg): for caching of CompareNilIC stubs to work correctly,
+      // we must exclude Undetectable here. This makes no sense, really,
+      // because it means that the template isn't actually parametric.
+      // Also, it doesn't apply elsewhere. 8-(
+ // We ought to find a cleaner solution for compiling stubs parameterised
+      // over type or class variables, esp ones with bounds...
+      return kDetectable;
+    case DECLARED_ACCESSOR_INFO_TYPE:
+    case EXECUTABLE_ACCESSOR_INFO_TYPE:
+    case ACCESSOR_PAIR_TYPE:
+    case FIXED_ARRAY_TYPE:
+      return kInternal;
+    default:
+      UNREACHABLE();
+      return kNone;
   }
 }

@@ -234,6 +240,18 @@
   } else {
     return kNone;
   }
+}
+
+
+// Most precise _current_ type of a value (usually its class).
+Type* Type::CurrentOf(Handle<i::Object> value) {
+  if (value->IsSmi()) return Smi();
+  i::Map* map = i::HeapObject::cast(*value)->map();
+  if (map->instance_type() == HEAP_NUMBER_TYPE ||
+      map->instance_type() == ODDBALL_TYPE) {
+    return Type::Of(value);
+  }
+  return Class(i::handle(map));
 }


@@ -374,11 +392,11 @@
   Isolate* isolate = NULL;
   int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0;
   if (!type1->is_bitset()) {
-    isolate = HeapObject::cast(*type1)->GetIsolate();
+    isolate = i::HeapObject::cast(*type1)->GetIsolate();
     size += (type1->is_union() ? type1->as_union()->length() : 1);
   }
   if (!type2->is_bitset()) {
-    isolate = HeapObject::cast(*type2)->GetIsolate();
+    isolate = i::HeapObject::cast(*type2)->GetIsolate();
     size += (type2->is_union() ? type2->as_union()->length() : 1);
   }
   ASSERT(isolate != NULL);
@@ -450,11 +468,11 @@
   Isolate* isolate = NULL;
   int size = 0;
   if (!type1->is_bitset()) {
-    isolate = HeapObject::cast(*type1)->GetIsolate();
+    isolate = i::HeapObject::cast(*type1)->GetIsolate();
     size = (type1->is_union() ? type1->as_union()->length() : 2);
   }
   if (!type2->is_bitset()) {
-    isolate = HeapObject::cast(*type2)->GetIsolate();
+    isolate = i::HeapObject::cast(*type2)->GetIsolate();
     int size2 = (type2->is_union() ? type2->as_union()->length() : 2);
     size = (size == 0 ? size2 : Min(size, size2));
   }
=======================================
--- /branches/bleeding_edge/src/types.h Mon Oct 14 12:14:42 2013 UTC
+++ /branches/bleeding_edge/src/types.h Fri Nov 15 15:14:09 2013 UTC
@@ -144,11 +144,11 @@
   TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
   #undef DEFINE_TYPE_CONSTRUCTOR

-  static Type* Class(Handle<Map> map) { return from_handle(map); }
-  static Type* Constant(Handle<HeapObject> value) {
+  static Type* Class(Handle<i::Map> map) { return from_handle(map); }
+  static Type* Constant(Handle<i::HeapObject> value) {
     return Constant(value, value->GetIsolate());
   }
- static Type* Constant(Handle<v8::internal::Object> value, Isolate* isolate) {
+  static Type* Constant(Handle<i::Object> value, Isolate* isolate) {
     return from_handle(isolate->factory()->NewBox(value));
   }

@@ -156,6 +156,11 @@
   static Type* Intersect(Handle<Type> type1, Handle<Type> type2);
   static Type* Optional(Handle<Type> type);  // type \/ Undefined

+  static Type* Of(Handle<i::Object> value) {
+    return from_bitset(LubBitset(*value));
+  }
+  static Type* CurrentOf(Handle<i::Object> value);
+
   bool Is(Type* that) { return (this == that) ? true : SlowIs(that); }
   bool Is(Handle<Type> that) { return this->Is(*that); }
   bool Maybe(Type* that);
@@ -163,8 +168,8 @@

   bool IsClass() { return is_class(); }
   bool IsConstant() { return is_constant(); }
-  Handle<Map> AsClass() { return as_class(); }
-  Handle<v8::internal::Object> AsConstant() { return as_constant(); }
+  Handle<i::Map> AsClass() { return as_class(); }
+  Handle<i::Object> AsConstant() { return as_constant(); }

   int NumClasses();
   int NumConstants();
@@ -191,16 +196,16 @@
     int index_;
   };

-  Iterator<Map> Classes() {
-    if (this->is_bitset()) return Iterator<Map>();
-    return Iterator<Map>(this->handle());
+  Iterator<i::Map> Classes() {
+    if (this->is_bitset()) return Iterator<i::Map>();
+    return Iterator<i::Map>(this->handle());
   }
-  Iterator<v8::internal::Object> Constants() {
-    if (this->is_bitset()) return Iterator<v8::internal::Object>();
-    return Iterator<v8::internal::Object>(this->handle());
+  Iterator<i::Object> Constants() {
+    if (this->is_bitset()) return Iterator<i::Object>();
+    return Iterator<i::Object>(this->handle());
   }

-  static Type* cast(v8::internal::Object* object) {
+  static Type* cast(i::Object* object) {
     Type* t = static_cast<Type*>(object);
     ASSERT(t->is_bitset() || t->is_class() ||
            t->is_constant() || t->is_union());
@@ -235,24 +240,24 @@
   bool SlowIs(Type* that);

   int as_bitset() { return Smi::cast(this)->value(); }
-  Handle<Map> as_class() { return Handle<Map>::cast(handle()); }
-  Handle<v8::internal::Object> as_constant() {
-    Handle<Box> box = Handle<Box>::cast(handle());
-    return v8::internal::handle(box->value(), box->GetIsolate());
+  Handle<i::Map> as_class() { return Handle<i::Map>::cast(handle()); }
+  Handle<i::Object> as_constant() {
+    Handle<i::Box> box = Handle<i::Box>::cast(handle());
+    return i::handle(box->value(), box->GetIsolate());
   }
   Handle<Unioned> as_union() { return Handle<Unioned>::cast(handle()); }

   Handle<Type> handle() { return handle_via_isolate_of(this); }
   Handle<Type> handle_via_isolate_of(Type* type) {
     ASSERT(type->IsHeapObject());
- return v8::internal::handle(this, HeapObject::cast(type)->GetIsolate());
+    return i::handle(this, i::HeapObject::cast(type)->GetIsolate());
   }

   static Type* from_bitset(int bitset) {
-    return static_cast<Type*>(Object::cast(Smi::FromInt(bitset)));
+    return static_cast<Type*>(i::Object::cast(i::Smi::FromInt(bitset)));
   }
-  static Type* from_handle(Handle<HeapObject> handle) {
-    return static_cast<Type*>(Object::cast(*handle));
+  static Type* from_handle(Handle<i::HeapObject> handle) {
+    return static_cast<Type*>(i::Object::cast(*handle));
   }

   static Handle<Type> union_get(Handle<Unioned> unioned, int i) {
@@ -263,6 +268,10 @@

   int LubBitset();  // least upper bound that's a bitset
   int GlbBitset();  // greatest lower bound that's a bitset
+
+  static int LubBitset(i::Object* value);
+  static int LubBitset(i::Map* map);
+
   bool InUnion(Handle<Unioned> unioned, int current_size);
   int ExtendUnion(Handle<Unioned> unioned, int current_size);
   int ExtendIntersection(

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to