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