Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: src/types.h

Issue 1655833002: Remove the template magic from types.(h|cc), remove types-inl.h. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Undo whitespace change Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/type-info.cc ('k') | src/types.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/handles.h" 9 #include "src/handles.h"
10 #include "src/objects.h" 10 #include "src/objects.h"
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 #define PROPER_BITSET_TYPE_LIST(V) \ 252 #define PROPER_BITSET_TYPE_LIST(V) \
253 REPRESENTATION_BITSET_TYPE_LIST(V) \ 253 REPRESENTATION_BITSET_TYPE_LIST(V) \
254 SEMANTIC_BITSET_TYPE_LIST(V) 254 SEMANTIC_BITSET_TYPE_LIST(V)
255 255
256 #define BITSET_TYPE_LIST(V) \ 256 #define BITSET_TYPE_LIST(V) \
257 MASK_BITSET_TYPE_LIST(V) \ 257 MASK_BITSET_TYPE_LIST(V) \
258 REPRESENTATION_BITSET_TYPE_LIST(V) \ 258 REPRESENTATION_BITSET_TYPE_LIST(V) \
259 INTERNAL_BITSET_TYPE_LIST(V) \ 259 INTERNAL_BITSET_TYPE_LIST(V) \
260 SEMANTIC_BITSET_TYPE_LIST(V) 260 SEMANTIC_BITSET_TYPE_LIST(V)
261 261
262 class Type;
262 263
263 // ----------------------------------------------------------------------------- 264 // -----------------------------------------------------------------------------
264 // The abstract Type class, parameterized over the low-level representation. 265 // Bitset types (internal).
265 266
266 // struct Config { 267 class BitsetType {
267 // typedef TypeImpl<Config> Type;
268 // typedef Base;
269 // typedef Struct;
270 // typedef Range;
271 // typedef Region;
272 // template<class> struct Handle { typedef type; } // No template typedefs...
273 //
274 // template<class T> static Handle<T>::type null_handle();
275 // template<class T> static Handle<T>::type handle(T* t); // !is_bitset(t)
276 // template<class T> static Handle<T>::type cast(Handle<Type>::type);
277 //
278 // static bool is_bitset(Type*);
279 // static bool is_class(Type*);
280 // static bool is_struct(Type*, int tag);
281 // static bool is_range(Type*);
282 //
283 // static bitset as_bitset(Type*);
284 // static i::Handle<i::Map> as_class(Type*);
285 // static Handle<Struct>::type as_struct(Type*);
286 // static Handle<Range>::type as_range(Type*);
287 //
288 // static Type* from_bitset(bitset);
289 // static Handle<Type>::type from_bitset(bitset, Region*);
290 // static Handle<Type>::type from_class(i::Handle<Map>, Region*);
291 // static Handle<Type>::type from_struct(Handle<Struct>::type, int tag);
292 // static Handle<Type>::type from_range(Handle<Range>::type);
293 //
294 // static Handle<Struct>::type struct_create(int tag, int length, Region*);
295 // static void struct_shrink(Handle<Struct>::type, int length);
296 // static int struct_tag(Handle<Struct>::type);
297 // static int struct_length(Handle<Struct>::type);
298 // static Handle<Type>::type struct_get(Handle<Struct>::type, int);
299 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type);
300 // template<class V>
301 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int);
302 // template<class V>
303 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>);
304 //
305 // static Handle<Range>::type range_create(Region*);
306 // static int range_get_bitset(Handle<Range>::type);
307 // static void range_set_bitset(Handle<Range>::type, int);
308 // static double range_get_double(Handle<Range>::type, int);
309 // static void range_set_double(Handle<Range>::type, int, double, Region*);
310 // }
311 template<class Config>
312 class TypeImpl : public Config::Base {
313 public: 268 public:
314 // Auxiliary types. 269 typedef uint32_t bitset; // Internal
315 270
316 typedef uint32_t bitset; // Internal 271 enum : uint32_t {
317 class BitsetType; // Internal 272 #define DECLARE_TYPE(type, value) k##type = (value),
318 class StructuralType; // Internal 273 BITSET_TYPE_LIST(DECLARE_TYPE)
319 class UnionType; // Internal 274 #undef DECLARE_TYPE
275 kUnusedEOL = 0
276 };
320 277
321 class ClassType; 278 static bitset SignedSmall();
322 class ConstantType; 279 static bitset UnsignedSmall();
323 class RangeType;
324 class ContextType;
325 class ArrayType;
326 class FunctionType;
327 class TupleType;
328 280
329 typedef typename Config::template Handle<TypeImpl>::type TypeHandle; 281 bitset Bitset() {
330 typedef typename Config::template Handle<ClassType>::type ClassHandle; 282 return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
331 typedef typename Config::template Handle<ConstantType>::type ConstantHandle;
332 typedef typename Config::template Handle<RangeType>::type RangeHandle;
333 typedef typename Config::template Handle<ContextType>::type ContextHandle;
334 typedef typename Config::template Handle<ArrayType>::type ArrayHandle;
335 typedef typename Config::template Handle<FunctionType>::type FunctionHandle;
336 typedef typename Config::template Handle<UnionType>::type UnionHandle;
337 typedef typename Config::template Handle<TupleType>::type TupleHandle;
338 typedef typename Config::Region Region;
339
340 // Constructors.
341
342 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
343 static TypeImpl* type() { \
344 return BitsetType::New(BitsetType::k##type); \
345 } \
346 static TypeHandle type(Region* region) { \
347 return BitsetType::New(BitsetType::k##type, region); \
348 }
349 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
350 #undef DEFINE_TYPE_CONSTRUCTOR
351
352 static TypeImpl* SignedSmall() {
353 return BitsetType::New(BitsetType::SignedSmall());
354 }
355 static TypeHandle SignedSmall(Region* region) {
356 return BitsetType::New(BitsetType::SignedSmall(), region);
357 }
358 static TypeImpl* UnsignedSmall() {
359 return BitsetType::New(BitsetType::UnsignedSmall());
360 }
361 static TypeHandle UnsignedSmall(Region* region) {
362 return BitsetType::New(BitsetType::UnsignedSmall(), region);
363 } 283 }
364 284
365 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { 285 static bool IsInhabited(bitset bits) {
366 return ClassType::New(map, region); 286 return SEMANTIC(bits) != kNone && REPRESENTATION(bits) != kNone;
367 }
368 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
369 return ConstantType::New(value, region);
370 }
371 static TypeHandle Range(double min, double max, Region* region) {
372 return RangeType::New(
373 min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged |
374 BitsetType::kUntaggedNumber),
375 region),
376 region);
377 }
378 static TypeHandle Context(TypeHandle outer, Region* region) {
379 return ContextType::New(outer, region);
380 }
381 static TypeHandle Array(TypeHandle element, Region* region) {
382 return ArrayType::New(element, region);
383 }
384 static FunctionHandle Function(
385 TypeHandle result, TypeHandle receiver, int arity, Region* region) {
386 return FunctionType::New(result, receiver, arity, region);
387 }
388 static TypeHandle Function(TypeHandle result, Region* region) {
389 return Function(result, Any(region), 0, region);
390 }
391 static TypeHandle Function(
392 TypeHandle result, TypeHandle param0, Region* region) {
393 FunctionHandle function = Function(result, Any(region), 1, region);
394 function->InitParameter(0, param0);
395 return function;
396 }
397 static TypeHandle Function(
398 TypeHandle result, TypeHandle param0, TypeHandle param1, Region* region) {
399 FunctionHandle function = Function(result, Any(region), 2, region);
400 function->InitParameter(0, param0);
401 function->InitParameter(1, param1);
402 return function;
403 }
404 static TypeHandle Function(
405 TypeHandle result, TypeHandle param0, TypeHandle param1,
406 TypeHandle param2, Region* region) {
407 FunctionHandle function = Function(result, Any(region), 3, region);
408 function->InitParameter(0, param0);
409 function->InitParameter(1, param1);
410 function->InitParameter(2, param2);
411 return function;
412 }
413 static TypeHandle Function(TypeHandle result, int arity, TypeHandle* params,
414 Region* region) {
415 FunctionHandle function = Function(result, Any(region), arity, region);
416 for (int i = 0; i < arity; ++i) {
417 function->InitParameter(i, params[i]);
418 }
419 return function;
420 }
421 static TypeHandle Tuple(TypeHandle first, TypeHandle second, TypeHandle third,
422 Region* region) {
423 TupleHandle tuple = TupleType::New(3, region);
424 tuple->InitElement(0, first);
425 tuple->InitElement(1, second);
426 tuple->InitElement(2, third);
427 return tuple;
428 } 287 }
429 288
430 #define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \ 289 static bool SemanticIsInhabited(bitset bits) {
431 static TypeHandle Name(Isolate* isolate, Region* region); 290 return SEMANTIC(bits) != kNone;
432 SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
433 #undef CONSTRUCT_SIMD_TYPE
434
435 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
436 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
437
438 static TypeHandle Of(double value, Region* region) {
439 return Config::from_bitset(BitsetType::ExpandInternals(
440 BitsetType::Lub(value)), region);
441 }
442 static TypeHandle Of(i::Object* value, Region* region) {
443 return Config::from_bitset(BitsetType::ExpandInternals(
444 BitsetType::Lub(value)), region);
445 }
446 static TypeHandle Of(i::Handle<i::Object> value, Region* region) {
447 return Of(*value, region);
448 } 291 }
449 292
450 // Extraction of components. 293 static bool Is(bitset bits1, bitset bits2) {
451 static TypeHandle Representation(TypeHandle t, Region* region); 294 return (bits1 | bits2) == bits2;
452 static TypeHandle Semantic(TypeHandle t, Region* region);
453
454 // Predicates.
455 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
456
457 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
458 template<class TypeHandle>
459 bool Is(TypeHandle that) { return this->Is(*that); }
460
461 bool Maybe(TypeImpl* that);
462 template<class TypeHandle>
463 bool Maybe(TypeHandle that) { return this->Maybe(*that); }
464
465 bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); }
466 template<class TypeHandle>
467 bool Equals(TypeHandle that) { return this->Equals(*that); }
468
469 // Equivalent to Constant(val)->Is(this), but avoiding allocation.
470 bool Contains(i::Object* val);
471 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
472
473 // State-dependent versions of the above that consider subtyping between
474 // a constant and its map class.
475 inline static TypeHandle NowOf(i::Object* value, Region* region);
476 static TypeHandle NowOf(i::Handle<i::Object> value, Region* region) {
477 return NowOf(*value, region);
478 }
479 bool NowIs(TypeImpl* that);
480 template<class TypeHandle>
481 bool NowIs(TypeHandle that) { return this->NowIs(*that); }
482 inline bool NowContains(i::Object* val);
483 bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
484
485 bool NowStable();
486
487 // Inspection.
488
489 bool IsRange() { return Config::is_range(this); }
490 bool IsClass() {
491 return Config::is_class(this)
492 || Config::is_struct(this, StructuralType::kClassTag);
493 }
494 bool IsConstant() {
495 return Config::is_struct(this, StructuralType::kConstantTag);
496 }
497 bool IsContext() {
498 return Config::is_struct(this, StructuralType::kContextTag);
499 }
500 bool IsArray() {
501 return Config::is_struct(this, StructuralType::kArrayTag);
502 }
503 bool IsFunction() {
504 return Config::is_struct(this, StructuralType::kFunctionTag);
505 }
506 bool IsTuple() { return Config::is_struct(this, StructuralType::kTupleTag); }
507
508 ClassType* AsClass() { return ClassType::cast(this); }
509 ConstantType* AsConstant() { return ConstantType::cast(this); }
510 RangeType* AsRange() { return RangeType::cast(this); }
511 ContextType* AsContext() { return ContextType::cast(this); }
512 ArrayType* AsArray() { return ArrayType::cast(this); }
513 FunctionType* AsFunction() { return FunctionType::cast(this); }
514 TupleType* AsTuple() { return TupleType::cast(this); }
515
516 // Minimum and maximum of a numeric type.
517 // These functions do not distinguish between -0 and +0. If the type equals
518 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these
519 // functions on subtypes of Number.
520 double Min();
521 double Max();
522
523 // Extracts a range from the type: if the type is a range or a union
524 // containing a range, that range is returned; otherwise, NULL is returned.
525 RangeType* GetRange();
526
527 static bool IsInteger(double x) {
528 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
529 }
530 static bool IsInteger(i::Object* x) {
531 return x->IsNumber() && IsInteger(x->Number());
532 } 295 }
533 296
534 int NumClasses(); 297 static double Min(bitset);
535 int NumConstants(); 298 static double Max(bitset);
536 299
537 template<class T> class Iterator; 300 static bitset Glb(Type* type); // greatest lower bound that's a bitset
538 Iterator<i::Map> Classes() { 301 static bitset Glb(double min, double max);
539 if (this->IsBitset()) return Iterator<i::Map>(); 302 static bitset Lub(Type* type); // least upper bound that's a bitset
540 return Iterator<i::Map>(Config::handle(this)); 303 static bitset Lub(i::Map* map);
541 } 304 static bitset Lub(i::Object* value);
542 Iterator<i::Object> Constants() { 305 static bitset Lub(double value);
543 if (this->IsBitset()) return Iterator<i::Object>(); 306 static bitset Lub(double min, double max);
544 return Iterator<i::Object>(Config::handle(this)); 307 static bitset ExpandInternals(bitset bits);
308
309 static const char* Name(bitset);
310 static void Print(std::ostream& os, bitset); // NOLINT
311 #ifdef DEBUG
312 static void Print(bitset);
313 #endif
314
315 static bitset NumberBits(bitset bits);
316
317 static bool IsBitset(Type* type) {
318 return reinterpret_cast<uintptr_t>(type) & 1;
545 } 319 }
546 320
547 // Casting and conversion. 321 static Type* NewForTesting(bitset bits) { return New(bits); }
548 322
549 static inline TypeImpl* cast(typename Config::Base* object); 323 private:
324 friend class Type;
550 325
551 // Printing. 326 static Type* New(bitset bits) {
327 return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u));
328 }
552 329
553 enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM }; 330 struct Boundary {
331 bitset internal;
332 bitset external;
333 double min;
334 };
335 static const Boundary BoundariesArray[];
336 static inline const Boundary* Boundaries();
337 static inline size_t BoundariesSize();
338 };
554 339
555 void PrintTo(std::ostream& os, PrintDimension dim = BOTH_DIMS); // NOLINT 340 // -----------------------------------------------------------------------------
341 // Superclass for non-bitset types (internal).
342 class TypeBase {
343 protected:
344 friend class Type;
556 345
557 #ifdef DEBUG 346 enum Kind {
558 void Print(); 347 kClass,
559 #endif 348 kConstant,
349 kContext,
350 kArray,
351 kFunction,
352 kTuple,
353 kUnion,
354 kRange
355 };
560 356
561 bool IsUnionForTesting() { return IsUnion(); } 357 Kind kind() const { return kind_; }
358 explicit TypeBase(Kind kind) : kind_(kind) {}
562 359
563 protected: 360 static bool IsKind(Type* type, Kind kind) {
564 // Friends. 361 if (BitsetType::IsBitset(type)) return false;
362 TypeBase* base = reinterpret_cast<TypeBase*>(type);
363 return base->kind() == kind;
364 }
565 365
566 template<class> friend class Iterator; 366 // The hacky conversion to/from Type*.
567 template<class> friend class TypeImpl; 367 static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); }
368 static TypeBase* FromType(Type* type) {
369 return reinterpret_cast<TypeBase*>(type);
370 }
568 371
569 // Handle conversion. 372 private:
373 Kind kind_;
374 };
570 375
571 template<class T> 376 // -----------------------------------------------------------------------------
572 static typename Config::template Handle<T>::type handle(T* type) { 377 // Class types.
573 return Config::handle(type); 378
379 class ClassType : public TypeBase {
380 public:
381 i::Handle<i::Map> Map() { return map_; }
382
383 private:
384 friend class Type;
385 friend class BitsetType;
386
387 static Type* New(i::Handle<i::Map> map, Zone* zone) {
388 return AsType(new (zone->New(sizeof(ClassType)))
389 ClassType(BitsetType::Lub(*map), map));
574 } 390 }
575 TypeImpl* unhandle() { return this; }
576 391
577 // Internal inspection. 392 static ClassType* cast(Type* type) {
393 DCHECK(IsKind(type, kClass));
394 return static_cast<ClassType*>(FromType(type));
395 }
578 396
579 bool IsNone() { return this == None(); } 397 ClassType(BitsetType::bitset bitset, i::Handle<i::Map> map)
580 bool IsAny() { return this == Any(); } 398 : TypeBase(kClass), bitset_(bitset), map_(map) {}
581 bool IsBitset() { return Config::is_bitset(this); }
582 bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); }
583 399
584 bitset AsBitset() { 400 BitsetType::bitset Lub() { return bitset_; }
585 DCHECK(this->IsBitset()); 401
586 return static_cast<BitsetType*>(this)->Bitset(); 402 BitsetType::bitset bitset_;
403 Handle<i::Map> map_;
404 };
405
406 // -----------------------------------------------------------------------------
407 // Constant types.
408
409 class ConstantType : public TypeBase {
410 public:
411 i::Handle<i::Object> Value() { return object_; }
412
413 private:
414 friend class Type;
415 friend class BitsetType;
416
417 static Type* New(i::Handle<i::Object> value, Zone* zone) {
418 BitsetType::bitset bitset = BitsetType::Lub(*value);
419 return AsType(new (zone->New(sizeof(ConstantType)))
420 ConstantType(bitset, value));
587 } 421 }
588 UnionType* AsUnion() { return UnionType::cast(this); }
589 422
590 bitset Representation(); 423 static ConstantType* cast(Type* type) {
424 DCHECK(IsKind(type, kConstant));
425 return static_cast<ConstantType*>(FromType(type));
426 }
591 427
592 // Auxiliary functions. 428 ConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object)
593 bool SemanticMaybe(TypeImpl* that); 429 : TypeBase(kConstant), bitset_(bitset), object_(object) {}
594 430
595 bitset BitsetGlb() { return BitsetType::Glb(this); } 431 BitsetType::bitset Lub() { return bitset_; }
596 bitset BitsetLub() { return BitsetType::Lub(this); }
597 432
598 bool SlowIs(TypeImpl* that); 433 BitsetType::bitset bitset_;
599 bool SemanticIs(TypeImpl* that); 434 Handle<i::Object> object_;
435 };
436 // TODO(neis): Also cache value if numerical.
437 // TODO(neis): Allow restricting the representation.
600 438
439 // -----------------------------------------------------------------------------
440 // Range types.
441
442 class RangeType : public TypeBase {
443 public:
601 struct Limits { 444 struct Limits {
602 double min; 445 double min;
603 double max; 446 double max;
604 Limits(double min, double max) : min(min), max(max) {} 447 Limits(double min, double max) : min(min), max(max) {}
605 explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {} 448 explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
606 bool IsEmpty(); 449 bool IsEmpty();
607 static Limits Empty() { return Limits(1, 0); } 450 static Limits Empty() { return Limits(1, 0); }
608 static Limits Intersect(Limits lhs, Limits rhs); 451 static Limits Intersect(Limits lhs, Limits rhs);
609 static Limits Union(Limits lhs, Limits rhs); 452 static Limits Union(Limits lhs, Limits rhs);
610 }; 453 };
611 454
612 static bool Overlap(RangeType* lhs, RangeType* rhs); 455 double Min() { return limits_.min; }
613 static bool Contains(RangeType* lhs, RangeType* rhs); 456 double Max() { return limits_.max; }
614 static bool Contains(RangeType* range, ConstantType* constant);
615 static bool Contains(RangeType* range, i::Object* val);
616 457
617 static int UpdateRange( 458 private:
618 RangeHandle type, UnionHandle result, int size, Region* region); 459 friend class Type;
460 friend class BitsetType;
461 friend class UnionType;
619 462
620 static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits, 463 static Type* New(double min, double max, BitsetType::bitset representation,
621 Region* region); 464 Zone* zone) {
622 static Limits ToLimits(bitset bits, Region* region); 465 return New(Limits(min, max), representation, zone);
466 }
623 467
624 bool SimplyEquals(TypeImpl* that); 468 static bool IsInteger(double x) {
625 template<class TypeHandle> 469 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
626 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } 470 }
627 471
628 static int AddToUnion( 472 static Type* New(Limits lim, BitsetType::bitset representation, Zone* zone) {
629 TypeHandle type, UnionHandle result, int size, Region* region); 473 DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
630 static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result, 474 DCHECK(lim.min <= lim.max);
631 int size, Limits* limits, Region* region); 475 DCHECK(REPRESENTATION(representation) == representation);
632 static TypeHandle NormalizeUnion(UnionHandle unioned, int size, 476 BitsetType::bitset bits =
633 Region* region); 477 SEMANTIC(BitsetType::Lub(lim.min, lim.max)) | representation;
634 static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits, 478
635 Region* region); 479 return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
480 }
481
482 static RangeType* cast(Type* type) {
483 DCHECK(IsKind(type, kRange));
484 return static_cast<RangeType*>(FromType(type));
485 }
486
487 RangeType(BitsetType::bitset bitset, Limits limits)
488 : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
489
490 BitsetType::bitset Lub() { return bitset_; }
491
492 BitsetType::bitset bitset_;
493 Limits limits_;
636 }; 494 };
637 495
496 // -----------------------------------------------------------------------------
497 // Context types.
498
499 class ContextType : public TypeBase {
500 public:
501 Type* Outer() { return outer_; }
502
503 private:
504 friend class Type;
505
506 static Type* New(Type* outer, Zone* zone) {
507 return AsType(new (zone->New(sizeof(ContextType))) ContextType(outer));
508 }
509
510 static ContextType* cast(Type* type) {
511 DCHECK(IsKind(type, kContext));
512 return static_cast<ContextType*>(FromType(type));
513 }
514
515 explicit ContextType(Type* outer) : TypeBase(kContext), outer_(outer) {}
516
517 Type* outer_;
518 };
638 519
639 // ----------------------------------------------------------------------------- 520 // -----------------------------------------------------------------------------
640 // Bitset types (internal). 521 // Array types.
641 522
642 template<class Config> 523 class ArrayType : public TypeBase {
643 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { 524 public:
644 protected: 525 Type* Element() { return element_; }
645 friend class TypeImpl<Config>;
646 526
647 enum : uint32_t { 527 private:
648 #define DECLARE_TYPE(type, value) k##type = (value), 528 friend class Type;
649 BITSET_TYPE_LIST(DECLARE_TYPE)
650 #undef DECLARE_TYPE
651 kUnusedEOL = 0
652 };
653 529
654 static bitset SignedSmall(); 530 explicit ArrayType(Type* element) : TypeBase(kArray), element_(element) {}
655 static bitset UnsignedSmall();
656 531
657 bitset Bitset() { return Config::as_bitset(this); } 532 static Type* New(Type* element, Zone* zone) {
658 533 return AsType(new (zone->New(sizeof(ArrayType))) ArrayType(element));
659 static TypeImpl* New(bitset bits) {
660 return Config::from_bitset(bits);
661 }
662 static TypeHandle New(bitset bits, Region* region) {
663 return Config::from_bitset(bits, region);
664 } 534 }
665 535
666 static bool IsInhabited(bitset bits) { 536 static ArrayType* cast(Type* type) {
667 return SEMANTIC(bits) != kNone && REPRESENTATION(bits) != kNone; 537 DCHECK(IsKind(type, kArray));
538 return static_cast<ArrayType*>(FromType(type));
668 } 539 }
669 540
670 static bool SemanticIsInhabited(bitset bits) { 541 Type* element_;
671 return SEMANTIC(bits) != kNone; 542 };
543
544 // -----------------------------------------------------------------------------
545 // Superclass for types with variable number of type fields.
546 class StructuralType : public TypeBase {
547 public:
548 int LengthForTesting() { return Length(); }
549
550 protected:
551 friend class Type;
552
553 int Length() { return length_; }
554
555 Type* Get(int i) {
556 DCHECK(0 <= i && i < this->Length());
557 return elements_[i];
672 } 558 }
673 559
674 static bool Is(bitset bits1, bitset bits2) { 560 void Set(int i, Type* type) {
675 return (bits1 | bits2) == bits2; 561 DCHECK(0 <= i && i < this->Length());
562 elements_[i] = type;
676 } 563 }
677 564
678 static double Min(bitset); 565 void Shrink(int length) {
679 static double Max(bitset); 566 DCHECK(2 <= length && length <= this->Length());
567 length_ = length;
568 }
680 569
681 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset 570 StructuralType(Kind kind, int length, i::Zone* zone)
682 static bitset Glb(double min, double max); 571 : TypeBase(kind), length_(length) {
683 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset 572 elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length));
684 static bitset Lub(i::Map* map); 573 }
685 static bitset Lub(i::Object* value);
686 static bitset Lub(double value);
687 static bitset Lub(double min, double max);
688 static bitset ExpandInternals(bitset bits);
689
690 static const char* Name(bitset);
691 static void Print(std::ostream& os, bitset); // NOLINT
692 #ifdef DEBUG
693 static void Print(bitset);
694 #endif
695
696 static bitset NumberBits(bitset bits);
697 574
698 private: 575 private:
699 struct Boundary { 576 int length_;
700 bitset internal; 577 Type** elements_;
701 bitset external;
702 double min;
703 };
704 static const Boundary BoundariesArray[];
705 static inline const Boundary* Boundaries();
706 static inline size_t BoundariesSize();
707 }; 578 };
708 579
580 // -----------------------------------------------------------------------------
581 // Function types.
709 582
710 // ----------------------------------------------------------------------------- 583 class FunctionType : public StructuralType {
711 // Superclass for non-bitset types (internal). 584 public:
712 // Contains a tag and a variable number of type or value fields. 585 int Arity() { return this->Length() - 2; }
586 Type* Result() { return this->Get(0); }
587 Type* Receiver() { return this->Get(1); }
588 Type* Parameter(int i) { return this->Get(2 + i); }
713 589
714 template<class Config> 590 void InitParameter(int i, Type* type) { this->Set(2 + i, type); }
715 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
716 protected:
717 template<class> friend class TypeImpl;
718 friend struct ZoneTypeConfig; // For tags.
719 friend struct HeapTypeConfig;
720 591
721 enum Tag { 592 private:
722 kClassTag, 593 friend class Type;
723 kConstantTag,
724 kContextTag,
725 kArrayTag,
726 kFunctionTag,
727 kTupleTag,
728 kUnionTag
729 };
730 594
731 int Length() { 595 FunctionType(Type* result, Type* receiver, int arity, Zone* zone)
732 return Config::struct_length(Config::as_struct(this)); 596 : StructuralType(kFunction, 2 + arity, zone) {
733 } 597 Set(0, result);
734 TypeHandle Get(int i) { 598 Set(1, receiver);
735 DCHECK(0 <= i && i < this->Length());
736 return Config::struct_get(Config::as_struct(this), i);
737 }
738 void Set(int i, TypeHandle type) {
739 DCHECK(0 <= i && i < this->Length());
740 Config::struct_set(Config::as_struct(this), i, type);
741 }
742 void Shrink(int length) {
743 DCHECK(2 <= length && length <= this->Length());
744 Config::struct_shrink(Config::as_struct(this), length);
745 }
746 template<class V> i::Handle<V> GetValue(int i) {
747 DCHECK(0 <= i && i < this->Length());
748 return Config::template struct_get_value<V>(Config::as_struct(this), i);
749 }
750 template<class V> void SetValue(int i, i::Handle<V> x) {
751 DCHECK(0 <= i && i < this->Length());
752 Config::struct_set_value(Config::as_struct(this), i, x);
753 } 599 }
754 600
755 static TypeHandle New(Tag tag, int length, Region* region) { 601 static Type* New(Type* result, Type* receiver, int arity, Zone* zone) {
756 DCHECK(1 <= length); 602 return AsType(new (zone->New(sizeof(FunctionType)))
757 return Config::from_struct(Config::struct_create(tag, length, region)); 603 FunctionType(result, receiver, arity, zone));
604 }
605
606 static FunctionType* cast(Type* type) {
607 DCHECK(IsKind(type, kFunction));
608 return static_cast<FunctionType*>(FromType(type));
758 } 609 }
759 }; 610 };
760 611
612 // -----------------------------------------------------------------------------
613 // Tuple types.
614
615 class TupleType : public StructuralType {
616 public:
617 int Arity() { return this->Length(); }
618 Type* Element(int i) { return this->Get(i); }
619
620 void InitElement(int i, Type* type) { this->Set(i, type); }
621
622 private:
623 friend class Type;
624
625 TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
626
627 static Type* New(int length, Zone* zone) {
628 return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone));
629 }
630
631 static TupleType* cast(Type* type) {
632 DCHECK(IsKind(type, kTuple));
633 return static_cast<TupleType*>(FromType(type));
634 }
635 };
761 636
762 // ----------------------------------------------------------------------------- 637 // -----------------------------------------------------------------------------
763 // Union types (internal). 638 // Union types (internal).
764 // A union is a structured type with the following invariants: 639 // A union is a structured type with the following invariants:
765 // - its length is at least 2 640 // - its length is at least 2
766 // - at most one field is a bitset, and it must go into index 0 641 // - at most one field is a bitset, and it must go into index 0
767 // - no field is a union 642 // - no field is a union
768 // - no field is a subtype of any other field 643 // - no field is a subtype of any other field
769 template<class Config> 644 class UnionType : public StructuralType {
770 class TypeImpl<Config>::UnionType : public StructuralType { 645 private:
771 public: 646 friend Type;
772 static UnionHandle New(int length, Region* region) { 647 friend BitsetType;
773 return Config::template cast<UnionType>( 648
774 StructuralType::New(StructuralType::kUnionTag, length, region)); 649 UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
775 } 650
776 651 static Type* New(int length, Zone* zone) {
777 static UnionType* cast(TypeImpl* type) { 652 return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone));
778 DCHECK(type->IsUnion()); 653 }
779 return static_cast<UnionType*>(type); 654
655 static UnionType* cast(Type* type) {
656 DCHECK(IsKind(type, kUnion));
657 return static_cast<UnionType*>(FromType(type));
780 } 658 }
781 659
782 bool Wellformed(); 660 bool Wellformed();
783 }; 661 };
784 662
785 663 class Type {
786 // -----------------------------------------------------------------------------
787 // Class types.
788
789 template<class Config>
790 class TypeImpl<Config>::ClassType : public StructuralType {
791 public: 664 public:
792 i::Handle<i::Map> Map() { 665 typedef BitsetType::bitset bitset; // Internal
793 return Config::is_class(this) ? Config::as_class(this) : 666
794 this->template GetValue<i::Map>(1); 667 // Constructors.
795 } 668 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
796 669 static Type* type() { return BitsetType::New(BitsetType::k##type); }
797 static ClassHandle New(i::Handle<i::Map> map, Region* region) { 670 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
798 ClassHandle type = 671 #undef DEFINE_TYPE_CONSTRUCTOR
799 Config::template cast<ClassType>(Config::from_class(map, region)); 672
800 if (!type->IsClass()) { 673 static Type* SignedSmall() {
801 type = Config::template cast<ClassType>( 674 return BitsetType::New(BitsetType::SignedSmall());
802 StructuralType::New(StructuralType::kClassTag, 2, region)); 675 }
803 type->Set(0, BitsetType::New(BitsetType::Lub(*map), region)); 676 static Type* UnsignedSmall() {
804 type->SetValue(1, map); 677 return BitsetType::New(BitsetType::UnsignedSmall());
678 }
679
680 static Type* Class(i::Handle<i::Map> map, Zone* zone) {
681 return ClassType::New(map, zone);
682 }
683 static Type* Constant(i::Handle<i::Object> value, Zone* zone) {
684 return ConstantType::New(value, zone);
685 }
686 static Type* Range(double min, double max, Zone* zone) {
687 return RangeType::New(min, max, REPRESENTATION(BitsetType::kTagged |
688 BitsetType::kUntaggedNumber),
689 zone);
690 }
691 static Type* Context(Type* outer, Zone* zone) {
692 return ContextType::New(outer, zone);
693 }
694 static Type* Array(Type* element, Zone* zone) {
695 return ArrayType::New(element, zone);
696 }
697 static Type* Function(Type* result, Type* receiver, int arity, Zone* zone) {
698 return FunctionType::New(result, receiver, arity, zone);
699 }
700 static Type* Function(Type* result, Zone* zone) {
701 return Function(result, Any(), 0, zone);
702 }
703 static Type* Function(Type* result, Type* param0, Zone* zone) {
704 Type* function = Function(result, Any(), 1, zone);
705 function->AsFunction()->InitParameter(0, param0);
706 return function;
707 }
708 static Type* Function(Type* result, Type* param0, Type* param1, Zone* zone) {
709 Type* function = Function(result, Any(), 2, zone);
710 function->AsFunction()->InitParameter(0, param0);
711 function->AsFunction()->InitParameter(1, param1);
712 return function;
713 }
714 static Type* Function(Type* result, Type* param0, Type* param1, Type* param2,
715 Zone* zone) {
716 Type* function = Function(result, Any(), 3, zone);
717 function->AsFunction()->InitParameter(0, param0);
718 function->AsFunction()->InitParameter(1, param1);
719 function->AsFunction()->InitParameter(2, param2);
720 return function;
721 }
722 static Type* Function(Type* result, int arity, Type** params, Zone* zone) {
723 Type* function = Function(result, Any(), arity, zone);
724 for (int i = 0; i < arity; ++i) {
725 function->AsFunction()->InitParameter(i, params[i]);
805 } 726 }
806 return type; 727 return function;
807 } 728 }
808 729 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
809 static ClassType* cast(TypeImpl* type) { 730 Type* tuple = TupleType::New(3, zone);
810 DCHECK(type->IsClass()); 731 tuple->AsTuple()->InitElement(0, first);
811 return static_cast<ClassType*>(type); 732 tuple->AsTuple()->InitElement(1, second);
812 } 733 tuple->AsTuple()->InitElement(2, third);
734 return tuple;
735 }
736
737 #define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
738 static Type* Name(Isolate* isolate, Zone* zone);
739 SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
740 #undef CONSTRUCT_SIMD_TYPE
741
742 static Type* Union(Type* type1, Type* type2, Zone* reg);
743 static Type* Intersect(Type* type1, Type* type2, Zone* reg);
744
745 static Type* Of(double value, Zone* zone) {
746 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
747 }
748 static Type* Of(i::Object* value, Zone* zone) {
749 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
750 }
751 static Type* Of(i::Handle<i::Object> value, Zone* zone) {
752 return Of(*value, zone);
753 }
754
755 // Extraction of components.
756 static Type* Representation(Type* t, Zone* zone);
757 static Type* Semantic(Type* t, Zone* zone);
758
759 // Predicates.
760 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
761
762 bool Is(Type* that) { return this == that || this->SlowIs(that); }
763 bool Maybe(Type* that);
764 bool Equals(Type* that) { return this->Is(that) && that->Is(this); }
765
766 // Equivalent to Constant(val)->Is(this), but avoiding allocation.
767 bool Contains(i::Object* val);
768 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
769
770 // State-dependent versions of the above that consider subtyping between
771 // a constant and its map class.
772 static Type* NowOf(i::Object* value, Zone* zone);
773 static Type* NowOf(i::Handle<i::Object> value, Zone* zone) {
774 return NowOf(*value, zone);
775 }
776 bool NowIs(Type* that);
777 bool NowContains(i::Object* val);
778 bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
779
780 bool NowStable();
781
782 // Inspection.
783 bool IsRange() { return IsKind(TypeBase::kRange); }
784 bool IsClass() { return IsKind(TypeBase::kClass); }
785 bool IsConstant() { return IsKind(TypeBase::kConstant); }
786 bool IsContext() { return IsKind(TypeBase::kContext); }
787 bool IsArray() { return IsKind(TypeBase::kArray); }
788 bool IsFunction() { return IsKind(TypeBase::kFunction); }
789 bool IsTuple() { return IsKind(TypeBase::kTuple); }
790
791 ClassType* AsClass() { return ClassType::cast(this); }
792 ConstantType* AsConstant() { return ConstantType::cast(this); }
793 RangeType* AsRange() { return RangeType::cast(this); }
794 ContextType* AsContext() { return ContextType::cast(this); }
795 ArrayType* AsArray() { return ArrayType::cast(this); }
796 FunctionType* AsFunction() { return FunctionType::cast(this); }
797 TupleType* AsTuple() { return TupleType::cast(this); }
798
799 // Minimum and maximum of a numeric type.
800 // These functions do not distinguish between -0 and +0. If the type equals
801 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these
802 // functions on subtypes of Number.
803 double Min();
804 double Max();
805
806 // Extracts a range from the type: if the type is a range or a union
807 // containing a range, that range is returned; otherwise, NULL is returned.
808 Type* GetRange();
809
810 static bool IsInteger(i::Object* x);
811 static bool IsInteger(double x) {
812 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
813 }
814
815 int NumClasses();
816 int NumConstants();
817
818 template <class T>
819 class Iterator {
820 public:
821 bool Done() const { return index_ < 0; }
822 i::Handle<T> Current();
823 void Advance();
824
825 private:
826 friend class Type;
827
828 Iterator() : index_(-1) {}
829 explicit Iterator(Type* type) : type_(type), index_(-1) { Advance(); }
830
831 inline bool matches(Type* type);
832 inline Type* get_type();
833
834 Type* type_;
835 int index_;
836 };
837
838 Iterator<i::Map> Classes() {
839 if (this->IsBitset()) return Iterator<i::Map>();
840 return Iterator<i::Map>(this);
841 }
842 Iterator<i::Object> Constants() {
843 if (this->IsBitset()) return Iterator<i::Object>();
844 return Iterator<i::Object>(this);
845 }
846
847 // Printing.
848
849 enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
850
851 void PrintTo(std::ostream& os, PrintDimension dim = BOTH_DIMS); // NOLINT
852
853 #ifdef DEBUG
854 void Print();
855 #endif
856
857 // Helpers for testing.
858 bool IsBitsetForTesting() { return IsBitset(); }
859 bool IsUnionForTesting() { return IsUnion(); }
860 bitset AsBitsetForTesting() { return AsBitset(); }
861 UnionType* AsUnionForTesting() { return AsUnion(); }
813 862
814 private: 863 private:
815 template<class> friend class TypeImpl; 864 // Friends.
816 bitset Lub() { 865 template <class>
817 return Config::is_class(this) ? 866 friend class Iterator;
818 BitsetType::Lub(*Config::as_class(this)) : 867 friend BitsetType;
819 this->Get(0)->AsBitset(); 868 friend UnionType;
820 } 869
870 // Internal inspection.
871 bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); }
872
873 bool IsNone() { return this == None(); }
874 bool IsAny() { return this == Any(); }
875 bool IsBitset() { return BitsetType::IsBitset(this); }
876 bool IsUnion() { return IsKind(TypeBase::kUnion); }
877
878 bitset AsBitset() {
879 DCHECK(this->IsBitset());
880 return reinterpret_cast<BitsetType*>(this)->Bitset();
881 }
882 UnionType* AsUnion() { return UnionType::cast(this); }
883
884 bitset Representation();
885
886 // Auxiliary functions.
887 bool SemanticMaybe(Type* that);
888
889 bitset BitsetGlb() { return BitsetType::Glb(this); }
890 bitset BitsetLub() { return BitsetType::Lub(this); }
891
892 bool SlowIs(Type* that);
893 bool SemanticIs(Type* that);
894
895 static bool Overlap(RangeType* lhs, RangeType* rhs);
896 static bool Contains(RangeType* lhs, RangeType* rhs);
897 static bool Contains(RangeType* range, ConstantType* constant);
898 static bool Contains(RangeType* range, i::Object* val);
899
900 static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
901
902 static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits,
903 Zone* zone);
904 static RangeType::Limits ToLimits(bitset bits, Zone* zone);
905
906 bool SimplyEquals(Type* that);
907
908 static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone);
909 static int IntersectAux(Type* type, Type* other, UnionType* result, int size,
910 RangeType::Limits* limits, Zone* zone);
911 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone);
912 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone);
821 }; 913 };
822 914
823
824 // -----------------------------------------------------------------------------
825 // Constant types.
826
827 template<class Config>
828 class TypeImpl<Config>::ConstantType : public StructuralType {
829 public:
830 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); }
831
832 static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
833 ConstantHandle type = Config::template cast<ConstantType>(
834 StructuralType::New(StructuralType::kConstantTag, 2, region));
835 type->Set(0, BitsetType::New(BitsetType::Lub(*value), region));
836 type->SetValue(1, value);
837 return type;
838 }
839
840 static ConstantType* cast(TypeImpl* type) {
841 DCHECK(type->IsConstant());
842 return static_cast<ConstantType*>(type);
843 }
844
845 private:
846 template<class> friend class TypeImpl;
847 bitset Lub() { return this->Get(0)->AsBitset(); }
848 };
849 // TODO(neis): Also cache value if numerical.
850 // TODO(neis): Allow restricting the representation.
851
852
853 // -----------------------------------------------------------------------------
854 // Range types.
855
856 template <class Config>
857 class TypeImpl<Config>::RangeType : public TypeImpl<Config> {
858 public:
859 double Min() { return Config::range_get_double(Config::as_range(this), 0); }
860 double Max() { return Config::range_get_double(Config::as_range(this), 1); }
861
862 static RangeHandle New(double min, double max, TypeHandle representation,
863 Region* region) {
864 DCHECK(IsInteger(min) && IsInteger(max));
865 DCHECK(min <= max);
866 bitset representation_bits = representation->AsBitset();
867 DCHECK(REPRESENTATION(representation_bits) == representation_bits);
868
869 typename Config::template Handle<typename Config::Range>::type range =
870 Config::range_create(region);
871
872 bitset bits = SEMANTIC(BitsetType::Lub(min, max)) | representation_bits;
873 Config::range_set_bitset(range, bits);
874 Config::range_set_double(range, 0, min, region);
875 Config::range_set_double(range, 1, max, region);
876 return Config::template cast<RangeType>(Config::from_range(range));
877 }
878
879 static RangeHandle New(Limits lim, bitset representation, Region* region) {
880 return New(lim.min, lim.max, BitsetType::New(representation, region),
881 region);
882 }
883
884 static RangeType* cast(TypeImpl* type) {
885 DCHECK(type->IsRange());
886 return static_cast<RangeType*>(type);
887 }
888
889 private:
890 template<class> friend class TypeImpl;
891 bitset Lub() {
892 return Config::range_get_bitset(Config::as_range(this));
893 }
894 };
895
896
897 // -----------------------------------------------------------------------------
898 // Context types.
899
900 template<class Config>
901 class TypeImpl<Config>::ContextType : public StructuralType {
902 public:
903 TypeHandle Outer() { return this->Get(0); }
904
905 static ContextHandle New(TypeHandle outer, Region* region) {
906 ContextHandle type = Config::template cast<ContextType>(
907 StructuralType::New(StructuralType::kContextTag, 1, region));
908 type->Set(0, outer);
909 return type;
910 }
911
912 static ContextType* cast(TypeImpl* type) {
913 DCHECK(type->IsContext());
914 return static_cast<ContextType*>(type);
915 }
916 };
917
918
919 // -----------------------------------------------------------------------------
920 // Array types.
921
922 template<class Config>
923 class TypeImpl<Config>::ArrayType : public StructuralType {
924 public:
925 TypeHandle Element() { return this->Get(0); }
926
927 static ArrayHandle New(TypeHandle element, Region* region) {
928 ArrayHandle type = Config::template cast<ArrayType>(
929 StructuralType::New(StructuralType::kArrayTag, 1, region));
930 type->Set(0, element);
931 return type;
932 }
933
934 static ArrayType* cast(TypeImpl* type) {
935 DCHECK(type->IsArray());
936 return static_cast<ArrayType*>(type);
937 }
938 };
939
940
941 // -----------------------------------------------------------------------------
942 // Function types.
943
944 template<class Config>
945 class TypeImpl<Config>::FunctionType : public StructuralType {
946 public:
947 int Arity() { return this->Length() - 2; }
948 TypeHandle Result() { return this->Get(0); }
949 TypeHandle Receiver() { return this->Get(1); }
950 TypeHandle Parameter(int i) { return this->Get(2 + i); }
951
952 void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); }
953
954 static FunctionHandle New(
955 TypeHandle result, TypeHandle receiver, int arity, Region* region) {
956 FunctionHandle type = Config::template cast<FunctionType>(
957 StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region));
958 type->Set(0, result);
959 type->Set(1, receiver);
960 return type;
961 }
962
963 static FunctionType* cast(TypeImpl* type) {
964 DCHECK(type->IsFunction());
965 return static_cast<FunctionType*>(type);
966 }
967 };
968
969
970 // -----------------------------------------------------------------------------
971 // Tuple types.
972
973 template <class Config>
974 class TypeImpl<Config>::TupleType : public StructuralType {
975 public:
976 int Arity() { return this->Length(); }
977 TypeHandle Element(int i) { return this->Get(i); }
978
979 void InitElement(int i, TypeHandle type) { this->Set(i, type); }
980
981 static TupleHandle New(int length, Region* region) {
982 TupleHandle type = Config::template cast<TupleType>(
983 StructuralType::New(StructuralType::kTupleTag, length, region));
984 return type;
985 }
986
987 static TupleType* cast(TypeImpl* type) {
988 DCHECK(type->IsTuple());
989 return static_cast<TupleType*>(type);
990 }
991 };
992
993
994 // -----------------------------------------------------------------------------
995 // Type iterators.
996
997 template<class Config> template<class T>
998 class TypeImpl<Config>::Iterator {
999 public:
1000 bool Done() const { return index_ < 0; }
1001 i::Handle<T> Current();
1002 void Advance();
1003
1004 private:
1005 template<class> friend class TypeImpl;
1006
1007 Iterator() : index_(-1) {}
1008 explicit Iterator(TypeHandle type) : type_(type), index_(-1) {
1009 Advance();
1010 }
1011
1012 inline bool matches(TypeHandle type);
1013 inline TypeHandle get_type();
1014
1015 TypeHandle type_;
1016 int index_;
1017 };
1018
1019
1020 // -----------------------------------------------------------------------------
1021 // Zone-allocated types; they are either (odd) integers to represent bitsets, or
1022 // (even) pointers to structures for everything else.
1023
1024 struct ZoneTypeConfig {
1025 typedef TypeImpl<ZoneTypeConfig> Type;
1026 class Base {};
1027 typedef void* Struct;
1028 // Hack: the Struct and Range types can be aliased in memory, the first
1029 // pointer word of each both must be the tag (kRangeStructTag for Range,
1030 // anything else for Struct) so that we can differentiate them.
1031 struct Range {
1032 void* tag;
1033 int bitset;
1034 double limits[2];
1035 };
1036 typedef i::Zone Region;
1037 template<class T> struct Handle { typedef T* type; };
1038
1039 static const int kRangeStructTag = 0x1000;
1040
1041 template<class T> static inline T* null_handle() { return nullptr; }
1042 template<class T> static inline T* handle(T* type);
1043 template<class T> static inline T* cast(Type* type);
1044
1045 static inline bool is_bitset(Type* type);
1046 static inline bool is_class(Type* type);
1047 static inline bool is_struct(Type* type, int tag);
1048 static inline bool is_range(Type* type);
1049
1050 static inline Type::bitset as_bitset(Type* type);
1051 static inline i::Handle<i::Map> as_class(Type* type);
1052 static inline Struct* as_struct(Type* type);
1053 static inline Range* as_range(Type* type);
1054
1055 static inline Type* from_bitset(Type::bitset);
1056 static inline Type* from_bitset(Type::bitset, Zone* zone);
1057 static inline Type* from_class(i::Handle<i::Map> map, Zone* zone);
1058 static inline Type* from_struct(Struct* structured);
1059 static inline Type* from_range(Range* range);
1060
1061 static inline Struct* struct_create(int tag, int length, Zone* zone);
1062 static inline void struct_shrink(Struct* structure, int length);
1063 static inline int struct_tag(Struct* structure);
1064 static inline int struct_length(Struct* structure);
1065 static inline Type* struct_get(Struct* structure, int i);
1066 static inline void struct_set(Struct* structure, int i, Type* type);
1067 template<class V>
1068 static inline i::Handle<V> struct_get_value(Struct* structure, int i);
1069 template<class V> static inline void struct_set_value(
1070 Struct* structure, int i, i::Handle<V> x);
1071
1072 static inline Range* range_create(Zone* zone);
1073 static inline int range_get_bitset(Range* range);
1074 static inline void range_set_bitset(Range* range, int);
1075 static inline double range_get_double(Range*, int index);
1076 static inline void range_set_double(Range*, int index, double value, Zone*);
1077 };
1078
1079 typedef TypeImpl<ZoneTypeConfig> Type;
1080
1081 // ----------------------------------------------------------------------------- 915 // -----------------------------------------------------------------------------
1082 // Type bounds. A simple struct to represent a pair of lower/upper types. 916 // Type bounds. A simple struct to represent a pair of lower/upper types.
1083 917
1084 template<class Config> 918 struct Bounds {
1085 struct BoundsImpl { 919 Type* lower;
1086 typedef TypeImpl<Config> Type; 920 Type* upper;
1087 typedef typename Type::TypeHandle TypeHandle; 921
1088 typedef typename Type::Region Region; 922 Bounds()
1089 923 : // Make sure accessing uninitialized bounds crashes big-time.
1090 TypeHandle lower; 924 lower(nullptr),
1091 TypeHandle upper; 925 upper(nullptr) {}
1092 926 explicit Bounds(Type* t) : lower(t), upper(t) {}
1093 BoundsImpl() : // Make sure accessing uninitialized bounds crashes big-time. 927 Bounds(Type* l, Type* u) : lower(l), upper(u) { DCHECK(lower->Is(upper)); }
1094 lower(Config::template null_handle<Type>()),
1095 upper(Config::template null_handle<Type>()) {}
1096 explicit BoundsImpl(TypeHandle t) : lower(t), upper(t) {}
1097 BoundsImpl(TypeHandle l, TypeHandle u) : lower(l), upper(u) {
1098 DCHECK(lower->Is(upper));
1099 }
1100 928
1101 // Unrestricted bounds. 929 // Unrestricted bounds.
1102 static BoundsImpl Unbounded() { 930 static Bounds Unbounded() { return Bounds(Type::None(), Type::Any()); }
1103 return BoundsImpl(Type::None(), Type::Any());
1104 }
1105 931
1106 // Meet: both b1 and b2 are known to hold. 932 // Meet: both b1 and b2 are known to hold.
1107 static BoundsImpl Both(BoundsImpl b1, BoundsImpl b2, Region* region) { 933 static Bounds Both(Bounds b1, Bounds b2, Zone* zone) {
1108 TypeHandle lower = Type::Union(b1.lower, b2.lower, region); 934 Type* lower = Type::Union(b1.lower, b2.lower, zone);
1109 TypeHandle upper = Type::Intersect(b1.upper, b2.upper, region); 935 Type* upper = Type::Intersect(b1.upper, b2.upper, zone);
1110 // Lower bounds are considered approximate, correct as necessary. 936 // Lower bounds are considered approximate, correct as necessary.
1111 if (!lower->Is(upper)) lower = upper; 937 if (!lower->Is(upper)) lower = upper;
1112 return BoundsImpl(lower, upper); 938 return Bounds(lower, upper);
1113 } 939 }
1114 940
1115 // Join: either b1 or b2 is known to hold. 941 // Join: either b1 or b2 is known to hold.
1116 static BoundsImpl Either(BoundsImpl b1, BoundsImpl b2, Region* region) { 942 static Bounds Either(Bounds b1, Bounds b2, Zone* zone) {
1117 TypeHandle lower = Type::Intersect(b1.lower, b2.lower, region); 943 Type* lower = Type::Intersect(b1.lower, b2.lower, zone);
1118 TypeHandle upper = Type::Union(b1.upper, b2.upper, region); 944 Type* upper = Type::Union(b1.upper, b2.upper, zone);
1119 return BoundsImpl(lower, upper); 945 return Bounds(lower, upper);
1120 } 946 }
1121 947
1122 static BoundsImpl NarrowLower(BoundsImpl b, TypeHandle t, Region* region) { 948 static Bounds NarrowLower(Bounds b, Type* t, Zone* zone) {
1123 TypeHandle lower = Type::Union(b.lower, t, region); 949 Type* lower = Type::Union(b.lower, t, zone);
1124 // Lower bounds are considered approximate, correct as necessary. 950 // Lower bounds are considered approximate, correct as necessary.
1125 if (!lower->Is(b.upper)) lower = b.upper; 951 if (!lower->Is(b.upper)) lower = b.upper;
1126 return BoundsImpl(lower, b.upper); 952 return Bounds(lower, b.upper);
1127 } 953 }
1128 static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) { 954 static Bounds NarrowUpper(Bounds b, Type* t, Zone* zone) {
1129 TypeHandle lower = b.lower; 955 Type* lower = b.lower;
1130 TypeHandle upper = Type::Intersect(b.upper, t, region); 956 Type* upper = Type::Intersect(b.upper, t, zone);
1131 // Lower bounds are considered approximate, correct as necessary. 957 // Lower bounds are considered approximate, correct as necessary.
1132 if (!lower->Is(upper)) lower = upper; 958 if (!lower->Is(upper)) lower = upper;
1133 return BoundsImpl(lower, upper); 959 return Bounds(lower, upper);
1134 } 960 }
1135 961
1136 bool Narrows(BoundsImpl that) { 962 bool Narrows(Bounds that) {
1137 return that.lower->Is(this->lower) && this->upper->Is(that.upper); 963 return that.lower->Is(this->lower) && this->upper->Is(that.upper);
1138 } 964 }
1139 }; 965 };
1140 966
1141 typedef BoundsImpl<ZoneTypeConfig> Bounds;
1142
1143 class FieldType : public Object { 967 class FieldType : public Object {
1144 public: 968 public:
1145 static FieldType* None(); 969 static FieldType* None();
1146 static FieldType* Any(); 970 static FieldType* Any();
1147 static Handle<FieldType> None(Isolate* isolate); 971 static Handle<FieldType> None(Isolate* isolate);
1148 static Handle<FieldType> Any(Isolate* isolate); 972 static Handle<FieldType> Any(Isolate* isolate);
1149 static FieldType* Class(i::Map* map); 973 static FieldType* Class(i::Map* map);
1150 static Handle<FieldType> Class(i::Handle<i::Map> map, Isolate* isolate); 974 static Handle<FieldType> Class(i::Handle<i::Map> map, Isolate* isolate);
1151 static FieldType* cast(Object* object); 975 static FieldType* cast(Object* object);
1152 976
1153 bool NowContains(Object* value); 977 bool NowContains(Object* value);
1154 bool NowContains(Handle<Object> value); 978 bool NowContains(Handle<Object> value);
1155 bool IsClass(); 979 bool IsClass();
1156 Handle<i::Map> AsClass(); 980 Handle<i::Map> AsClass();
1157 bool IsNone() { return this == None(); } 981 bool IsNone() { return this == None(); }
1158 bool IsAny() { return this == Any(); } 982 bool IsAny() { return this == Any(); }
1159 bool NowStable(); 983 bool NowStable();
1160 bool NowIs(FieldType* other); 984 bool NowIs(FieldType* other);
1161 bool NowIs(Handle<FieldType> other); 985 bool NowIs(Handle<FieldType> other);
1162 Type* Convert(Zone* zone); 986 Type* Convert(Zone* zone);
1163 987
1164 void PrintTo(std::ostream& os); 988 void PrintTo(std::ostream& os);
1165 }; 989 };
1166 990
1167 } // namespace internal 991 } // namespace internal
1168 } // namespace v8 992 } // namespace v8
1169 993
1170 #endif // V8_TYPES_H_ 994 #endif // V8_TYPES_H_
OLDNEW
« no previous file with comments | « src/type-info.cc ('k') | src/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698