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 typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::SignedSmall() {
     21   return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
     22 }
     23 
     24 
     25 template<class Config>
     26 typename TypeImpl<Config>::bitset
     27 TypeImpl<Config>::BitsetType::UnsignedSmall() {
     28   return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
     29 }
     30 
     31 
     32 #define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
     33 template<class Config> \
     34 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Name( \
     35     Isolate* isolate, Region* region) { \
     36   return Class(i::handle(isolate->heap()->name##_map()), region); \
     37 }
     38 SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
     39 #undef CONSTRUCT_SIMD_TYPE
     40 
     41 
     42 template<class Config>
     43 TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
     44   TypeImpl* t = static_cast<TypeImpl*>(object);
     45   DCHECK(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsRange() ||
     46          t->IsUnion() || t->IsArray() || t->IsFunction() || t->IsContext());
     47   return t;
     48 }
     49 
     50 
     51 // Most precise _current_ type of a value (usually its class).
     52 template<class Config>
     53 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
     54     i::Object* value, Region* region) {
     55   if (value->IsSmi() ||
     56       i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
     57     return Of(value, region);
     58   }
     59   return Class(i::handle(i::HeapObject::cast(value)->map()), region);
     60 }
     61 
     62 
     63 template<class Config>
     64 bool TypeImpl<Config>::NowContains(i::Object* value) {
     65   DisallowHeapAllocation no_allocation;
     66   if (this->IsAny()) return true;
     67   if (value->IsHeapObject()) {
     68     i::Map* map = i::HeapObject::cast(value)->map();
     69     for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
     70       if (*it.Current() == map) return true;
     71     }
     72   }
     73   return this->Contains(value);
     74 }
     75 
     76 
     77 // -----------------------------------------------------------------------------
     78 // ZoneTypeConfig
     79 
     80 // static
     81 template<class T>
     82 T* ZoneTypeConfig::handle(T* type) {
     83   return type;
     84 }
     85 
     86 
     87 // static
     88 template<class T>
     89 T* ZoneTypeConfig::cast(Type* type) {
     90   return static_cast<T*>(type);
     91 }
     92 
     93 
     94 // static
     95 bool ZoneTypeConfig::is_bitset(Type* type) {
     96   return reinterpret_cast<uintptr_t>(type) & 1;
     97 }
     98 
     99 
    100 // static
    101 bool ZoneTypeConfig::is_struct(Type* type, int tag) {
    102   DCHECK(tag != kRangeStructTag);
    103   if (is_bitset(type)) return false;
    104   int type_tag = struct_tag(as_struct(type));
    105   return type_tag == tag;
    106 }
    107 
    108 
    109 // static
    110 bool ZoneTypeConfig::is_range(Type* type) {
    111   if (is_bitset(type)) return false;
    112   int type_tag = struct_tag(as_struct(type));
    113   return type_tag == kRangeStructTag;
    114 }
    115 
    116 
    117 // static
    118 bool ZoneTypeConfig::is_class(Type* type) {
    119   return false;
    120 }
    121 
    122 
    123 // static
    124 ZoneTypeConfig::Type::bitset ZoneTypeConfig::as_bitset(Type* type) {
    125   DCHECK(is_bitset(type));
    126   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type) ^ 1u);
    127 }
    128 
    129 
    130 // static
    131 ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
    132   DCHECK(!is_bitset(type));
    133   return reinterpret_cast<Struct*>(type);
    134 }
    135 
    136 
    137 // static
    138 ZoneTypeConfig::Range* ZoneTypeConfig::as_range(Type* type) {
    139   DCHECK(!is_bitset(type));
    140   return reinterpret_cast<Range*>(type);
    141 }
    142 
    143 
    144 // static
    145 i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
    146   UNREACHABLE();
    147   return i::Handle<i::Map>();
    148 }
    149 
    150 
    151 // static
    152 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(Type::bitset bitset) {
    153   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset | 1u));
    154 }
    155 
    156 
    157 // static
    158 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(
    159     Type::bitset bitset, Zone* Zone) {
    160   return from_bitset(bitset);
    161 }
    162 
    163 
    164 // static
    165 ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) {
    166   return reinterpret_cast<Type*>(structure);
    167 }
    168 
    169 
    170 // static
    171 ZoneTypeConfig::Type* ZoneTypeConfig::from_range(Range* range) {
    172   return reinterpret_cast<Type*>(range);
    173 }
    174 
    175 
    176 // static
    177 ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
    178     i::Handle<i::Map> map, Zone* zone) {
    179   return from_bitset(0);
    180 }
    181 
    182 
    183 // static
    184 ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
    185     int tag, int length, Zone* zone) {
    186   DCHECK(tag != kRangeStructTag);
    187   Struct* structure = reinterpret_cast<Struct*>(
    188       zone->New(sizeof(void*) * (length + 2)));  // NOLINT
    189   structure[0] = reinterpret_cast<void*>(tag);
    190   structure[1] = reinterpret_cast<void*>(length);
    191   return structure;
    192 }
    193 
    194 
    195 // static
    196 void ZoneTypeConfig::struct_shrink(Struct* structure, int length) {
    197   DCHECK(0 <= length && length <= struct_length(structure));
    198   structure[1] = reinterpret_cast<void*>(length);
    199 }
    200 
    201 
    202 // static
    203 int ZoneTypeConfig::struct_tag(Struct* structure) {
    204   return static_cast<int>(reinterpret_cast<intptr_t>(structure[0]));
    205 }
    206 
    207 
    208 // static
    209 int ZoneTypeConfig::struct_length(Struct* structure) {
    210   return static_cast<int>(reinterpret_cast<intptr_t>(structure[1]));
    211 }
    212 
    213 
    214 // static
    215 Type* ZoneTypeConfig::struct_get(Struct* structure, int i) {
    216   DCHECK(0 <= i && i <= struct_length(structure));
    217   return static_cast<Type*>(structure[2 + i]);
    218 }
    219 
    220 
    221 // static
    222 void ZoneTypeConfig::struct_set(Struct* structure, int i, Type* x) {
    223   DCHECK(0 <= i && i <= struct_length(structure));
    224   structure[2 + i] = x;
    225 }
    226 
    227 
    228 // static
    229 template<class V>
    230 i::Handle<V> ZoneTypeConfig::struct_get_value(Struct* structure, int i) {
    231   DCHECK(0 <= i && i <= struct_length(structure));
    232   return i::Handle<V>(static_cast<V**>(structure[2 + i]));
    233 }
    234 
    235 
    236 // static
    237 template<class V>
    238 void ZoneTypeConfig::struct_set_value(
    239     Struct* structure, int i, i::Handle<V> x) {
    240   DCHECK(0 <= i && i <= struct_length(structure));
    241   structure[2 + i] = x.location();
    242 }
    243 
    244 
    245 // static
    246 ZoneTypeConfig::Range* ZoneTypeConfig::range_create(Zone* zone) {
    247   Range* range = reinterpret_cast<Range*>(zone->New(sizeof(Range)));  // NOLINT
    248   range->tag = reinterpret_cast<void*>(kRangeStructTag);
    249   range->bitset = 0;
    250   range->limits[0] = 1;
    251   range->limits[1] = 0;
    252   return range;
    253 }
    254 
    255 
    256 // static
    257 int ZoneTypeConfig::range_get_bitset(ZoneTypeConfig::Range* range) {
    258   return range->bitset;
    259 }
    260 
    261 
    262 // static
    263 void ZoneTypeConfig::range_set_bitset(ZoneTypeConfig::Range* range, int value) {
    264   range->bitset = value;
    265 }
    266 
    267 
    268 // static
    269 double ZoneTypeConfig::range_get_double(ZoneTypeConfig::Range* range,
    270                                         int index) {
    271   DCHECK(index >= 0 && index < 2);
    272   return range->limits[index];
    273 }
    274 
    275 
    276 // static
    277 void ZoneTypeConfig::range_set_double(ZoneTypeConfig::Range* range, int index,
    278                                       double value, Zone*) {
    279   DCHECK(index >= 0 && index < 2);
    280   range->limits[index] = value;
    281 }
    282 
    283 
    284 // -----------------------------------------------------------------------------
    285 // HeapTypeConfig
    286 
    287 // static
    288 template<class T>
    289 i::Handle<T> HeapTypeConfig::handle(T* type) {
    290   return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
    291 }
    292 
    293 
    294 // static
    295 template<class T>
    296 i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
    297   return i::Handle<T>::cast(type);
    298 }
    299 
    300 
    301 // static
    302 bool HeapTypeConfig::is_bitset(Type* type) {
    303   return type->IsSmi();
    304 }
    305 
    306 
    307 // static
    308 bool HeapTypeConfig::is_class(Type* type) {
    309   return type->IsMap();
    310 }
    311 
    312 
    313 // static
    314 bool HeapTypeConfig::is_struct(Type* type, int tag) {
    315   DCHECK(tag != kRangeStructTag);
    316   return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
    317 }
    318 
    319 
    320 // static
    321 bool HeapTypeConfig::is_range(Type* type) {
    322   return type->IsFixedArray() && struct_tag(as_struct(type)) == kRangeStructTag;
    323 }
    324 
    325 
    326 // static
    327 HeapTypeConfig::Type::bitset HeapTypeConfig::as_bitset(Type* type) {
    328   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
    329   return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type));
    330 }
    331 
    332 
    333 // static
    334 i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) {
    335   return i::handle(i::Map::cast(type));
    336 }
    337 
    338 
    339 // static
    340 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
    341   return i::handle(Struct::cast(type));
    342 }
    343 
    344 
    345 // static
    346 i::Handle<HeapTypeConfig::Range> HeapTypeConfig::as_range(Type* type) {
    347   return i::handle(Range::cast(type));
    348 }
    349 
    350 
    351 // static
    352 HeapTypeConfig::Type* HeapTypeConfig::from_bitset(Type::bitset bitset) {
    353   // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way.
    354   return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset));
    355 }
    356 
    357 
    358 // static
    359 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
    360     Type::bitset bitset, Isolate* isolate) {
    361   return i::handle(from_bitset(bitset), isolate);
    362 }
    363 
    364 
    365 // static
    366 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class(
    367     i::Handle<i::Map> map, Isolate* isolate) {
    368   return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
    369 }
    370 
    371 
    372 // static
    373 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
    374     i::Handle<Struct> structure) {
    375   return i::Handle<Type>::cast(i::Handle<Object>::cast(structure));
    376 }
    377 
    378 
    379 // static
    380 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_range(
    381     i::Handle<Range> range) {
    382   return i::Handle<Type>::cast(i::Handle<Object>::cast(range));
    383 }
    384 
    385 
    386 // static
    387 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
    388     int tag, int length, Isolate* isolate) {
    389   i::Handle<Struct> structure = isolate->factory()->NewFixedArray(length + 1);
    390   structure->set(0, i::Smi::FromInt(tag));
    391   return structure;
    392 }
    393 
    394 
    395 // static
    396 void HeapTypeConfig::struct_shrink(i::Handle<Struct> structure, int length) {
    397   structure->Shrink(length + 1);
    398 }
    399 
    400 
    401 // static
    402 int HeapTypeConfig::struct_tag(i::Handle<Struct> structure) {
    403   return static_cast<i::Smi*>(structure->get(0))->value();
    404 }
    405 
    406 
    407 // static
    408 int HeapTypeConfig::struct_length(i::Handle<Struct> structure) {
    409   return structure->length() - 1;
    410 }
    411 
    412 
    413 // static
    414 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
    415     i::Handle<Struct> structure, int i) {
    416   Type* type = static_cast<Type*>(structure->get(i + 1));
    417   return i::handle(type, structure->GetIsolate());
    418 }
    419 
    420 
    421 // static
    422 void HeapTypeConfig::struct_set(
    423     i::Handle<Struct> structure, int i, i::Handle<Type> type) {
    424   structure->set(i + 1, *type);
    425 }
    426 
    427 
    428 // static
    429 template<class V>
    430 i::Handle<V> HeapTypeConfig::struct_get_value(
    431     i::Handle<Struct> structure, int i) {
    432   V* x = static_cast<V*>(structure->get(i + 1));
    433   return i::handle(x, structure->GetIsolate());
    434 }
    435 
    436 
    437 // static
    438 template<class V>
    439 void HeapTypeConfig::struct_set_value(
    440     i::Handle<Struct> structure, int i, i::Handle<V> x) {
    441   structure->set(i + 1, *x);
    442 }
    443 
    444 
    445 // static
    446 i::Handle<HeapTypeConfig::Range> HeapTypeConfig::range_create(
    447     Isolate* isolate) {
    448   i::Handle<Range> range = isolate->factory()->NewFixedArray(4);
    449   range->set(0, i::Smi::FromInt(kRangeStructTag));
    450   return range;
    451 }
    452 
    453 
    454 // static
    455 int HeapTypeConfig::range_get_bitset(i::Handle<HeapTypeConfig::Range> range) {
    456   Type* v = static_cast<Type*>(range->get(1));
    457   return as_bitset(v);
    458 }
    459 
    460 
    461 // static
    462 void HeapTypeConfig::range_set_bitset(i::Handle<HeapTypeConfig::Range> range,
    463                                       int value) {
    464   range->set(1, from_bitset(value));
    465 }
    466 
    467 
    468 // static
    469 double HeapTypeConfig::range_get_double(i::Handle<HeapTypeConfig::Range> range,
    470                                         int index) {
    471   DCHECK(index >= 0 && index < 2);
    472   return range->get(index + 2)->Number();
    473 }
    474 
    475 
    476 // static
    477 void HeapTypeConfig::range_set_double(i::Handle<HeapTypeConfig::Range> range,
    478                                       int index, double value,
    479                                       Isolate* isolate) {
    480   DCHECK(index >= 0 && index < 2);
    481   i::Handle<Object> number = isolate->factory()->NewNumber(value);
    482   range->set(index + 2, *number);
    483 }
    484 }  // namespace internal
    485 }  // namespace v8
    486 
    487 #endif  // V8_TYPES_INL_H_
    488