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 255 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) && | |
rossberg
2014/07/24 09:38:30
I don't think these should be removed, but they sh
| |
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) || | 341 // TODO(rossberg): Check details of arrays, functions, bounds. |
rossberg
2014/07/24 09:38:30
Similarly here: use the public getters.
|
rossberg
2014/07/24 09:38:30
If you want, please also feel free to flesh out th
|
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) || | 342 (!Rep::IsUnion(type1) || |
386 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); | 343 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); |
387 } | 344 } |
388 | 345 |
389 void CheckEqual(TypeHandle type1, TypeHandle type2) { | 346 void CheckEqual(TypeHandle type1, TypeHandle type2) { |
390 CHECK(Equal(type1, type2)); | 347 CHECK(Equal(type1, type2)); |
391 } | 348 } |
392 | 349 |
393 void CheckSub(TypeHandle type1, TypeHandle type2) { | 350 void CheckSub(TypeHandle type1, TypeHandle type2) { |
394 CHECK(type1->Is(type2)); | 351 CHECK(type1->Is(type2)); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
494 } | 451 } |
495 } | 452 } |
496 } | 453 } |
497 } | 454 } |
498 | 455 |
499 void Class() { | 456 void Class() { |
500 // Constructor | 457 // Constructor |
501 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 458 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
502 Handle<i::Map> map = *mt; | 459 Handle<i::Map> map = *mt; |
503 TypeHandle type = T.Class(map); | 460 TypeHandle type = T.Class(map); |
504 CHECK(this->IsClass(type)); | 461 CHECK(type->IsClass()); |
505 } | 462 } |
506 | 463 |
507 // Map attribute | 464 // Map attribute |
508 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 465 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
509 Handle<i::Map> map = *mt; | 466 Handle<i::Map> map = *mt; |
510 TypeHandle type = T.Class(map); | 467 TypeHandle type = T.Class(map); |
511 CHECK(*map == *type->AsClass()->Map()); | 468 CHECK(*map == *type->AsClass()->Map()); |
512 } | 469 } |
513 | 470 |
514 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 | 471 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 |
515 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 472 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
516 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 473 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
517 Handle<i::Map> map1 = *mt1; | 474 Handle<i::Map> map1 = *mt1; |
518 Handle<i::Map> map2 = *mt2; | 475 Handle<i::Map> map2 = *mt2; |
519 TypeHandle type1 = T.Class(map1); | 476 TypeHandle type1 = T.Class(map1); |
520 TypeHandle type2 = T.Class(map2); | 477 TypeHandle type2 = T.Class(map2); |
521 CHECK(Equal(type1, type2) == (*map1 == *map2)); | 478 CHECK(Equal(type1, type2) == (*map1 == *map2)); |
522 } | 479 } |
523 } | 480 } |
524 } | 481 } |
525 | 482 |
526 void Constant() { | 483 void Constant() { |
527 // Constructor | 484 // Constructor |
528 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 485 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
529 Handle<i::Object> value = *vt; | 486 Handle<i::Object> value = *vt; |
530 TypeHandle type = T.Constant(value); | 487 TypeHandle type = T.Constant(value); |
531 CHECK(this->IsConstant(type)); | 488 CHECK(type->IsConstant()); |
532 } | 489 } |
533 | 490 |
534 // Value attribute | 491 // Value attribute |
535 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 492 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
536 Handle<i::Object> value = *vt; | 493 Handle<i::Object> value = *vt; |
537 TypeHandle type = T.Constant(value); | 494 TypeHandle type = T.Constant(value); |
538 CHECK(*value == *type->AsConstant()->Value()); | 495 CHECK(*value == *type->AsConstant()->Value()); |
539 } | 496 } |
540 | 497 |
541 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 | 498 // 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)); | 546 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber)); |
590 } | 547 } |
591 | 548 |
592 void Range() { | 549 void Range() { |
593 // Constructor | 550 // Constructor |
594 for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { | 551 for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { |
595 for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { | 552 for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { |
596 double min = std::min(*i, *j); | 553 double min = std::min(*i, *j); |
597 double max = std::max(*i, *j); | 554 double max = std::max(*i, *j); |
598 TypeHandle type = T.Range(min, max); | 555 TypeHandle type = T.Range(min, max); |
599 CHECK(this->IsRange(type)); | 556 CHECK(type->IsRange()); |
600 } | 557 } |
601 } | 558 } |
602 | 559 |
603 // Range attributes | 560 // Range attributes |
604 for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { | 561 for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { |
605 for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { | 562 for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { |
606 double min = std::min(*i, *j); | 563 double min = std::min(*i, *j); |
607 double max = std::max(*i, *j); | 564 double max = std::max(*i, *j); |
608 printf("RangeType: min, max = %f, %f\n", min, max); | 565 printf("RangeType: min, max = %f, %f\n", min, max); |
609 TypeHandle type = T.Range(min, max); | 566 TypeHandle type = T.Range(min, max); |
(...skipping 24 matching lines...) Expand all Loading... | |
634 // } | 591 // } |
635 // } | 592 // } |
636 // } | 593 // } |
637 } | 594 } |
638 | 595 |
639 void Array() { | 596 void Array() { |
640 // Constructor | 597 // Constructor |
641 for (int i = 0; i < 20; ++i) { | 598 for (int i = 0; i < 20; ++i) { |
642 TypeHandle type = T.Random(); | 599 TypeHandle type = T.Random(); |
643 TypeHandle array = T.Array1(type); | 600 TypeHandle array = T.Array1(type); |
644 CHECK(this->IsArray(array)); | 601 CHECK(array->IsArray()); |
645 } | 602 } |
646 | 603 |
647 // Attributes | 604 // Attributes |
648 for (int i = 0; i < 20; ++i) { | 605 for (int i = 0; i < 20; ++i) { |
649 TypeHandle type = T.Random(); | 606 TypeHandle type = T.Random(); |
650 TypeHandle array = T.Array1(type); | 607 TypeHandle array = T.Array1(type); |
651 CheckEqual(type, array->AsArray()->Element()); | 608 CheckEqual(type, array->AsArray()->Element()); |
652 } | 609 } |
653 | 610 |
654 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 | 611 // 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>(); | 1945 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
1989 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 1946 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
1990 } | 1947 } |
1991 | 1948 |
1992 | 1949 |
1993 TEST(HTypeFromType) { | 1950 TEST(HTypeFromType) { |
1994 CcTest::InitializeVM(); | 1951 CcTest::InitializeVM(); |
1995 ZoneTests().HTypeFromType(); | 1952 ZoneTests().HTypeFromType(); |
1996 HeapTests().HTypeFromType(); | 1953 HeapTests().HTypeFromType(); |
1997 } | 1954 } |
OLD | NEW |