| 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 |