| OLD | NEW | 
|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include <vector> | 5 #include <vector> | 
| 6 | 6 | 
| 7 #include "src/hydrogen-types.h" | 7 #include "src/hydrogen-types.h" | 
| 8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" | 
| 9 #include "src/types.h" | 9 #include "src/types.h" | 
| 10 #include "test/cctest/cctest.h" | 10 #include "test/cctest/cctest.h" | 
| 11 | 11 | 
| 12 using namespace v8::internal; | 12 using namespace v8::internal; | 
| 13 | 13 | 
| 14 // Testing auxiliaries (breaking the Type abstraction). | 14 // Testing auxiliaries (breaking the Type abstraction). | 
| 15 struct ZoneRep { | 15 struct ZoneRep { | 
| 16   typedef void* Struct; | 16   typedef void* Struct; | 
| 17 | 17 | 
| 18   static bool IsStruct(Type* t, int tag) { | 18   static bool IsStruct(Type* t, int tag) { | 
| 19     return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; | 19     return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; | 
| 20   } | 20   } | 
| 21   static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } | 21   static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } | 
| 22   static bool IsClass(Type* t) { return IsStruct(t, 0); } |  | 
| 23   static bool IsConstant(Type* t) { return IsStruct(t, 1); } |  | 
| 24   static bool IsRange(Type* t) { return IsStruct(t, 2); } |  | 
| 25   static bool IsContext(Type* t) { return IsStruct(t, 3); } |  | 
| 26   static bool IsArray(Type* t) { return IsStruct(t, 4); } |  | 
| 27   static bool IsFunction(Type* t) { return IsStruct(t, 5); } |  | 
| 28   static bool IsUnion(Type* t) { return IsStruct(t, 6); } | 22   static bool IsUnion(Type* t) { return IsStruct(t, 6); } | 
| 29 | 23 | 
| 30   static Struct* AsStruct(Type* t) { | 24   static Struct* AsStruct(Type* t) { | 
| 31     return reinterpret_cast<Struct*>(t); | 25     return reinterpret_cast<Struct*>(t); | 
| 32   } | 26   } | 
| 33   static int AsBitset(Type* t) { | 27   static int AsBitset(Type* t) { | 
| 34     return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); | 28     return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); | 
| 35   } | 29   } | 
| 36   static Map* AsClass(Type* t) { |  | 
| 37     return *static_cast<Map**>(AsStruct(t)[3]); |  | 
| 38   } |  | 
| 39   static Object* AsConstant(Type* t) { |  | 
| 40     return *static_cast<Object**>(AsStruct(t)[3]); |  | 
| 41   } |  | 
| 42   static Type* AsContext(Type* t) { |  | 
| 43     return *static_cast<Type**>(AsStruct(t)[2]); |  | 
| 44   } |  | 
| 45   static Struct* AsUnion(Type* t) { | 30   static Struct* AsUnion(Type* t) { | 
| 46     return AsStruct(t); | 31     return AsStruct(t); | 
| 47   } | 32   } | 
| 48   static int Length(Struct* structured) { | 33   static int Length(Struct* structured) { | 
| 49     return static_cast<int>(reinterpret_cast<intptr_t>(structured[1])); | 34     return static_cast<int>(reinterpret_cast<intptr_t>(structured[1])); | 
| 50   } | 35   } | 
| 51 | 36 | 
| 52   static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } | 37   static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } | 
| 53 | 38 | 
| 54   struct BitsetType : Type::BitsetType { | 39   struct BitsetType : Type::BitsetType { | 
| 55     using Type::BitsetType::New; | 40     using Type::BitsetType::New; | 
| 56     using Type::BitsetType::Glb; | 41     using Type::BitsetType::Glb; | 
| 57     using Type::BitsetType::Lub; | 42     using Type::BitsetType::Lub; | 
| 58     using Type::BitsetType::InherentLub; | 43     using Type::BitsetType::InherentLub; | 
| 59   }; | 44   }; | 
| 60 }; | 45 }; | 
| 61 | 46 | 
| 62 | 47 | 
| 63 struct HeapRep { | 48 struct HeapRep { | 
| 64   typedef FixedArray Struct; | 49   typedef FixedArray Struct; | 
| 65 | 50 | 
| 66   static bool IsStruct(Handle<HeapType> t, int tag) { | 51   static bool IsStruct(Handle<HeapType> t, int tag) { | 
| 67     return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; | 52     return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; | 
| 68   } | 53   } | 
| 69   static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } | 54   static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } | 
| 70   static bool IsClass(Handle<HeapType> t) { |  | 
| 71     return t->IsMap() || IsStruct(t, 0); |  | 
| 72   } |  | 
| 73   static bool IsConstant(Handle<HeapType> t) { return IsStruct(t, 1); } |  | 
| 74   static bool IsRange(Handle<HeapType> t) { return IsStruct(t, 2); } |  | 
| 75   static bool IsContext(Handle<HeapType> t) { return IsStruct(t, 3); } |  | 
| 76   static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 4); } |  | 
| 77   static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 5); } |  | 
| 78   static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); } | 55   static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); } | 
| 79 | 56 | 
| 80   static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } | 57   static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } | 
| 81   static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } | 58   static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } | 
| 82   static Map* AsClass(Handle<HeapType> t) { |  | 
| 83     return t->IsMap() ? Map::cast(*t) : Map::cast(AsStruct(t)->get(2)); |  | 
| 84   } |  | 
| 85   static Object* AsConstant(Handle<HeapType> t) { return AsStruct(t)->get(2); } |  | 
| 86   static HeapType* AsContext(Handle<HeapType> t) { |  | 
| 87     return HeapType::cast(AsStruct(t)->get(1)); |  | 
| 88   } |  | 
| 89   static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } | 59   static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } | 
| 90   static int Length(Struct* structured) { return structured->length() - 1; } | 60   static int Length(Struct* structured) { return structured->length() - 1; } | 
| 91 | 61 | 
| 92   static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } | 62   static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } | 
| 93 | 63 | 
| 94   struct BitsetType : HeapType::BitsetType { | 64   struct BitsetType : HeapType::BitsetType { | 
| 95     using HeapType::BitsetType::New; | 65     using HeapType::BitsetType::New; | 
| 96     using HeapType::BitsetType::Glb; | 66     using HeapType::BitsetType::Glb; | 
| 97     using HeapType::BitsetType::Lub; | 67     using HeapType::BitsetType::Lub; | 
| 98     using HeapType::BitsetType::InherentLub; | 68     using HeapType::BitsetType::InherentLub; | 
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 210   TypeHandle MethodFunction; | 180   TypeHandle MethodFunction; | 
| 211 | 181 | 
| 212   typedef std::vector<TypeHandle> TypeVector; | 182   typedef std::vector<TypeHandle> TypeVector; | 
| 213   typedef std::vector<Handle<i::Map> > MapVector; | 183   typedef std::vector<Handle<i::Map> > MapVector; | 
| 214   typedef std::vector<Handle<i::Object> > ValueVector; | 184   typedef std::vector<Handle<i::Object> > ValueVector; | 
| 215   typedef std::vector<double> DoubleVector; | 185   typedef std::vector<double> DoubleVector; | 
| 216 | 186 | 
| 217   TypeVector types; | 187   TypeVector types; | 
| 218   MapVector maps; | 188   MapVector maps; | 
| 219   ValueVector values; | 189   ValueVector values; | 
| 220   DoubleVector doubles; | 190   DoubleVector doubles;  // Some floating-point values, excluding NaN. | 
| 221 | 191 | 
| 222   TypeHandle Of(Handle<i::Object> value) { | 192   TypeHandle Of(Handle<i::Object> value) { | 
| 223     return Type::Of(value, region_); | 193     return Type::Of(value, region_); | 
| 224   } | 194   } | 
| 225 | 195 | 
| 226   TypeHandle NowOf(Handle<i::Object> value) { | 196   TypeHandle NowOf(Handle<i::Object> value) { | 
| 227     return Type::NowOf(value, region_); | 197     return Type::NowOf(value, region_); | 
| 228   } | 198   } | 
| 229 | 199 | 
| 230   TypeHandle Constant(Handle<i::Object> value) { | 200   TypeHandle Constant(Handle<i::Object> value) { | 
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 354 | 324 | 
| 355   Tests() : | 325   Tests() : | 
| 356       isolate(CcTest::i_isolate()), | 326       isolate(CcTest::i_isolate()), | 
| 357       scope(isolate), | 327       scope(isolate), | 
| 358       zone(isolate), | 328       zone(isolate), | 
| 359       T(Rep::ToRegion(&zone, isolate), isolate) { | 329       T(Rep::ToRegion(&zone, isolate), isolate) { | 
| 360   } | 330   } | 
| 361 | 331 | 
| 362   bool Equal(TypeHandle type1, TypeHandle type2) { | 332   bool Equal(TypeHandle type1, TypeHandle type2) { | 
| 363     return | 333     return | 
| 364         type1->Is(type2) && type2->Is(type1) && | 334         type1->Equals(type2) && | 
| 365         Rep::IsBitset(type1) == Rep::IsBitset(type2) && | 335         Rep::IsBitset(type1) == Rep::IsBitset(type2) && | 
| 366         Rep::IsClass(type1) == Rep::IsClass(type2) && |  | 
| 367         Rep::IsConstant(type1) == Rep::IsConstant(type2) && |  | 
| 368         Rep::IsRange(type1) == Rep::IsRange(type2) && |  | 
| 369         Rep::IsContext(type1) == Rep::IsContext(type2) && |  | 
| 370         Rep::IsArray(type1) == Rep::IsArray(type2) && |  | 
| 371         Rep::IsFunction(type1) == Rep::IsFunction(type2) && |  | 
| 372         Rep::IsUnion(type1) == Rep::IsUnion(type2) && | 336         Rep::IsUnion(type1) == Rep::IsUnion(type2) && | 
| 373         type1->NumClasses() == type2->NumClasses() && | 337         type1->NumClasses() == type2->NumClasses() && | 
| 374         type1->NumConstants() == type2->NumConstants() && | 338         type1->NumConstants() == type2->NumConstants() && | 
| 375         (!Rep::IsBitset(type1) || | 339         (!Rep::IsBitset(type1) || | 
| 376           Rep::AsBitset(type1) == Rep::AsBitset(type2)) && | 340           Rep::AsBitset(type1) == Rep::AsBitset(type2)) && | 
| 377         (!Rep::IsClass(type1) || |  | 
| 378           Rep::AsClass(type1) == Rep::AsClass(type2)) && |  | 
| 379         (!Rep::IsConstant(type1) || |  | 
| 380           Rep::AsConstant(type1) == Rep::AsConstant(type2)) && |  | 
| 381         (!Rep::IsRange(type1) || |  | 
| 382           (type1->AsRange()->Min() == type2->AsRange()->Min() && |  | 
| 383            type1->AsRange()->Max() == type2->AsRange()->Max())) && |  | 
| 384           // TODO(rossberg): Check details of arrays, functions, bounds. |  | 
| 385         (!Rep::IsUnion(type1) || | 341         (!Rep::IsUnion(type1) || | 
| 386           Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); | 342           Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); | 
| 387   } | 343   } | 
| 388 | 344 | 
| 389   void CheckEqual(TypeHandle type1, TypeHandle type2) { | 345   void CheckEqual(TypeHandle type1, TypeHandle type2) { | 
| 390     CHECK(Equal(type1, type2)); | 346     CHECK(Equal(type1, type2)); | 
| 391   } | 347   } | 
| 392 | 348 | 
| 393   void CheckSub(TypeHandle type1, TypeHandle type2) { | 349   void CheckSub(TypeHandle type1, TypeHandle type2) { | 
| 394     CHECK(type1->Is(type2)); | 350     CHECK(type1->Is(type2)); | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 494         } | 450         } | 
| 495       } | 451       } | 
| 496     } | 452     } | 
| 497   } | 453   } | 
| 498 | 454 | 
| 499   void Class() { | 455   void Class() { | 
| 500     // Constructor | 456     // Constructor | 
| 501     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 457     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 
| 502       Handle<i::Map> map = *mt; | 458       Handle<i::Map> map = *mt; | 
| 503       TypeHandle type = T.Class(map); | 459       TypeHandle type = T.Class(map); | 
| 504       CHECK(this->IsClass(type)); | 460       CHECK(type->IsClass()); | 
| 505     } | 461     } | 
| 506 | 462 | 
| 507     // Map attribute | 463     // Map attribute | 
| 508     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 464     for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 
| 509       Handle<i::Map> map = *mt; | 465       Handle<i::Map> map = *mt; | 
| 510       TypeHandle type = T.Class(map); | 466       TypeHandle type = T.Class(map); | 
| 511       CHECK(*map == *type->AsClass()->Map()); | 467       CHECK(*map == *type->AsClass()->Map()); | 
| 512     } | 468     } | 
| 513 | 469 | 
| 514     // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 | 470     // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 | 
| 515     for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 471     for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 
| 516       for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 472       for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 
| 517         Handle<i::Map> map1 = *mt1; | 473         Handle<i::Map> map1 = *mt1; | 
| 518         Handle<i::Map> map2 = *mt2; | 474         Handle<i::Map> map2 = *mt2; | 
| 519         TypeHandle type1 = T.Class(map1); | 475         TypeHandle type1 = T.Class(map1); | 
| 520         TypeHandle type2 = T.Class(map2); | 476         TypeHandle type2 = T.Class(map2); | 
| 521         CHECK(Equal(type1, type2) == (*map1 == *map2)); | 477         CHECK(Equal(type1, type2) == (*map1 == *map2)); | 
| 522       } | 478       } | 
| 523     } | 479     } | 
| 524   } | 480   } | 
| 525 | 481 | 
| 526   void Constant() { | 482   void Constant() { | 
| 527     // Constructor | 483     // Constructor | 
| 528     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 484     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 
| 529       Handle<i::Object> value = *vt; | 485       Handle<i::Object> value = *vt; | 
| 530       TypeHandle type = T.Constant(value); | 486       TypeHandle type = T.Constant(value); | 
| 531       CHECK(this->IsConstant(type)); | 487       CHECK(type->IsConstant()); | 
| 532     } | 488     } | 
| 533 | 489 | 
| 534     // Value attribute | 490     // Value attribute | 
| 535     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 491     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 
| 536       Handle<i::Object> value = *vt; | 492       Handle<i::Object> value = *vt; | 
| 537       TypeHandle type = T.Constant(value); | 493       TypeHandle type = T.Constant(value); | 
| 538       CHECK(*value == *type->AsConstant()->Value()); | 494       CHECK(*value == *type->AsConstant()->Value()); | 
| 539     } | 495     } | 
| 540 | 496 | 
| 541     // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 | 497     // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 589     CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber)); | 545     CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber)); | 
| 590   } | 546   } | 
| 591 | 547 | 
| 592   void Range() { | 548   void Range() { | 
| 593     // Constructor | 549     // Constructor | 
| 594     for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { | 550     for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { | 
| 595       for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { | 551       for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { | 
| 596         double min = std::min(*i, *j); | 552         double min = std::min(*i, *j); | 
| 597         double max = std::max(*i, *j); | 553         double max = std::max(*i, *j); | 
| 598         TypeHandle type = T.Range(min, max); | 554         TypeHandle type = T.Range(min, max); | 
| 599         CHECK(this->IsRange(type)); | 555         CHECK(type->IsRange()); | 
| 600       } | 556       } | 
| 601     } | 557     } | 
| 602 | 558 | 
| 603     // Range attributes | 559     // Range attributes | 
| 604     for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { | 560     for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { | 
| 605       for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { | 561       for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { | 
| 606         double min = std::min(*i, *j); | 562         double min = std::min(*i, *j); | 
| 607         double max = std::max(*i, *j); | 563         double max = std::max(*i, *j); | 
| 608         printf("RangeType: min, max = %f, %f\n", min, max); | 564         printf("RangeType: min, max = %f, %f\n", min, max); | 
| 609         TypeHandle type = T.Range(min, max); | 565         TypeHandle type = T.Range(min, max); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 634 //      } | 590 //      } | 
| 635 //    } | 591 //    } | 
| 636 //  } | 592 //  } | 
| 637   } | 593   } | 
| 638 | 594 | 
| 639   void Array() { | 595   void Array() { | 
| 640     // Constructor | 596     // Constructor | 
| 641     for (int i = 0; i < 20; ++i) { | 597     for (int i = 0; i < 20; ++i) { | 
| 642       TypeHandle type = T.Random(); | 598       TypeHandle type = T.Random(); | 
| 643       TypeHandle array = T.Array1(type); | 599       TypeHandle array = T.Array1(type); | 
| 644       CHECK(this->IsArray(array)); | 600       CHECK(array->IsArray()); | 
| 645     } | 601     } | 
| 646 | 602 | 
| 647     // Attributes | 603     // Attributes | 
| 648     for (int i = 0; i < 20; ++i) { | 604     for (int i = 0; i < 20; ++i) { | 
| 649       TypeHandle type = T.Random(); | 605       TypeHandle type = T.Random(); | 
| 650       TypeHandle array = T.Array1(type); | 606       TypeHandle array = T.Array1(type); | 
| 651       CheckEqual(type, array->AsArray()->Element()); | 607       CheckEqual(type, array->AsArray()->Element()); | 
| 652     } | 608     } | 
| 653 | 609 | 
| 654     // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 | 610     // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 | 
| (...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1988   ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 1944   ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 
| 1989   HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 1945   HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 
| 1990 } | 1946 } | 
| 1991 | 1947 | 
| 1992 | 1948 | 
| 1993 TEST(HTypeFromType) { | 1949 TEST(HTypeFromType) { | 
| 1994   CcTest::InitializeVM(); | 1950   CcTest::InitializeVM(); | 
| 1995   ZoneTests().HTypeFromType(); | 1951   ZoneTests().HTypeFromType(); | 
| 1996   HeapTests().HTypeFromType(); | 1952   HeapTests().HTypeFromType(); | 
| 1997 } | 1953 } | 
| OLD | NEW | 
|---|