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 |