| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include <vector> | 28 #include <vector> |
| 29 | 29 |
| 30 #include "cctest.h" | 30 #include "cctest.h" |
| 31 #include "types.h" | 31 #include "types.h" |
| 32 | 32 |
| 33 using namespace v8::internal; | 33 using namespace v8::internal; |
| 34 | 34 |
| 35 template<class Type, class TypeHandle, class Region> | 35 template<class Type, class TypeHandle, class Region> |
| 36 class Types { | 36 class Types { |
| 37 public: | 37 public: |
| 38 Types(Region* region, Isolate* isolate) : | 38 Types(Region* region, Isolate* isolate) : region_(region) { |
| 39 Representation(Type::Representation(region)), | 39 static const size_t kMaxTypes = 300; |
| 40 Semantic(Type::Semantic(region)), | 40 types.reserve(kMaxTypes); |
| 41 None(Type::None(region)), | 41 |
| 42 Any(Type::Any(region)), | 42 #define DECLARE_TYPE(name, value) \ |
| 43 Boolean(Type::Boolean(region)), | 43 name = Type::name(region); \ |
| 44 Null(Type::Null(region)), | 44 types.push_back(name); |
| 45 Undefined(Type::Undefined(region)), | 45 BITSET_TYPE_LIST(DECLARE_TYPE) |
| 46 Number(Type::Number(region)), | 46 #undef DECLARE_TYPE |
| 47 SignedSmall(Type::SignedSmall(region)), | 47 |
| 48 Signed32(Type::Signed32(region)), | 48 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize); |
| 49 Float(Type::Float(region)), | 49 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize); |
| 50 Name(Type::Name(region)), | 50 ObjectClass = Type::Class(object_map, region); |
| 51 UniqueName(Type::UniqueName(region)), | 51 ArrayClass = Type::Class(array_map, region); |
| 52 String(Type::String(region)), | 52 types.push_back(ObjectClass); |
| 53 InternalizedString(Type::InternalizedString(region)), | 53 types.push_back(ArrayClass); |
| 54 Symbol(Type::Symbol(region)), | 54 |
| 55 Receiver(Type::Receiver(region)), | |
| 56 Object(Type::Object(region)), | |
| 57 Array(Type::Array(region)), | |
| 58 Function(Type::Function(region)), | |
| 59 Proxy(Type::Proxy(region)), | |
| 60 object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)), | |
| 61 array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)), | |
| 62 region_(region) { | |
| 63 smi = handle(Smi::FromInt(666), isolate); | 55 smi = handle(Smi::FromInt(666), isolate); |
| 64 signed32 = isolate->factory()->NewHeapNumber(0x40000000); | 56 signed32 = isolate->factory()->NewHeapNumber(0x40000000); |
| 65 object1 = isolate->factory()->NewJSObjectFromMap(object_map); | 57 object1 = isolate->factory()->NewJSObjectFromMap(object_map); |
| 66 object2 = isolate->factory()->NewJSObjectFromMap(object_map); | 58 object2 = isolate->factory()->NewJSObjectFromMap(object_map); |
| 67 array = isolate->factory()->NewJSArray(20); | 59 array = isolate->factory()->NewJSArray(20); |
| 68 ObjectClass = Type::Class(object_map, region); | 60 values.push_back(smi); |
| 69 ArrayClass = Type::Class(array_map, region); | 61 values.push_back(signed32); |
| 62 values.push_back(object1); |
| 63 values.push_back(object2); |
| 64 values.push_back(array); |
| 70 SmiConstant = Type::Constant(smi, region); | 65 SmiConstant = Type::Constant(smi, region); |
| 71 Signed32Constant = Type::Constant(signed32, region); | 66 Signed32Constant = Type::Constant(signed32, region); |
| 72 ObjectConstant1 = Type::Constant(object1, region); | 67 ObjectConstant1 = Type::Constant(object1, region); |
| 73 ObjectConstant2 = Type::Constant(object2, region); | 68 ObjectConstant2 = Type::Constant(object2, region); |
| 74 ArrayConstant1 = Type::Constant(array, region); | 69 ArrayConstant1 = Type::Constant(array, region); |
| 75 ArrayConstant2 = Type::Constant(array, region); | 70 ArrayConstant2 = Type::Constant(array, region); |
| 71 for (ObjectVector::iterator it = values.begin(); it != values.end(); ++it) { |
| 72 types.push_back(Type::Constant(*it, region)); |
| 73 } |
| 76 | 74 |
| 77 objects.push_back(smi); | |
| 78 objects.push_back(signed32); | |
| 79 objects.push_back(object1); | |
| 80 objects.push_back(object2); | |
| 81 objects.push_back(array); | |
| 82 | |
| 83 static const size_t kMaxTypes = 300; | |
| 84 types.reserve(kMaxTypes); | |
| 85 #define PUSH_BACK_BITSET_TYPE(type, value) \ | |
| 86 types.push_back(Type::type(region)); | |
| 87 BITSET_TYPE_LIST(PUSH_BACK_BITSET_TYPE) | |
| 88 #undef PUSH_BACK_BITSET_TYPE | |
| 89 types.push_back(ObjectClass); | |
| 90 types.push_back(ArrayClass); | |
| 91 for (ObjectVector::iterator it = objects.begin(); it != objects.end(); ++it) | |
| 92 types.push_back(Type::Constant(*it, region)); | |
| 93 while (types.size() < kMaxTypes) { | 75 while (types.size() < kMaxTypes) { |
| 94 size_t i = rand() % types.size(); | 76 size_t i = rand() % types.size(); |
| 95 size_t j = rand() % types.size(); | 77 size_t j = rand() % types.size(); |
| 96 if (i != j) types.push_back(Type::Union(types[i], types[j], region)); | 78 if (i != j) types.push_back(Type::Union(types[i], types[j], region)); |
| 97 } | 79 } |
| 98 } | 80 } |
| 99 | 81 |
| 100 TypeHandle Representation; | 82 #define DECLARE_TYPE(name, value) TypeHandle name; |
| 101 TypeHandle Semantic; | 83 BITSET_TYPE_LIST(DECLARE_TYPE) |
| 102 TypeHandle None; | 84 #undef DECLARE_TYPE |
| 103 TypeHandle Any; | |
| 104 TypeHandle Boolean; | |
| 105 TypeHandle Null; | |
| 106 TypeHandle Undefined; | |
| 107 TypeHandle Number; | |
| 108 TypeHandle SignedSmall; | |
| 109 TypeHandle Signed32; | |
| 110 TypeHandle Float; | |
| 111 TypeHandle Name; | |
| 112 TypeHandle UniqueName; | |
| 113 TypeHandle String; | |
| 114 TypeHandle InternalizedString; | |
| 115 TypeHandle Symbol; | |
| 116 TypeHandle Receiver; | |
| 117 TypeHandle Object; | |
| 118 TypeHandle Array; | |
| 119 TypeHandle Function; | |
| 120 TypeHandle Proxy; | |
| 121 | 85 |
| 122 TypeHandle ObjectClass; | 86 TypeHandle ObjectClass; |
| 123 TypeHandle ArrayClass; | 87 TypeHandle ArrayClass; |
| 124 | 88 |
| 125 TypeHandle SmiConstant; | 89 TypeHandle SmiConstant; |
| 126 TypeHandle Signed32Constant; | 90 TypeHandle Signed32Constant; |
| 127 TypeHandle ObjectConstant1; | 91 TypeHandle ObjectConstant1; |
| 128 TypeHandle ObjectConstant2; | 92 TypeHandle ObjectConstant2; |
| 129 TypeHandle ArrayConstant1; | 93 TypeHandle ArrayConstant1; |
| 130 TypeHandle ArrayConstant2; | 94 TypeHandle ArrayConstant2; |
| 131 | 95 |
| 132 Handle<i::Map> object_map; | 96 Handle<i::Map> object_map; |
| 133 Handle<i::Map> array_map; | 97 Handle<i::Map> array_map; |
| 134 | 98 |
| 135 Handle<i::Smi> smi; | 99 Handle<i::Smi> smi; |
| 136 Handle<i::HeapNumber> signed32; | 100 Handle<i::HeapNumber> signed32; |
| 137 Handle<i::JSObject> object1; | 101 Handle<i::JSObject> object1; |
| 138 Handle<i::JSObject> object2; | 102 Handle<i::JSObject> object2; |
| 139 Handle<i::JSArray> array; | 103 Handle<i::JSArray> array; |
| 140 | 104 |
| 141 typedef std::vector<TypeHandle> TypeVector; | 105 typedef std::vector<TypeHandle> TypeVector; |
| 142 TypeVector types; | 106 TypeVector types; |
| 143 | 107 |
| 144 typedef std::vector<Handle<i::Object> > ObjectVector; | 108 typedef std::vector<Handle<i::Object> > ObjectVector; |
| 145 ObjectVector objects; | 109 ObjectVector values; |
| 146 | 110 |
| 147 TypeHandle Of(Handle<i::Object> obj) { | 111 TypeHandle Of(Handle<i::Object> obj) { |
| 148 return Type::Of(obj, region_); | 112 return Type::Of(obj, region_); |
| 149 } | 113 } |
| 150 | 114 |
| 151 TypeHandle Constant(Handle<i::Object> obj) { | 115 TypeHandle Constant(Handle<i::Object> obj) { |
| 152 return Type::Constant(obj, region_); | 116 return Type::Constant(obj, region_); |
| 153 } | 117 } |
| 154 | 118 |
| 155 TypeHandle Union(TypeHandle t1, TypeHandle t2) { | 119 TypeHandle Union(TypeHandle t1, TypeHandle t2) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 } | 187 } |
| 224 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } | 188 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } |
| 225 static int Length(Struct* structured) { return structured->length() - 1; } | 189 static int Length(Struct* structured) { return structured->length() - 1; } |
| 226 | 190 |
| 227 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } | 191 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } |
| 228 }; | 192 }; |
| 229 | 193 |
| 230 | 194 |
| 231 template<class Type, class TypeHandle, class Region, class Rep> | 195 template<class Type, class TypeHandle, class Region, class Rep> |
| 232 struct Tests : Rep { | 196 struct Tests : Rep { |
| 197 typedef Types<Type, TypeHandle, Region> TypesInstance; |
| 198 typedef typename TypesInstance::TypeVector::iterator TypeIterator; |
| 199 typedef typename TypesInstance::ObjectVector::iterator ObjectIterator; |
| 200 |
| 233 Isolate* isolate; | 201 Isolate* isolate; |
| 234 HandleScope scope; | 202 HandleScope scope; |
| 235 Zone zone; | 203 Zone zone; |
| 236 Types<Type, TypeHandle, Region> T; | 204 TypesInstance T; |
| 237 typedef typename Types<Type, TypeHandle, Region>::TypeVector::iterator | |
| 238 TypeIterator; | |
| 239 typedef typename Types<Type, TypeHandle, Region>::ObjectVector::iterator | |
| 240 ObjectIterator; | |
| 241 | 205 |
| 242 Tests() : | 206 Tests() : |
| 243 isolate(CcTest::i_isolate()), | 207 isolate(CcTest::i_isolate()), |
| 244 scope(isolate), | 208 scope(isolate), |
| 245 zone(isolate), | 209 zone(isolate), |
| 246 T(Rep::ToRegion(&zone, isolate), isolate) { | 210 T(Rep::ToRegion(&zone, isolate), isolate) { |
| 247 } | 211 } |
| 248 | 212 |
| 249 void CheckEqual(TypeHandle type1, TypeHandle type2) { | 213 void CheckEqual(TypeHandle type1, TypeHandle type2) { |
| 250 CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2)); | 214 CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2)); |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 } | 472 } |
| 509 } | 473 } |
| 510 | 474 |
| 511 CHECK(T.ObjectConstant1->NowIs(T.ObjectClass)); | 475 CHECK(T.ObjectConstant1->NowIs(T.ObjectClass)); |
| 512 CHECK(T.ObjectConstant2->NowIs(T.ObjectClass)); | 476 CHECK(T.ObjectConstant2->NowIs(T.ObjectClass)); |
| 513 } | 477 } |
| 514 | 478 |
| 515 void Contains() { | 479 void Contains() { |
| 516 // T->Contains(O) iff Constant(O)->Is(T) for all T,O | 480 // T->Contains(O) iff Constant(O)->Is(T) for all T,O |
| 517 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 481 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 518 for (ObjectIterator ot = T.objects.begin(); ot != T.objects.end(); ++ot) { | 482 for (ObjectIterator ot = T.values.begin(); ot != T.values.end(); ++ot) { |
| 519 TypeHandle type = *it; | 483 TypeHandle type = *it; |
| 520 Handle<i::Object> obj = *ot; | 484 Handle<i::Object> obj = *ot; |
| 521 CHECK(type->Contains(obj) == T.Constant(obj)->Is(type)); | 485 CHECK(type->Contains(obj) == T.Constant(obj)->Is(type)); |
| 522 } | 486 } |
| 523 } | 487 } |
| 524 | 488 |
| 525 // Of(O)->Is(T) implies T->Contains(O) for all T,O | 489 // Of(O)->Is(T) implies T->Contains(O) for all T,O |
| 526 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 490 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 527 for (ObjectIterator ot = T.objects.begin(); ot != T.objects.end(); ++ot) { | 491 for (ObjectIterator ot = T.values.begin(); ot != T.values.end(); ++ot) { |
| 528 TypeHandle type = *it; | 492 TypeHandle type = *it; |
| 529 Handle<i::Object> obj = *ot; | 493 Handle<i::Object> obj = *ot; |
| 530 CHECK(!T.Of(obj)->Is(type) || type->Contains(obj)); | 494 CHECK(!T.Of(obj)->Is(type) || type->Contains(obj)); |
| 531 } | 495 } |
| 532 } | 496 } |
| 533 } | 497 } |
| 534 | 498 |
| 535 void Maybe() { | 499 void Maybe() { |
| 536 // T->Maybe(T) for all inhabited T | 500 // T->Maybe(T) for all inhabited T |
| 537 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 501 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 538 TypeHandle type = *it; | 502 TypeHandle type = *it; |
| 539 CHECK(type->Maybe(type) || !type->IsInhabited()); | 503 CHECK(type->Maybe(type) || !type->IsInhabited()); |
| 540 } | 504 } |
| 541 | 505 |
| 542 // Commutativity | 506 // Symmetry |
| 543 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 507 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 544 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 508 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 545 TypeHandle type1 = *it1; | 509 TypeHandle type1 = *it1; |
| 546 TypeHandle type2 = *it2; | 510 TypeHandle type2 = *it2; |
| 547 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); | 511 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); |
| 548 } | 512 } |
| 549 } | 513 } |
| 550 | 514 |
| 551 // T1->Is(T2) implies T1->Maybe(T2) or T1 is uninhabited for all T1,T2 | 515 // T1->Is(T2) implies T1->Maybe(T2) or T1 is uninhabited for all T1,T2 |
| 552 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 516 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 ZoneTests().Intersect(); | 1003 ZoneTests().Intersect(); |
| 1040 HeapTests().Intersect(); | 1004 HeapTests().Intersect(); |
| 1041 } | 1005 } |
| 1042 | 1006 |
| 1043 | 1007 |
| 1044 TEST(Convert) { | 1008 TEST(Convert) { |
| 1045 CcTest::InitializeVM(); | 1009 CcTest::InitializeVM(); |
| 1046 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 1010 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
| 1047 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 1011 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
| 1048 } | 1012 } |
| OLD | NEW |