| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_TYPES_H_ | 5 #ifndef V8_TYPES_H_ |
| 6 #define V8_TYPES_H_ | 6 #define V8_TYPES_H_ |
| 7 | 7 |
| 8 #include "handles.h" | 8 #include "handles.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 // - class HeapType (heap-allocated, for persistent types) | 125 // - class HeapType (heap-allocated, for persistent types) |
| 126 // | 126 // |
| 127 // Both provide the same API, and the Convert method can be used to interconvert | 127 // Both provide the same API, and the Convert method can be used to interconvert |
| 128 // them. For zone types, no query method touches the heap, only constructors do. | 128 // them. For zone types, no query method touches the heap, only constructors do. |
| 129 | 129 |
| 130 | 130 |
| 131 #define MASK_BITSET_TYPE_LIST(V) \ | 131 #define MASK_BITSET_TYPE_LIST(V) \ |
| 132 V(Representation, static_cast<int>(0xff800000)) \ | 132 V(Representation, static_cast<int>(0xff800000)) \ |
| 133 V(Semantic, static_cast<int>(0x007fffff)) | 133 V(Semantic, static_cast<int>(0x007fffff)) |
| 134 | 134 |
| 135 #define REPRESENTATION(k) ((k) & kRepresentation) | 135 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation) |
| 136 #define SEMANTIC(k) ((k) & kSemantic) | 136 #define SEMANTIC(k) ((k) & BitsetType::kSemantic) |
| 137 | 137 |
| 138 #define REPRESENTATION_BITSET_TYPE_LIST(V) \ | 138 #define REPRESENTATION_BITSET_TYPE_LIST(V) \ |
| 139 V(None, 0) \ | 139 V(None, 0) \ |
| 140 V(UntaggedInt8, 1 << 23 | kSemantic) \ | 140 V(UntaggedInt8, 1 << 23 | kSemantic) \ |
| 141 V(UntaggedInt16, 1 << 24 | kSemantic) \ | 141 V(UntaggedInt16, 1 << 24 | kSemantic) \ |
| 142 V(UntaggedInt32, 1 << 25 | kSemantic) \ | 142 V(UntaggedInt32, 1 << 25 | kSemantic) \ |
| 143 V(UntaggedFloat32, 1 << 26 | kSemantic) \ | 143 V(UntaggedFloat32, 1 << 26 | kSemantic) \ |
| 144 V(UntaggedFloat64, 1 << 27 | kSemantic) \ | 144 V(UntaggedFloat64, 1 << 27 | kSemantic) \ |
| 145 V(UntaggedPtr, 1 << 28 | kSemantic) \ | 145 V(UntaggedPtr, 1 << 28 | kSemantic) \ |
| 146 V(TaggedInt, 1 << 29 | kSemantic) \ | 146 V(TaggedInt, 1 << 29 | kSemantic) \ |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 // struct Config { | 195 // struct Config { |
| 196 // typedef TypeImpl<Config> Type; | 196 // typedef TypeImpl<Config> Type; |
| 197 // typedef Base; | 197 // typedef Base; |
| 198 // typedef Struct; | 198 // typedef Struct; |
| 199 // typedef Region; | 199 // typedef Region; |
| 200 // template<class> struct Handle { typedef type; } // No template typedefs... | 200 // template<class> struct Handle { typedef type; } // No template typedefs... |
| 201 // template<class T> static Handle<T>::type handle(T* t); // !is_bitset(t) | 201 // template<class T> static Handle<T>::type handle(T* t); // !is_bitset(t) |
| 202 // template<class T> static Handle<T>::type cast(Handle<Type>::type); | 202 // template<class T> static Handle<T>::type cast(Handle<Type>::type); |
| 203 // static bool is_bitset(Type*); | 203 // static bool is_bitset(Type*); |
| 204 // static bool is_class(Type*); | 204 // static bool is_class(Type*); |
| 205 // static bool is_constant(Type*); | |
| 206 // static bool is_struct(Type*, int tag); | 205 // static bool is_struct(Type*, int tag); |
| 207 // static int as_bitset(Type*); | 206 // static int as_bitset(Type*); |
| 208 // static i::Handle<i::Map> as_class(Type*); | 207 // static i::Handle<i::Map> as_class(Type*); |
| 209 // static i::Handle<i::Object> as_constant(Type*); | |
| 210 // static Handle<Struct>::type as_struct(Type*); | 208 // static Handle<Struct>::type as_struct(Type*); |
| 211 // static Type* from_bitset(int bitset); | 209 // static Type* from_bitset(int bitset); |
| 212 // static Handle<Type>::type from_bitset(int bitset, Region*); | 210 // static Handle<Type>::type from_bitset(int bitset, Region*); |
| 213 // static Handle<Type>::type from_class(i::Handle<Map>, int lub, Region*); | 211 // static Handle<Type>::type from_class(i::Handle<Map>, Region*); |
| 214 // static Handle<Type>::type from_constant(i::Handle<Object>, int, Region*); | |
| 215 // static Handle<Type>::type from_struct(Handle<Struct>::type, int tag); | 212 // static Handle<Type>::type from_struct(Handle<Struct>::type, int tag); |
| 216 // static Handle<Struct>::type struct_create(int tag, int length, Region*); | 213 // static Handle<Struct>::type struct_create(int tag, int length, Region*); |
| 217 // static void struct_shrink(Handle<Struct>::type, int length); | 214 // static void struct_shrink(Handle<Struct>::type, int length); |
| 218 // static int struct_tag(Handle<Struct>::type); | 215 // static int struct_tag(Handle<Struct>::type); |
| 219 // static int struct_length(Handle<Struct>::type); | 216 // static int struct_length(Handle<Struct>::type); |
| 220 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); | 217 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); |
| 221 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); | 218 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); |
| 222 // static int lub_bitset(Type*); | 219 // template<class V> |
| 220 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); |
| 221 // template<class V> |
| 222 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); |
| 223 // } | 223 // } |
| 224 template<class Config> | 224 template<class Config> |
| 225 class TypeImpl : public Config::Base { | 225 class TypeImpl : public Config::Base { |
| 226 public: | 226 public: |
| 227 class BitsetType; // Internal | 227 class BitsetType; // Internal |
| 228 class StructuralType; // Internal | 228 class StructuralType; // Internal |
| 229 class UnionType; // Internal | 229 class UnionType; // Internal |
| 230 | 230 |
| 231 class ClassType; | 231 class ClassType; |
| 232 class ConstantType; | 232 class ConstantType; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); | 282 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); |
| 283 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); | 283 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); |
| 284 | 284 |
| 285 static TypeHandle Of(i::Object* value, Region* region) { | 285 static TypeHandle Of(i::Object* value, Region* region) { |
| 286 return Config::from_bitset(BitsetType::Lub(value), region); | 286 return Config::from_bitset(BitsetType::Lub(value), region); |
| 287 } | 287 } |
| 288 static TypeHandle Of(i::Handle<i::Object> value, Region* region) { | 288 static TypeHandle Of(i::Handle<i::Object> value, Region* region) { |
| 289 return Of(*value, region); | 289 return Of(*value, region); |
| 290 } | 290 } |
| 291 | 291 |
| 292 bool IsInhabited() { | 292 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); } |
| 293 return !this->IsBitset() || BitsetType::IsInhabited(this->AsBitset()); | |
| 294 } | |
| 295 | 293 |
| 296 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } | 294 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } |
| 297 template<class TypeHandle> | 295 template<class TypeHandle> |
| 298 bool Is(TypeHandle that) { return this->Is(*that); } | 296 bool Is(TypeHandle that) { return this->Is(*that); } |
| 299 | 297 |
| 300 bool Maybe(TypeImpl* that); | 298 bool Maybe(TypeImpl* that); |
| 301 template<class TypeHandle> | 299 template<class TypeHandle> |
| 302 bool Maybe(TypeHandle that) { return this->Maybe(*that); } | 300 bool Maybe(TypeHandle that) { return this->Maybe(*that); } |
| 303 | 301 |
| 304 bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); } | 302 bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 316 return NowOf(*value, region); | 314 return NowOf(*value, region); |
| 317 } | 315 } |
| 318 bool NowIs(TypeImpl* that); | 316 bool NowIs(TypeImpl* that); |
| 319 template<class TypeHandle> | 317 template<class TypeHandle> |
| 320 bool NowIs(TypeHandle that) { return this->NowIs(*that); } | 318 bool NowIs(TypeHandle that) { return this->NowIs(*that); } |
| 321 inline bool NowContains(i::Object* val); | 319 inline bool NowContains(i::Object* val); |
| 322 bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); } | 320 bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); } |
| 323 | 321 |
| 324 bool NowStable(); | 322 bool NowStable(); |
| 325 | 323 |
| 326 bool IsClass() { return Config::is_class(this); } | 324 bool IsClass() { |
| 327 bool IsConstant() { return Config::is_constant(this); } | 325 return Config::is_class(this) |
| 328 bool IsArray() { return Config::is_struct(this, StructuralType::kArrayTag); } | 326 || Config::is_struct(this, StructuralType::kClassTag); |
| 327 } |
| 328 bool IsConstant() { |
| 329 return Config::is_struct(this, StructuralType::kConstantTag); |
| 330 } |
| 331 bool IsArray() { |
| 332 return Config::is_struct(this, StructuralType::kArrayTag); |
| 333 } |
| 329 bool IsFunction() { | 334 bool IsFunction() { |
| 330 return Config::is_struct(this, StructuralType::kFunctionTag); | 335 return Config::is_struct(this, StructuralType::kFunctionTag); |
| 331 } | 336 } |
| 332 | 337 |
| 333 ClassType* AsClass() { return ClassType::cast(this); } | 338 ClassType* AsClass() { return ClassType::cast(this); } |
| 334 ConstantType* AsConstant() { return ConstantType::cast(this); } | 339 ConstantType* AsConstant() { return ConstantType::cast(this); } |
| 335 ArrayType* AsArray() { return ArrayType::cast(this); } | 340 ArrayType* AsArray() { return ArrayType::cast(this); } |
| 336 FunctionType* AsFunction() { return FunctionType::cast(this); } | 341 FunctionType* AsFunction() { return FunctionType::cast(this); } |
| 337 | 342 |
| 338 int NumClasses(); | 343 int NumClasses(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 359 void TypePrint(FILE* out, PrintDimension = BOTH_DIMS); | 364 void TypePrint(FILE* out, PrintDimension = BOTH_DIMS); |
| 360 | 365 |
| 361 protected: | 366 protected: |
| 362 template<class> friend class Iterator; | 367 template<class> friend class Iterator; |
| 363 template<class> friend class TypeImpl; | 368 template<class> friend class TypeImpl; |
| 364 | 369 |
| 365 template<class T> | 370 template<class T> |
| 366 static typename Config::template Handle<T>::type handle(T* type) { | 371 static typename Config::template Handle<T>::type handle(T* type) { |
| 367 return Config::handle(type); | 372 return Config::handle(type); |
| 368 } | 373 } |
| 374 TypeImpl* unhandle() { return this; } |
| 369 | 375 |
| 370 bool IsNone() { return this == None(); } | 376 bool IsNone() { return this == None(); } |
| 371 bool IsAny() { return this == Any(); } | 377 bool IsAny() { return this == Any(); } |
| 372 bool IsBitset() { return Config::is_bitset(this); } | 378 bool IsBitset() { return Config::is_bitset(this); } |
| 373 bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); } | 379 bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); } |
| 374 | 380 |
| 375 int AsBitset() { | 381 int AsBitset() { |
| 376 ASSERT(this->IsBitset()); | 382 ASSERT(this->IsBitset()); |
| 377 return static_cast<BitsetType*>(this)->Bitset(); | 383 return static_cast<BitsetType*>(this)->Bitset(); |
| 378 } | 384 } |
| 379 UnionType* AsUnion() { return UnionType::cast(this); } | 385 UnionType* AsUnion() { return UnionType::cast(this); } |
| 380 | 386 |
| 381 bool SlowIs(TypeImpl* that); | 387 bool SlowIs(TypeImpl* that); |
| 382 | 388 |
| 383 bool InUnion(UnionHandle unioned, int current_size); | 389 TypeHandle Narrow(int bitset, Region* region); |
| 390 int BoundBy(TypeImpl* that); |
| 391 int IndexInUnion(int bound, UnionHandle unioned, int current_size); |
| 384 static int ExtendUnion( | 392 static int ExtendUnion( |
| 385 UnionHandle unioned, TypeHandle t, int current_size); | 393 UnionHandle unioned, int current_size, TypeHandle t, |
| 386 static int ExtendIntersection( | 394 TypeHandle other, bool is_intersect, Region* region); |
| 387 UnionHandle unioned, TypeHandle t, TypeHandle other, int current_size); | 395 static int NormalizeUnion(UnionHandle unioned, int current_size, int bitset); |
| 388 | 396 |
| 389 int BitsetGlb() { return BitsetType::Glb(this); } | 397 int BitsetGlb() { return BitsetType::Glb(this); } |
| 390 int BitsetLub() { return BitsetType::Lub(this); } | 398 int BitsetLub() { return BitsetType::Lub(this); } |
| 399 int InherentBitsetLub() { return BitsetType::InherentLub(this); } |
| 391 }; | 400 }; |
| 392 | 401 |
| 393 | 402 |
| 394 template<class Config> | 403 template<class Config> |
| 395 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { | 404 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { |
| 396 private: | 405 private: |
| 397 friend class TypeImpl<Config>; | 406 friend class TypeImpl<Config>; |
| 398 | 407 |
| 399 enum { | 408 enum { |
| 400 #define DECLARE_TYPE(type, value) k##type = (value), | 409 #define DECLARE_TYPE(type, value) k##type = (value), |
| 401 BITSET_TYPE_LIST(DECLARE_TYPE) | 410 BITSET_TYPE_LIST(DECLARE_TYPE) |
| 402 #undef DECLARE_TYPE | 411 #undef DECLARE_TYPE |
| 403 kUnusedEOL = 0 | 412 kUnusedEOL = 0 |
| 404 }; | 413 }; |
| 405 | 414 |
| 406 int Bitset() { return Config::as_bitset(this); } | 415 int Bitset() { return Config::as_bitset(this); } |
| 407 | 416 |
| 408 static BitsetType* New(int bitset) { | 417 static TypeImpl* New(int bitset) { |
| 409 return static_cast<BitsetType*>(Config::from_bitset(bitset)); | 418 return static_cast<BitsetType*>(Config::from_bitset(bitset)); |
| 410 } | 419 } |
| 411 static TypeHandle New(int bitset, Region* region) { | 420 static TypeHandle New(int bitset, Region* region) { |
| 412 return Config::from_bitset(bitset, region); | 421 return Config::from_bitset(bitset, region); |
| 413 } | 422 } |
| 414 | 423 |
| 415 static bool IsInhabited(int bitset) { | 424 static bool IsInhabited(int bitset) { |
| 416 return (bitset & kRepresentation) && (bitset & kSemantic); | 425 return (bitset & kRepresentation) && (bitset & kSemantic); |
| 417 } | 426 } |
| 418 | 427 |
| 419 static int Glb(TypeImpl* type); // greatest lower bound that's a bitset | 428 static int Glb(TypeImpl* type); // greatest lower bound that's a bitset |
| 420 static int Lub(TypeImpl* type); // least upper bound that's a bitset | 429 static int Lub(TypeImpl* type); // least upper bound that's a bitset |
| 421 static int Lub(i::Object* value); | 430 static int Lub(i::Object* value); |
| 422 static int Lub(i::Map* map); | 431 static int Lub(i::Map* map); |
| 432 static int InherentLub(TypeImpl* type); |
| 423 | 433 |
| 424 static const char* Name(int bitset); | 434 static const char* Name(int bitset); |
| 425 static void BitsetTypePrint(FILE* out, int bitset); | 435 static void BitsetTypePrint(FILE* out, int bitset); |
| 426 }; | 436 }; |
| 427 | 437 |
| 428 | 438 |
| 429 // Internal | 439 // Internal |
| 430 // A structured type contains a tag and a variable number of type fields. | 440 // A structured type contains a tag and a variable number of type fields. |
| 431 template<class Config> | 441 template<class Config> |
| 432 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { | 442 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { |
| 433 protected: | 443 protected: |
| 434 template<class> friend class TypeImpl; | 444 template<class> friend class TypeImpl; |
| 435 friend struct ZoneTypeConfig; // For tags. | 445 friend struct ZoneTypeConfig; // For tags. |
| 436 friend struct HeapTypeConfig; | 446 friend struct HeapTypeConfig; |
| 437 | 447 |
| 438 enum Tag { | 448 enum Tag { |
| 439 kClassTag, | 449 kClassTag, |
| 440 kConstantTag, | 450 kConstantTag, |
| 441 kArrayTag, | 451 kArrayTag, |
| 442 kFunctionTag, | 452 kFunctionTag, |
| 443 kUnionTag | 453 kUnionTag |
| 444 }; | 454 }; |
| 445 | 455 |
| 446 int Length() { | 456 int Length() { |
| 447 return Config::struct_length(Config::as_struct(this)); | 457 return Config::struct_length(Config::as_struct(this)); |
| 448 } | 458 } |
| 449 TypeHandle Get(int i) { | 459 TypeHandle Get(int i) { |
| 460 ASSERT(0 <= i && i < this->Length()); |
| 450 return Config::struct_get(Config::as_struct(this), i); | 461 return Config::struct_get(Config::as_struct(this), i); |
| 451 } | 462 } |
| 452 void Set(int i, TypeHandle type) { | 463 void Set(int i, TypeHandle type) { |
| 464 ASSERT(0 <= i && i < this->Length()); |
| 453 Config::struct_set(Config::as_struct(this), i, type); | 465 Config::struct_set(Config::as_struct(this), i, type); |
| 454 } | 466 } |
| 455 void Shrink(int length) { | 467 void Shrink(int length) { |
| 468 ASSERT(2 <= length && length <= this->Length()); |
| 456 Config::struct_shrink(Config::as_struct(this), length); | 469 Config::struct_shrink(Config::as_struct(this), length); |
| 457 } | 470 } |
| 471 template<class V> i::Handle<V> GetValue(int i) { |
| 472 ASSERT(0 <= i && i < this->Length()); |
| 473 return Config::template struct_get_value<V>(Config::as_struct(this), i); |
| 474 } |
| 475 template<class V> void SetValue(int i, i::Handle<V> x) { |
| 476 ASSERT(0 <= i && i < this->Length()); |
| 477 Config::struct_set_value(Config::as_struct(this), i, x); |
| 478 } |
| 458 | 479 |
| 459 static TypeHandle New(Tag tag, int length, Region* region) { | 480 static TypeHandle New(Tag tag, int length, Region* region) { |
| 481 ASSERT(1 <= length); |
| 460 return Config::from_struct(Config::struct_create(tag, length, region)); | 482 return Config::from_struct(Config::struct_create(tag, length, region)); |
| 461 } | 483 } |
| 462 }; | 484 }; |
| 463 | 485 |
| 464 | 486 |
| 487 // Internal |
| 488 // A union is a structured type with the following invariants: |
| 489 // - its length is at least 2 |
| 490 // - at most one field is a bitset, and it must go into index 0 |
| 491 // - no field is a union |
| 492 // - no field is a subtype of any other field |
| 465 template<class Config> | 493 template<class Config> |
| 466 class TypeImpl<Config>::ClassType : public TypeImpl<Config> { | 494 class TypeImpl<Config>::UnionType : public StructuralType { |
| 467 public: | 495 public: |
| 468 i::Handle<i::Map> Map() { return Config::as_class(this); } | 496 static UnionHandle New(int length, Region* region) { |
| 497 return Config::template cast<UnionType>( |
| 498 StructuralType::New(StructuralType::kUnionTag, length, region)); |
| 499 } |
| 500 |
| 501 static UnionType* cast(TypeImpl* type) { |
| 502 ASSERT(type->IsUnion()); |
| 503 return static_cast<UnionType*>(type); |
| 504 } |
| 505 |
| 506 bool Wellformed(); |
| 507 }; |
| 508 |
| 509 |
| 510 template<class Config> |
| 511 class TypeImpl<Config>::ClassType : public StructuralType { |
| 512 public: |
| 513 TypeHandle Bound(Region* region) { |
| 514 return Config::is_class(this) |
| 515 ? BitsetType::New(BitsetType::Lub(*Config::as_class(this)), region) |
| 516 : this->Get(0); |
| 517 } |
| 518 i::Handle<i::Map> Map() { |
| 519 return Config::is_class(this) |
| 520 ? Config::as_class(this) |
| 521 : this->template GetValue<i::Map>(1); |
| 522 } |
| 523 |
| 524 static ClassHandle New( |
| 525 i::Handle<i::Map> map, TypeHandle bound, Region* region) { |
| 526 ClassHandle type = Config::template cast<ClassType>( |
| 527 StructuralType::New(StructuralType::kClassTag, 2, region)); |
| 528 type->Set(0, bound); |
| 529 type->SetValue(1, map); |
| 530 return type; |
| 531 } |
| 469 | 532 |
| 470 static ClassHandle New(i::Handle<i::Map> map, Region* region) { | 533 static ClassHandle New(i::Handle<i::Map> map, Region* region) { |
| 471 return Config::template cast<ClassType>( | 534 ClassHandle type = |
| 472 Config::from_class(map, BitsetType::Lub(*map), region)); | 535 Config::template cast<ClassType>(Config::from_class(map, region)); |
| 536 if (type->IsClass()) { |
| 537 return type; |
| 538 } else { |
| 539 TypeHandle bound = BitsetType::New(BitsetType::Lub(*map), region); |
| 540 return New(map, bound, region); |
| 541 } |
| 473 } | 542 } |
| 474 | 543 |
| 475 static ClassType* cast(TypeImpl* type) { | 544 static ClassType* cast(TypeImpl* type) { |
| 476 ASSERT(type->IsClass()); | 545 ASSERT(type->IsClass()); |
| 477 return static_cast<ClassType*>(type); | 546 return static_cast<ClassType*>(type); |
| 478 } | 547 } |
| 479 }; | 548 }; |
| 480 | 549 |
| 481 | 550 |
| 482 template<class Config> | 551 template<class Config> |
| 483 class TypeImpl<Config>::ConstantType : public TypeImpl<Config> { | 552 class TypeImpl<Config>::ConstantType : public StructuralType { |
| 484 public: | 553 public: |
| 485 i::Handle<i::Object> Value() { return Config::as_constant(this); } | 554 TypeHandle Bound() { return this->Get(0); } |
| 555 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); } |
| 556 |
| 557 static ConstantHandle New( |
| 558 i::Handle<i::Object> value, TypeHandle bound, Region* region) { |
| 559 ConstantHandle type = Config::template cast<ConstantType>( |
| 560 StructuralType::New(StructuralType::kConstantTag, 2, region)); |
| 561 type->Set(0, bound); |
| 562 type->SetValue(1, value); |
| 563 return type; |
| 564 } |
| 486 | 565 |
| 487 static ConstantHandle New(i::Handle<i::Object> value, Region* region) { | 566 static ConstantHandle New(i::Handle<i::Object> value, Region* region) { |
| 488 return Config::template cast<ConstantType>( | 567 TypeHandle bound = BitsetType::New(BitsetType::Lub(*value), region); |
| 489 Config::from_constant(value, BitsetType::Lub(*value), region)); | 568 return New(value, bound, region); |
| 490 } | 569 } |
| 491 | 570 |
| 492 static ConstantType* cast(TypeImpl* type) { | 571 static ConstantType* cast(TypeImpl* type) { |
| 493 ASSERT(type->IsConstant()); | 572 ASSERT(type->IsConstant()); |
| 494 return static_cast<ConstantType*>(type); | 573 return static_cast<ConstantType*>(type); |
| 495 } | 574 } |
| 496 }; | 575 }; |
| 497 | 576 |
| 498 | 577 |
| 499 // Internal | |
| 500 // A union is a structured type with the following invariants: | |
| 501 // - its length is at least 2 | |
| 502 // - at most one field is a bitset, and it must go into index 0 | |
| 503 // - no field is a union | |
| 504 template<class Config> | |
| 505 class TypeImpl<Config>::UnionType : public StructuralType { | |
| 506 public: | |
| 507 static UnionHandle New(int length, Region* region) { | |
| 508 return Config::template cast<UnionType>( | |
| 509 StructuralType::New(StructuralType::kUnionTag, length, region)); | |
| 510 } | |
| 511 | |
| 512 static UnionType* cast(TypeImpl* type) { | |
| 513 ASSERT(type->IsUnion()); | |
| 514 return static_cast<UnionType*>(type); | |
| 515 } | |
| 516 }; | |
| 517 | |
| 518 | |
| 519 template<class Config> | 578 template<class Config> |
| 520 class TypeImpl<Config>::ArrayType : public StructuralType { | 579 class TypeImpl<Config>::ArrayType : public StructuralType { |
| 521 public: | 580 public: |
| 522 TypeHandle Element() { return this->Get(0); } | 581 TypeHandle Bound() { return this->Get(0); } |
| 582 TypeHandle Element() { return this->Get(1); } |
| 583 |
| 584 static ArrayHandle New(TypeHandle element, TypeHandle bound, Region* region) { |
| 585 ASSERT(SEMANTIC(bound->AsBitset()) == SEMANTIC(BitsetType::kArray)); |
| 586 ArrayHandle type = Config::template cast<ArrayType>( |
| 587 StructuralType::New(StructuralType::kArrayTag, 2, region)); |
| 588 type->Set(0, bound); |
| 589 type->Set(1, element); |
| 590 return type; |
| 591 } |
| 523 | 592 |
| 524 static ArrayHandle New(TypeHandle element, Region* region) { | 593 static ArrayHandle New(TypeHandle element, Region* region) { |
| 525 ArrayHandle type = Config::template cast<ArrayType>( | 594 TypeHandle bound = BitsetType::New(BitsetType::kArray, region); |
| 526 StructuralType::New(StructuralType::kArrayTag, 1, region)); | 595 return New(element, bound, region); |
| 527 type->Set(0, element); | |
| 528 return type; | |
| 529 } | 596 } |
| 530 | 597 |
| 531 static ArrayType* cast(TypeImpl* type) { | 598 static ArrayType* cast(TypeImpl* type) { |
| 532 ASSERT(type->IsArray()); | 599 ASSERT(type->IsArray()); |
| 533 return static_cast<ArrayType*>(type); | 600 return static_cast<ArrayType*>(type); |
| 534 } | 601 } |
| 535 }; | 602 }; |
| 536 | 603 |
| 537 | 604 |
| 538 template<class Config> | 605 template<class Config> |
| 539 class TypeImpl<Config>::FunctionType : public StructuralType { | 606 class TypeImpl<Config>::FunctionType : public StructuralType { |
| 540 public: | 607 public: |
| 541 int Arity() { return this->Length() - 2; } | 608 int Arity() { return this->Length() - 3; } |
| 542 TypeHandle Result() { return this->Get(0); } | 609 TypeHandle Bound() { return this->Get(0); } |
| 543 TypeHandle Receiver() { return this->Get(1); } | 610 TypeHandle Result() { return this->Get(1); } |
| 544 TypeHandle Parameter(int i) { return this->Get(2 + i); } | 611 TypeHandle Receiver() { return this->Get(2); } |
| 612 TypeHandle Parameter(int i) { return this->Get(3 + i); } |
| 545 | 613 |
| 546 void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); } | 614 void InitParameter(int i, TypeHandle type) { this->Set(3 + i, type); } |
| 615 |
| 616 static FunctionHandle New( |
| 617 TypeHandle result, TypeHandle receiver, TypeHandle bound, |
| 618 int arity, Region* region) { |
| 619 ASSERT(SEMANTIC(bound->AsBitset()) == SEMANTIC(BitsetType::kFunction)); |
| 620 FunctionHandle type = Config::template cast<FunctionType>( |
| 621 StructuralType::New(StructuralType::kFunctionTag, 3 + arity, region)); |
| 622 type->Set(0, bound); |
| 623 type->Set(1, result); |
| 624 type->Set(2, receiver); |
| 625 return type; |
| 626 } |
| 547 | 627 |
| 548 static FunctionHandle New( | 628 static FunctionHandle New( |
| 549 TypeHandle result, TypeHandle receiver, int arity, Region* region) { | 629 TypeHandle result, TypeHandle receiver, int arity, Region* region) { |
| 550 FunctionHandle type = Config::template cast<FunctionType>( | 630 TypeHandle bound = BitsetType::New(BitsetType::kFunction, region); |
| 551 StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region)); | 631 return New(result, receiver, bound, arity, region); |
| 552 type->Set(0, result); | |
| 553 type->Set(1, receiver); | |
| 554 return type; | |
| 555 } | 632 } |
| 556 | 633 |
| 557 static FunctionType* cast(TypeImpl* type) { | 634 static FunctionType* cast(TypeImpl* type) { |
| 558 ASSERT(type->IsFunction()); | 635 ASSERT(type->IsFunction()); |
| 559 return static_cast<FunctionType*>(type); | 636 return static_cast<FunctionType*>(type); |
| 560 } | 637 } |
| 561 }; | 638 }; |
| 562 | 639 |
| 563 | 640 |
| 564 template<class Config> template<class T> | 641 template<class Config> template<class T> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 591 class Base {}; | 668 class Base {}; |
| 592 typedef void* Struct; | 669 typedef void* Struct; |
| 593 typedef i::Zone Region; | 670 typedef i::Zone Region; |
| 594 template<class T> struct Handle { typedef T* type; }; | 671 template<class T> struct Handle { typedef T* type; }; |
| 595 | 672 |
| 596 template<class T> static inline T* handle(T* type); | 673 template<class T> static inline T* handle(T* type); |
| 597 template<class T> static inline T* cast(Type* type); | 674 template<class T> static inline T* cast(Type* type); |
| 598 | 675 |
| 599 static inline bool is_bitset(Type* type); | 676 static inline bool is_bitset(Type* type); |
| 600 static inline bool is_class(Type* type); | 677 static inline bool is_class(Type* type); |
| 601 static inline bool is_constant(Type* type); | |
| 602 static inline bool is_struct(Type* type, int tag); | 678 static inline bool is_struct(Type* type, int tag); |
| 603 | 679 |
| 604 static inline int as_bitset(Type* type); | 680 static inline int as_bitset(Type* type); |
| 681 static inline i::Handle<i::Map> as_class(Type* type); |
| 605 static inline Struct* as_struct(Type* type); | 682 static inline Struct* as_struct(Type* type); |
| 606 static inline i::Handle<i::Map> as_class(Type* type); | |
| 607 static inline i::Handle<i::Object> as_constant(Type* type); | |
| 608 | 683 |
| 609 static inline Type* from_bitset(int bitset); | 684 static inline Type* from_bitset(int bitset); |
| 610 static inline Type* from_bitset(int bitset, Zone* zone); | 685 static inline Type* from_bitset(int bitset, Zone* zone); |
| 686 static inline Type* from_class(i::Handle<i::Map> map, Zone* zone); |
| 611 static inline Type* from_struct(Struct* structured); | 687 static inline Type* from_struct(Struct* structured); |
| 612 static inline Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone); | |
| 613 static inline Type* from_constant( | |
| 614 i::Handle<i::Object> value, int lub, Zone* zone); | |
| 615 | 688 |
| 616 static inline Struct* struct_create(int tag, int length, Zone* zone); | 689 static inline Struct* struct_create(int tag, int length, Zone* zone); |
| 617 static inline void struct_shrink(Struct* structured, int length); | 690 static inline void struct_shrink(Struct* structure, int length); |
| 618 static inline int struct_tag(Struct* structured); | 691 static inline int struct_tag(Struct* structure); |
| 619 static inline int struct_length(Struct* structured); | 692 static inline int struct_length(Struct* structure); |
| 620 static inline Type* struct_get(Struct* structured, int i); | 693 static inline Type* struct_get(Struct* structure, int i); |
| 621 static inline void struct_set(Struct* structured, int i, Type* type); | 694 static inline void struct_set(Struct* structure, int i, Type* type); |
| 622 | 695 template<class V> |
| 623 static inline int lub_bitset(Type* type); | 696 static inline i::Handle<V> struct_get_value(Struct* structure, int i); |
| 697 template<class V> static inline void struct_set_value( |
| 698 Struct* structure, int i, i::Handle<V> x); |
| 624 }; | 699 }; |
| 625 | 700 |
| 626 typedef TypeImpl<ZoneTypeConfig> Type; | 701 typedef TypeImpl<ZoneTypeConfig> Type; |
| 627 | 702 |
| 628 | 703 |
| 629 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for | 704 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for |
| 630 // constants, or fixed arrays for unions. | 705 // constants, or fixed arrays for unions. |
| 631 struct HeapTypeConfig { | 706 struct HeapTypeConfig { |
| 632 typedef TypeImpl<HeapTypeConfig> Type; | 707 typedef TypeImpl<HeapTypeConfig> Type; |
| 633 typedef i::Object Base; | 708 typedef i::Object Base; |
| 634 typedef i::FixedArray Struct; | 709 typedef i::FixedArray Struct; |
| 635 typedef i::Isolate Region; | 710 typedef i::Isolate Region; |
| 636 template<class T> struct Handle { typedef i::Handle<T> type; }; | 711 template<class T> struct Handle { typedef i::Handle<T> type; }; |
| 637 | 712 |
| 638 template<class T> static inline i::Handle<T> handle(T* type); | 713 template<class T> static inline i::Handle<T> handle(T* type); |
| 639 template<class T> static inline i::Handle<T> cast(i::Handle<Type> type); | 714 template<class T> static inline i::Handle<T> cast(i::Handle<Type> type); |
| 640 | 715 |
| 641 static inline bool is_bitset(Type* type); | 716 static inline bool is_bitset(Type* type); |
| 642 static inline bool is_class(Type* type); | 717 static inline bool is_class(Type* type); |
| 643 static inline bool is_constant(Type* type); | |
| 644 static inline bool is_struct(Type* type, int tag); | 718 static inline bool is_struct(Type* type, int tag); |
| 645 | 719 |
| 646 static inline int as_bitset(Type* type); | 720 static inline int as_bitset(Type* type); |
| 647 static inline i::Handle<i::Map> as_class(Type* type); | 721 static inline i::Handle<i::Map> as_class(Type* type); |
| 648 static inline i::Handle<i::Object> as_constant(Type* type); | |
| 649 static inline i::Handle<Struct> as_struct(Type* type); | 722 static inline i::Handle<Struct> as_struct(Type* type); |
| 650 | 723 |
| 651 static inline Type* from_bitset(int bitset); | 724 static inline Type* from_bitset(int bitset); |
| 652 static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate); | 725 static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate); |
| 653 static inline i::Handle<Type> from_class( | 726 static inline i::Handle<Type> from_class( |
| 654 i::Handle<i::Map> map, int lub, Isolate* isolate); | 727 i::Handle<i::Map> map, Isolate* isolate); |
| 655 static inline i::Handle<Type> from_constant( | 728 static inline i::Handle<Type> from_struct(i::Handle<Struct> structure); |
| 656 i::Handle<i::Object> value, int lub, Isolate* isolate); | |
| 657 static inline i::Handle<Type> from_struct(i::Handle<Struct> structured); | |
| 658 | 729 |
| 659 static inline i::Handle<Struct> struct_create( | 730 static inline i::Handle<Struct> struct_create( |
| 660 int tag, int length, Isolate* isolate); | 731 int tag, int length, Isolate* isolate); |
| 661 static inline void struct_shrink(i::Handle<Struct> structured, int length); | 732 static inline void struct_shrink(i::Handle<Struct> structure, int length); |
| 662 static inline int struct_tag(i::Handle<Struct> structured); | 733 static inline int struct_tag(i::Handle<Struct> structure); |
| 663 static inline int struct_length(i::Handle<Struct> structured); | 734 static inline int struct_length(i::Handle<Struct> structure); |
| 664 static inline i::Handle<Type> struct_get(i::Handle<Struct> structured, int i); | 735 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); |
| 665 static inline void struct_set( | 736 static inline void struct_set( |
| 666 i::Handle<Struct> structured, int i, i::Handle<Type> type); | 737 i::Handle<Struct> structure, int i, i::Handle<Type> type); |
| 667 | 738 template<class V> |
| 668 static inline int lub_bitset(Type* type); | 739 static inline i::Handle<V> struct_get_value( |
| 740 i::Handle<Struct> structure, int i); |
| 741 template<class V> |
| 742 static inline void struct_set_value( |
| 743 i::Handle<Struct> structure, int i, i::Handle<V> x); |
| 669 }; | 744 }; |
| 670 | 745 |
| 671 typedef TypeImpl<HeapTypeConfig> HeapType; | 746 typedef TypeImpl<HeapTypeConfig> HeapType; |
| 672 | 747 |
| 673 | 748 |
| 674 // A simple struct to represent a pair of lower/upper type bounds. | 749 // A simple struct to represent a pair of lower/upper type bounds. |
| 675 template<class Config> | 750 template<class Config> |
| 676 struct BoundsImpl { | 751 struct BoundsImpl { |
| 677 typedef TypeImpl<Config> Type; | 752 typedef TypeImpl<Config> Type; |
| 678 typedef typename Type::TypeHandle TypeHandle; | 753 typedef typename Type::TypeHandle TypeHandle; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 bool Narrows(BoundsImpl that) { | 798 bool Narrows(BoundsImpl that) { |
| 724 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 799 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
| 725 } | 800 } |
| 726 }; | 801 }; |
| 727 | 802 |
| 728 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 803 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
| 729 | 804 |
| 730 } } // namespace v8::internal | 805 } } // namespace v8::internal |
| 731 | 806 |
| 732 #endif // V8_TYPES_H_ | 807 #endif // V8_TYPES_H_ |
| OLD | NEW |