Home | History | Annotate | Download | only in src
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_TYPES_INL_H_
      6 #define V8_TYPES_INL_H_
      7 
      8 #include "src/types.h"
      9 
     10 #include "src/factory.h"
     11 #include "src/handles-inl.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 // -----------------------------------------------------------------------------
     17 // TypeImpl
     18 
     19 template<class Config>
     20 TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
     21   TypeImpl* t = static_cast<TypeImpl*>(object);
     22   DCHECK(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsRange() ||
     23          t->IsUnion() || t->IsArray() || t->IsFunction() || t->IsContext());
     24   return t;
     25 }
     26 
     27 
     28 // Most precise _current_ type of a value (usually its class).
     29 template<class Config>
     30 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
     31     i::Object* value, Region* region) {
     32   if (value->IsSmi() ||
     33       i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
     34     return Of(value, region);
     35   }
     36   return Class(i::handle(i::HeapObject::cast(value)->map()), region);
     37 }
     38 
     39 
     40 template<class Config>
     41 bool TypeImpl<Config>::NowContains(i::Object* value) {
     42   DisallowHeapAllocation no_allocation;
     43   if (this->IsAny()) return true;
     44   if (value->IsHeapObject()) {
     45     i::Map* map = i::HeapObject::cast(value)->map();
     46     for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
     47       if (*it.Current() == map) return true;
     48     }
     49   }
     50   return this->Contains(value);
     51 }
     52 
     53 
     54 // -----------------------------------------------------------------------------
     55 // ZoneTypeConfig
     56 
     57 // static
     58 template<class T>
     59 T* ZoneTypeConfig::handle(T* type) {
     60   return type;
     61 }
     62 
     63 
     64 // static
     65 template<class T>
     66 T* ZoneTypeConfig::cast(Type* type) {
     67   return static_cast<T*>(type);
     68 }
     69 
     70 
     71 // static
     72 bool ZoneTypeConfig::is_bitset(Type* type) {
     73   return reinterpret_cast<uintptr_t>(type) & 1;
     74 }
     75 
     76 
     77 // static
     78 bool ZoneTypeConfig::is_struct(Type* type, int tag) {
     79   return !is_bitset(type) && struct_tag(as_struct(type)) == tag;
     80 }
     81 
     82 
     83 // static
     84 bool ZoneTypeConfig::is_class(Type* type) {
     85   return false;
     86 }
     87 
     88 
     89 // static
     90 ZoneTypeConfig::Type::bitset ZoneTypeConfig::as_bitset(Type* type) {
     91   DCHECK(is_bitset(type));
     92   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type) ^ 1u);
     93 }
     94 
     95 
     96 // static
     97 ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
     98   DCHECK(!is_bitset(type));
     99   return reinterpret_cast<Struct*>(type);
    100 }
    101 
    102 
    103 // static
    104 i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
    105   UNREACHABLE();
    106   return i::Handle<i::Map>();
    107 }
    108 
    109 
    110 // static
    111 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(Type::bitset bitset) {
    112   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset | 1u));
    113 }
    114 
    115 
    116 // static
    117 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(
    118     Type::bitset bitset, Zone* Zone) {
    119   return from_bitset(bitset);
    120 }
    121 
    122 
    123 // static
    124 ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) {
    125   return reinterpret_cast<Type*>(structure);
    126 }
    127 
    128 
    129 // static
    130 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
    131     i::Handle<i::Map> map, Zone* zone) {
    132   return from_bitset(0);
    133 }
    134 
    135 
    136 // static
    137 ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
    138     int tag, int length, Zone* zone) {
    139   Struct* structure = reinterpret_cast<Struct*>(
    140       zone->New(sizeof(void*) * (length + 2)));  // NOLINT
    141   structure[0] = reinterpret_cast<void*>(tag);
    142   structure[1] = reinterpret_cast<void*>(length);
    143   return structure;
    144 }
    145 
    146 
    147 // static
    148 void ZoneTypeConfig::struct_shrink(Struct* structure, int length) {
    149   DCHECK(0 <= length && length <= struct_length(structure));
    150   structure[1] = reinterpret_cast<void*>(length);
    151 }
    152 
    153 
    154 // static
    155 int ZoneTypeConfig::struct_tag(Struct* structure) {
    156   return static_cast<int>(reinterpret_cast<intptr_t>(structure[0]));
    157 }
    158 
    159 
    160 // static
    161 int ZoneTypeConfig::struct_length(Struct* structure) {
    162   return static_cast<int>(reinterpret_cast<intptr_t>(structure[1]));
    163 }
    164 
    165 
    166 // static
    167 Type* ZoneTypeConfig::struct_get(Struct* structure, int i) {
    168   DCHECK(0 <= i && i <= struct_length(structure));
    169   return static_cast<Type*>(structure[2 + i]);
    170 }
    171 
    172 
    173 // static
    174 void ZoneTypeConfig::struct_set(Struct* structure, int i, Type* x) {
    175   DCHECK(0 <= i && i <= struct_length(structure));
    176   structure[2 + i] = x;
    177 }
    178 
    179 
    180 // static
    181 template<class V>
    182 i::Handle<V> ZoneTypeConfig::struct_get_value(Struct* structure, int i) {
    183   DCHECK(0 <= i && i <= struct_length(structure));
    184   return i::Handle<V>(static_cast<V**>(structure[2 + i]));
    185 }
    186 
    187 
    188 // static
    189 template<class V>
    190 void ZoneTypeConfig::struct_set_value(
    191     Struct* structure, int i, i::Handle<V> x) {
    192   DCHECK(0 <= i && i <= struct_length(structure));
    193   structure[2 + i] = x.location();
    194 }
    195 
    196 
    197 // -----------------------------------------------------------------------------
    198 // HeapTypeConfig
    199 
    200 // static
    201 template<class T>
    202 i::Handle<T> HeapTypeConfig::handle(T* type) {
    203   return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
    204 }
    205 
    206 
    207 // static
    208 template<class T>
    209 i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
    210   return i::Handle<T>::cast(type);
    211 }
    212 
    213 
    214 // static
    215 bool HeapTypeConfig::is_bitset(Type* type) {
    216   return type->IsSmi();
    217 }
    218 
    219 
    220 // static
    221 bool HeapTypeConfig::is_class(Type* type) {
    222   return type->IsMap();
    223 }
    224 
    225 
    226 // static
    227 bool HeapTypeConfig::is_struct(Type* type, int tag) {
    228   return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
    229 }
    230 
    231 
    232 // static
    233 HeapTypeConfig::Type::bitset HeapTypeConfig::as_bitset(Type* type) {
    234   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
    235   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type));
    236 }
    237 
    238 
    239 // static
    240 i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) {
    241   return i::handle(i::Map::cast(type));
    242 }
    243 
    244 
    245 // static
    246 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
    247   return i::handle(Struct::cast(type));
    248 }
    249 
    250 
    251 // static
    252 HeapTypeConfig::Type* HeapTypeConfig::from_bitset(Type::bitset bitset) {
    253   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
    254   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset));
    255 }
    256 
    257 
    258 // static
    259 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
    260     Type::bitset bitset, Isolate* isolate) {
    261   return i::handle(from_bitset(bitset), isolate);
    262 }
    263 
    264 
    265 // static
    266 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class(
    267     i::Handle<i::Map> map, Isolate* isolate) {
    268   return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
    269 }
    270 
    271 
    272 // static
    273 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
    274     i::Handle<Struct> structure) {
    275   return i::Handle<Type>::cast(i::Handle<Object>::cast(structure));
    276 }
    277 
    278 
    279 // static
    280 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
    281     int tag, int length, Isolate* isolate) {
    282   i::Handle<Struct> structure = isolate->factory()->NewFixedArray(length + 1);
    283   structure->set(0, i::Smi::FromInt(tag));
    284   return structure;
    285 }
    286 
    287 
    288 // static
    289 void HeapTypeConfig::struct_shrink(i::Handle<Struct> structure, int length) {
    290   structure->Shrink(length + 1);
    291 }
    292 
    293 
    294 // static
    295 int HeapTypeConfig::struct_tag(i::Handle<Struct> structure) {
    296   return static_cast<i::Smi*>(structure->get(0))->value();
    297 }
    298 
    299 
    300 // static
    301 int HeapTypeConfig::struct_length(i::Handle<Struct> structure) {
    302   return structure->length() - 1;
    303 }
    304 
    305 
    306 // static
    307 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
    308     i::Handle<Struct> structure, int i) {
    309   Type* type = static_cast<Type*>(structure->get(i + 1));
    310   return i::handle(type, structure->GetIsolate());
    311 }
    312 
    313 
    314 // static
    315 void HeapTypeConfig::struct_set(
    316     i::Handle<Struct> structure, int i, i::Handle<Type> type) {
    317   structure->set(i + 1, *type);
    318 }
    319 
    320 
    321 // static
    322 template<class V>
    323 i::Handle<V> HeapTypeConfig::struct_get_value(
    324     i::Handle<Struct> structure, int i) {
    325   V* x = static_cast<V*>(structure->get(i + 1));
    326   return i::handle(x, structure->GetIsolate());
    327 }
    328 
    329 
    330 // static
    331 template<class V>
    332 void HeapTypeConfig::struct_set_value(
    333     i::Handle<Struct> structure, int i, i::Handle<V> x) {
    334   structure->set(i + 1, *x);
    335 }
    336 
    337 } }  // namespace v8::internal
    338 
    339 #endif  // V8_TYPES_INL_H_
    340