1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "utils/random-number-generator.h"
34 using namespace v8::internal;
36 // Testing auxiliaries (breaking the Type abstraction).
38 typedef ZoneList<void*> Struct;
40 static bool IsStruct(Type* t, int tag) {
42 && reinterpret_cast<intptr_t>(AsStruct(t)->at(0)) == tag;
44 static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
45 static bool IsClass(Type* t) { return IsStruct(t, 0); }
46 static bool IsConstant(Type* t) { return IsStruct(t, 1); }
47 static bool IsUnion(Type* t) { return IsStruct(t, 2); }
49 static Struct* AsStruct(Type* t) {
50 return reinterpret_cast<Struct*>(t);
52 static int AsBitset(Type* t) {
53 return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1);
55 static Map* AsClass(Type* t) {
56 return *static_cast<Map**>(AsStruct(t)->at(2));
58 static Object* AsConstant(Type* t) {
59 return *static_cast<Object**>(AsStruct(t)->at(2));
61 static Struct* AsUnion(Type* t) {
64 static int Length(Struct* structured) { return structured->length() - 2; }
66 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
71 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
72 static bool IsClass(Handle<HeapType> t) { return t->IsMap(); }
73 static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); }
74 static bool IsUnion(Handle<HeapType> t) { return t->IsFixedArray(); }
76 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
77 static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); }
78 static Object* AsConstant(Handle<HeapType> t) {
79 return Box::cast(*t)->value();
81 static FixedArray* AsUnion(Handle<HeapType> t) {
82 return FixedArray::cast(*t);
84 static int Length(FixedArray* structured) { return structured->length(); }
86 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
90 template<class Type, class TypeHandle, class Region>
93 Types(Region* region, Isolate* isolate) : region_(region) {
94 #define DECLARE_TYPE(name, value) \
95 name = Type::name(region); \
96 types.push_back(name);
97 BITSET_TYPE_LIST(DECLARE_TYPE)
100 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize);
101 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize);
102 ObjectClass = Type::Class(object_map, region);
103 ArrayClass = Type::Class(array_map, region);
105 maps.push_back(object_map);
106 maps.push_back(array_map);
107 for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
108 types.push_back(Type::Class(*it, region));
111 smi = handle(Smi::FromInt(666), isolate);
112 signed32 = isolate->factory()->NewHeapNumber(0x40000000);
113 object1 = isolate->factory()->NewJSObjectFromMap(object_map);
114 object2 = isolate->factory()->NewJSObjectFromMap(object_map);
115 array = isolate->factory()->NewJSArray(20);
116 SmiConstant = Type::Constant(smi, region);
117 Signed32Constant = Type::Constant(signed32, region);
118 ObjectConstant1 = Type::Constant(object1, region);
119 ObjectConstant2 = Type::Constant(object2, region);
120 ArrayConstant = Type::Constant(array, region);
122 values.push_back(smi);
123 values.push_back(signed32);
124 values.push_back(object1);
125 values.push_back(object2);
126 values.push_back(array);
127 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
128 types.push_back(Type::Constant(*it, region));
131 for (int i = 0; i < 50; ++i) {
132 types.push_back(Fuzz());
136 Handle<i::Map> object_map;
137 Handle<i::Map> array_map;
140 Handle<i::HeapNumber> signed32;
141 Handle<i::JSObject> object1;
142 Handle<i::JSObject> object2;
143 Handle<i::JSArray> array;
145 #define DECLARE_TYPE(name, value) TypeHandle name;
146 BITSET_TYPE_LIST(DECLARE_TYPE)
149 TypeHandle ObjectClass;
150 TypeHandle ArrayClass;
152 TypeHandle SmiConstant;
153 TypeHandle Signed32Constant;
154 TypeHandle ObjectConstant1;
155 TypeHandle ObjectConstant2;
156 TypeHandle ArrayConstant;
158 typedef std::vector<TypeHandle> TypeVector;
159 typedef std::vector<Handle<i::Map> > MapVector;
160 typedef std::vector<Handle<i::Object> > ValueVector;
165 TypeHandle Of(Handle<i::Object> value) {
166 return Type::Of(value, region_);
169 TypeHandle NowOf(Handle<i::Object> value) {
170 return Type::NowOf(value, region_);
173 TypeHandle Constant(Handle<i::Object> value) {
174 return Type::Constant(value, region_);
177 TypeHandle Class(Handle<i::Map> map) {
178 return Type::Class(map, region_);
181 TypeHandle Union(TypeHandle t1, TypeHandle t2) {
182 return Type::Union(t1, t2, region_);
184 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
185 return Type::Intersect(t1, t2, region_);
188 template<class Type2, class TypeHandle2>
189 TypeHandle Convert(TypeHandle2 t) {
190 return Type::template Convert<Type2>(t, region_);
193 TypeHandle Random() {
194 return types[rng_.NextInt(static_cast<int>(types.size()))];
197 TypeHandle Fuzz(int depth = 5) {
198 switch (rng_.NextInt(depth == 0 ? 3 : 20)) {
201 #define COUNT_BITSET_TYPES(type, value) + 1
202 BITSET_TYPE_LIST(COUNT_BITSET_TYPES)
203 #undef COUNT_BITSET_TYPES
205 int i = rng_.NextInt(n);
206 #define PICK_BITSET_TYPE(type, value) \
207 if (i-- == 0) return Type::type(region_);
208 BITSET_TYPE_LIST(PICK_BITSET_TYPE)
209 #undef PICK_BITSET_TYPE
213 int i = rng_.NextInt(static_cast<int>(maps.size()));
214 return Type::Class(maps[i], region_);
216 case 2: { // constant
217 int i = rng_.NextInt(static_cast<int>(values.size()));
218 return Type::Constant(values[i], region_);
221 int n = rng_.NextInt(10);
222 TypeHandle type = None;
223 for (int i = 0; i < n; ++i) {
224 TypeHandle operand = Fuzz(depth - 1);
225 type = Type::Union(type, operand, region_);
235 RandomNumberGenerator rng_;
239 template<class Type, class TypeHandle, class Region, class Rep>
241 typedef Types<Type, TypeHandle, Region> TypesInstance;
242 typedef typename TypesInstance::TypeVector::iterator TypeIterator;
243 typedef typename TypesInstance::MapVector::iterator MapIterator;
244 typedef typename TypesInstance::ValueVector::iterator ValueIterator;
252 isolate(CcTest::i_isolate()),
255 T(Rep::ToRegion(&zone, isolate), isolate) {
258 bool Equal(TypeHandle type1, TypeHandle type2) {
260 type1->Is(type2) && type2->Is(type1) &&
261 Rep::IsBitset(type1) == Rep::IsBitset(type2) &&
262 Rep::IsClass(type1) == Rep::IsClass(type2) &&
263 Rep::IsConstant(type1) == Rep::IsConstant(type2) &&
264 Rep::IsUnion(type1) == Rep::IsUnion(type2) &&
265 type1->NumClasses() == type2->NumClasses() &&
266 type1->NumConstants() == type2->NumConstants() &&
267 (!Rep::IsBitset(type1) ||
268 Rep::AsBitset(type1) == Rep::AsBitset(type2)) &&
269 (!Rep::IsClass(type1) ||
270 Rep::AsClass(type1) == Rep::AsClass(type2)) &&
271 (!Rep::IsConstant(type1) ||
272 Rep::AsConstant(type1) == Rep::AsConstant(type2)) &&
273 (!Rep::IsUnion(type1) ||
274 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2)));
277 void CheckEqual(TypeHandle type1, TypeHandle type2) {
278 CHECK(Equal(type1, type2));
281 void CheckSub(TypeHandle type1, TypeHandle type2) {
282 CHECK(type1->Is(type2));
283 CHECK(!type2->Is(type1));
284 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
285 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
289 void CheckUnordered(TypeHandle type1, TypeHandle type2) {
290 CHECK(!type1->Is(type2));
291 CHECK(!type2->Is(type1));
292 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
293 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
297 void CheckOverlap(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
298 CHECK(type1->Maybe(type2));
299 CHECK(type2->Maybe(type1));
300 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
302 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask));
306 void CheckDisjoint(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
307 CHECK(!type1->Is(type2));
308 CHECK(!type2->Is(type1));
309 CHECK(!type1->Maybe(type2));
310 CHECK(!type2->Maybe(type1));
311 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
313 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask));
318 // None and Any are bitsets.
319 CHECK(this->IsBitset(T.None));
320 CHECK(this->IsBitset(T.Any));
322 CHECK_EQ(0, this->AsBitset(T.None));
323 CHECK_EQ(-1, this->AsBitset(T.Any));
325 // Union(T1, T2) is bitset for bitsets T1,T2
326 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
327 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
328 TypeHandle type1 = *it1;
329 TypeHandle type2 = *it2;
330 TypeHandle union12 = T.Union(type1, type2);
331 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
332 this->IsBitset(union12));
336 // Intersect(T1, T2) is bitset for bitsets T1,T2
337 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
338 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
339 TypeHandle type1 = *it1;
340 TypeHandle type2 = *it2;
341 TypeHandle intersect12 = T.Intersect(type1, type2);
342 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
343 this->IsBitset(intersect12));
347 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2)
348 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
349 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
350 TypeHandle type1 = *it1;
351 TypeHandle type2 = *it2;
352 TypeHandle union12 = T.Union(type1, type2);
353 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) ||
354 this->IsBitset(union12));
358 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2
359 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
360 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
361 TypeHandle type1 = *it1;
362 TypeHandle type2 = *it2;
363 TypeHandle union12 = T.Union(type1, type2);
364 if (this->IsBitset(type1) && this->IsBitset(type2)) {
366 this->AsBitset(type1) | this->AsBitset(type2),
367 this->AsBitset(union12));
372 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2
373 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
374 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
375 TypeHandle type1 = *it1;
376 TypeHandle type2 = *it2;
377 TypeHandle intersect12 = T.Intersect(type1, type2);
378 if (this->IsBitset(type1) && this->IsBitset(type2)) {
380 this->AsBitset(type1) & this->AsBitset(type2),
381 this->AsBitset(intersect12));
389 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
390 Handle<i::Map> map = *mt;
391 TypeHandle type = T.Class(map);
392 CHECK(this->IsClass(type));
396 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
397 Handle<i::Map> map = *mt;
398 TypeHandle type = T.Class(map);
399 CHECK(*map == *type->AsClass());
402 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2
403 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
404 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
405 Handle<i::Map> map1 = *mt1;
406 Handle<i::Map> map2 = *mt2;
407 TypeHandle type1 = T.Class(map1);
408 TypeHandle type2 = T.Class(map2);
409 CHECK(Equal(type1, type2) == (*map1 == *map2));
416 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
417 Handle<i::Object> value = *vt;
418 TypeHandle type = T.Constant(value);
419 CHECK(this->IsConstant(type));
423 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
424 Handle<i::Object> value = *vt;
425 TypeHandle type = T.Constant(value);
426 CHECK(*value == *type->AsConstant());
429 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2
430 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
431 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
432 Handle<i::Object> value1 = *vt1;
433 Handle<i::Object> value2 = *vt2;
434 TypeHandle type1 = T.Constant(value1);
435 TypeHandle type2 = T.Constant(value2);
436 CHECK(Equal(type1, type2) == (*value1 == *value2));
442 // Constant(V)->Is(Of(V))
443 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
444 Handle<i::Object> value = *vt;
445 TypeHandle const_type = T.Constant(value);
446 TypeHandle of_type = T.Of(value);
447 CHECK(const_type->Is(of_type));
450 // Constant(V)->Is(T) iff Of(V)->Is(T) or T->Maybe(Constant(V))
451 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
452 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
453 Handle<i::Object> value = *vt;
454 TypeHandle type = *it;
455 TypeHandle const_type = T.Constant(value);
456 TypeHandle of_type = T.Of(value);
457 CHECK(const_type->Is(type) ==
458 (of_type->Is(type) || type->Maybe(const_type)));
464 // Least Element (Bottom): None->Is(T)
465 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
466 TypeHandle type = *it;
467 CHECK(T.None->Is(type));
470 // Greatest Element (Top): T->Is(Any)
471 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
472 TypeHandle type = *it;
473 CHECK(type->Is(T.Any));
476 // Bottom Uniqueness: T->Is(None) implies T = None
477 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
478 TypeHandle type = *it;
479 if (type->Is(T.None)) CheckEqual(type, T.None);
482 // Top Uniqueness: Any->Is(T) implies T = Any
483 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
484 TypeHandle type = *it;
485 if (T.Any->Is(type)) CheckEqual(type, T.Any);
488 // Reflexivity: T->Is(T)
489 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
490 TypeHandle type = *it;
491 CHECK(type->Is(type));
494 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3)
495 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
496 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
497 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
498 TypeHandle type1 = *it1;
499 TypeHandle type2 = *it2;
500 TypeHandle type3 = *it3;
501 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3));
506 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2
507 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
508 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
509 TypeHandle type1 = *it1;
510 TypeHandle type2 = *it2;
511 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2));
515 // Constant(V1)->Is(Constant(V2)) iff V1 = V2
516 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
517 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
518 Handle<i::Object> value1 = *vt1;
519 Handle<i::Object> value2 = *vt2;
520 TypeHandle const_type1 = T.Constant(value1);
521 TypeHandle const_type2 = T.Constant(value2);
522 CHECK(const_type1->Is(const_type2) == (*value1 == *value2));
526 // Class(M1)->Is(Class(M2)) iff M1 = M2
527 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
528 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
529 Handle<i::Map> map1 = *mt1;
530 Handle<i::Map> map2 = *mt2;
531 TypeHandle class_type1 = T.Class(map1);
532 TypeHandle class_type2 = T.Class(map2);
533 CHECK(class_type1->Is(class_type2) == (*map1 == *map2));
537 // Constant(V)->Is(Class(M)) never
538 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
539 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
540 Handle<i::Map> map = *mt;
541 Handle<i::Object> value = *vt;
542 TypeHandle constant_type = T.Constant(value);
543 TypeHandle class_type = T.Class(map);
544 CHECK(!constant_type->Is(class_type));
548 // Class(M)->Is(Constant(V)) never
549 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
550 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
551 Handle<i::Map> map = *mt;
552 Handle<i::Object> value = *vt;
553 TypeHandle constant_type = T.Constant(value);
554 TypeHandle class_type = T.Class(map);
555 CHECK(!class_type->Is(constant_type));
560 CheckUnordered(T.Boolean, T.Null);
561 CheckUnordered(T.Undefined, T.Null);
562 CheckUnordered(T.Boolean, T.Undefined);
564 CheckSub(T.SignedSmall, T.Number);
565 CheckSub(T.Signed32, T.Number);
566 CheckSub(T.Float, T.Number);
567 CheckSub(T.SignedSmall, T.Signed32);
568 CheckUnordered(T.SignedSmall, T.Float);
569 CheckUnordered(T.Signed32, T.Float);
571 CheckSub(T.UniqueName, T.Name);
572 CheckSub(T.String, T.Name);
573 CheckSub(T.InternalizedString, T.String);
574 CheckSub(T.InternalizedString, T.UniqueName);
575 CheckSub(T.InternalizedString, T.Name);
576 CheckSub(T.Symbol, T.UniqueName);
577 CheckSub(T.Symbol, T.Name);
578 CheckUnordered(T.String, T.UniqueName);
579 CheckUnordered(T.String, T.Symbol);
580 CheckUnordered(T.InternalizedString, T.Symbol);
582 CheckSub(T.Object, T.Receiver);
583 CheckSub(T.Array, T.Object);
584 CheckSub(T.Function, T.Object);
585 CheckSub(T.Proxy, T.Receiver);
586 CheckUnordered(T.Object, T.Proxy);
587 CheckUnordered(T.Array, T.Function);
590 CheckSub(T.ObjectClass, T.Object);
591 CheckSub(T.ArrayClass, T.Object);
592 CheckSub(T.ArrayClass, T.Array);
593 CheckUnordered(T.ObjectClass, T.ArrayClass);
595 CheckSub(T.SmiConstant, T.SignedSmall);
596 CheckSub(T.SmiConstant, T.Signed32);
597 CheckSub(T.SmiConstant, T.Number);
598 CheckSub(T.ObjectConstant1, T.Object);
599 CheckSub(T.ObjectConstant2, T.Object);
600 CheckSub(T.ArrayConstant, T.Object);
601 CheckSub(T.ArrayConstant, T.Array);
602 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
603 CheckUnordered(T.ObjectConstant1, T.ArrayConstant);
605 CheckUnordered(T.ObjectConstant1, T.ObjectClass);
606 CheckUnordered(T.ObjectConstant2, T.ObjectClass);
607 CheckUnordered(T.ObjectConstant1, T.ArrayClass);
608 CheckUnordered(T.ObjectConstant2, T.ArrayClass);
609 CheckUnordered(T.ArrayConstant, T.ObjectClass);
613 // T->Maybe(None) never
614 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
615 TypeHandle type = *it;
616 CHECK(!type->Maybe(T.None));
619 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1)
620 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
621 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
622 TypeHandle type1 = *it1;
623 TypeHandle type2 = *it2;
624 CHECK(type1->Maybe(type2) == type2->Maybe(type1));
628 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2
629 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
630 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
631 Handle<i::Object> value1 = *vt1;
632 Handle<i::Object> value2 = *vt2;
633 TypeHandle const_type1 = T.Constant(value1);
634 TypeHandle const_type2 = T.Constant(value2);
635 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2));
639 // Class(M1)->Maybe(Class(M2)) iff M1 = M2
640 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
641 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
642 Handle<i::Map> map1 = *mt1;
643 Handle<i::Map> map2 = *mt2;
644 TypeHandle class_type1 = T.Class(map1);
645 TypeHandle class_type2 = T.Class(map2);
646 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2));
650 // Constant(V)->Maybe(Class(M)) never
651 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
652 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
653 Handle<i::Map> map = *mt;
654 Handle<i::Object> value = *vt;
655 TypeHandle const_type = T.Constant(value);
656 TypeHandle class_type = T.Class(map);
657 CHECK(!const_type->Maybe(class_type));
661 // Class(M)->Maybe(Constant(V)) never
662 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
663 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
664 Handle<i::Map> map = *mt;
665 Handle<i::Object> value = *vt;
666 TypeHandle const_type = T.Constant(value);
667 TypeHandle class_type = T.Class(map);
668 CHECK(!class_type->Maybe(const_type));
673 CheckDisjoint(T.Boolean, T.Null, T.Semantic);
674 CheckDisjoint(T.Undefined, T.Null, T.Semantic);
675 CheckDisjoint(T.Boolean, T.Undefined, T.Semantic);
677 CheckOverlap(T.SignedSmall, T.Number, T.Semantic);
678 CheckOverlap(T.Float, T.Number, T.Semantic);
679 CheckDisjoint(T.Signed32, T.Float, T.Semantic);
681 CheckOverlap(T.UniqueName, T.Name, T.Semantic);
682 CheckOverlap(T.String, T.Name, T.Semantic);
683 CheckOverlap(T.InternalizedString, T.String, T.Semantic);
684 CheckOverlap(T.InternalizedString, T.UniqueName, T.Semantic);
685 CheckOverlap(T.InternalizedString, T.Name, T.Semantic);
686 CheckOverlap(T.Symbol, T.UniqueName, T.Semantic);
687 CheckOverlap(T.Symbol, T.Name, T.Semantic);
688 CheckOverlap(T.String, T.UniqueName, T.Semantic);
689 CheckDisjoint(T.String, T.Symbol, T.Semantic);
690 CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic);
692 CheckOverlap(T.Object, T.Receiver, T.Semantic);
693 CheckOverlap(T.Array, T.Object, T.Semantic);
694 CheckOverlap(T.Function, T.Object, T.Semantic);
695 CheckOverlap(T.Proxy, T.Receiver, T.Semantic);
696 CheckDisjoint(T.Object, T.Proxy, T.Semantic);
697 CheckDisjoint(T.Array, T.Function, T.Semantic);
700 CheckOverlap(T.ObjectClass, T.Object, T.Semantic);
701 CheckOverlap(T.ArrayClass, T.Object, T.Semantic);
702 CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic);
703 CheckOverlap(T.ArrayClass, T.ArrayClass, T.Semantic);
704 CheckDisjoint(T.ObjectClass, T.ArrayClass, T.Semantic);
706 CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic);
707 CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic);
708 CheckOverlap(T.SmiConstant, T.Number, T.Semantic);
709 CheckDisjoint(T.SmiConstant, T.Float, T.Semantic);
710 CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic);
711 CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic);
712 CheckOverlap(T.ArrayConstant, T.Object, T.Semantic);
713 CheckOverlap(T.ArrayConstant, T.Array, T.Semantic);
714 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1, T.Semantic);
715 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2, T.Semantic);
716 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic);
718 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic);
719 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic);
720 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic);
721 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic);
722 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic);
726 // Identity: Union(T, None) = T
727 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
728 TypeHandle type = *it;
729 TypeHandle union_type = T.Union(type, T.None);
730 CheckEqual(union_type, type);
733 // Domination: Union(T, Any) = Any
734 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
735 TypeHandle type = *it;
736 TypeHandle union_type = T.Union(type, T.Any);
737 CheckEqual(union_type, T.Any);
740 // Idempotence: Union(T, T) = T
741 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
742 TypeHandle type = *it;
743 TypeHandle union_type = T.Union(type, type);
744 CheckEqual(union_type, type);
747 // Commutativity: Union(T1, T2) = Union(T2, T1)
748 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
749 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
750 TypeHandle type1 = *it1;
751 TypeHandle type2 = *it2;
752 TypeHandle union12 = T.Union(type1, type2);
753 TypeHandle union21 = T.Union(type2, type1);
754 CheckEqual(union12, union21);
758 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3)
759 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
760 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
761 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
762 TypeHandle type1 = *it1;
763 TypeHandle type2 = *it2;
764 TypeHandle type3 = *it3;
765 TypeHandle union12 = T.Union(type1, type2);
766 TypeHandle union23 = T.Union(type2, type3);
767 TypeHandle union1_23 = T.Union(type1, union23);
768 TypeHandle union12_3 = T.Union(union12, type3);
769 CheckEqual(union1_23, union12_3);
774 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2))
775 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
776 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
777 TypeHandle type1 = *it1;
778 TypeHandle type2 = *it2;
779 TypeHandle union12 = T.Union(type1, type2);
780 CHECK(type1->Is(union12));
781 CHECK(type2->Is(union12));
785 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2
786 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
787 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
788 TypeHandle type1 = *it1;
789 TypeHandle type2 = *it2;
790 TypeHandle union12 = T.Union(type1, type2);
791 if (type1->Is(type2)) CheckEqual(union12, type2);
797 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3))
798 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
799 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
800 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
801 TypeHandle type1 = *it1;
802 TypeHandle type2 = *it2;
803 TypeHandle type3 = *it3;
804 TypeHandle union13 = T.Union(type1, type3);
805 TypeHandle union23 = T.Union(type2, type3);
806 CHECK(!type1->Is(type2) || union13->Is(union23));
811 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3)
812 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
813 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
814 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
815 TypeHandle type1 = *it1;
816 TypeHandle type2 = *it2;
817 TypeHandle type3 = *it3;
818 TypeHandle union12 = T.Union(type1, type2);
819 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3));
824 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
825 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
826 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
827 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
828 TypeHandle type1 = *it1;
829 TypeHandle type2 = *it2;
830 TypeHandle type3 = *it3;
831 TypeHandle union23 = T.Union(type2, type3);
832 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23));
838 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
839 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
840 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic);
841 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic);
844 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
845 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
847 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
849 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic);
851 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic);
853 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic);
857 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number));
858 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
859 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
860 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic);
861 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic);
865 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
866 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
867 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
868 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic);
869 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic);
872 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
873 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
875 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
876 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant);
878 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2,
881 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic);
886 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
888 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float),
889 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
893 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
896 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
897 T.Union(T.ArrayClass, T.ObjectConstant2));
902 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
903 T.Union(T.ObjectConstant2, T.ObjectConstant1));
906 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1),
908 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
913 T.Union(T.ObjectConstant2, T.ObjectConstant1),
914 T.Union(T.ObjectConstant1, T.ObjectConstant2)),
915 T.Union(T.ObjectConstant2, T.ObjectConstant1));
918 T.Union(T.Number, T.ArrayClass),
919 T.Union(T.SignedSmall, T.Array)),
920 T.Union(T.Number, T.Array));
924 // Identity: Intersect(T, Any) = T
925 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
926 TypeHandle type = *it;
927 TypeHandle intersect_type = T.Intersect(type, T.Any);
928 CheckEqual(intersect_type, type);
931 // Domination: Intersect(T, None) = None
932 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
933 TypeHandle type = *it;
934 TypeHandle intersect_type = T.Intersect(type, T.None);
935 CheckEqual(intersect_type, T.None);
938 // Idempotence: Intersect(T, T) = T
939 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
940 TypeHandle type = *it;
941 TypeHandle intersect_type = T.Intersect(type, type);
942 CheckEqual(intersect_type, type);
945 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1)
946 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
947 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
948 TypeHandle type1 = *it1;
949 TypeHandle type2 = *it2;
950 TypeHandle intersect12 = T.Intersect(type1, type2);
951 TypeHandle intersect21 = T.Intersect(type2, type1);
952 CheckEqual(intersect12, intersect21);
957 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3)
958 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
959 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
960 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
961 TypeHandle type1 = *it1;
962 TypeHandle type2 = *it2;
963 TypeHandle type3 = *it3;
964 TypeHandle intersect12 = T.Intersect(type1, type2);
965 TypeHandle intersect23 = T.Intersect(type2, type3);
966 TypeHandle intersect1_23 = T.Intersect(type1, intersect23);
967 TypeHandle intersect12_3 = T.Intersect(intersect12, type3);
968 CheckEqual(intersect1_23, intersect12_3);
973 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2)
974 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
975 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
976 TypeHandle type1 = *it1;
977 TypeHandle type2 = *it2;
978 TypeHandle intersect12 = T.Intersect(type1, type2);
979 CHECK(intersect12->Is(type1));
980 CHECK(intersect12->Is(type2));
984 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1
985 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
986 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
987 TypeHandle type1 = *it1;
988 TypeHandle type2 = *it2;
989 TypeHandle intersect12 = T.Intersect(type1, type2);
990 if (type1->Is(type2)) CheckEqual(intersect12, type1);
996 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3))
997 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
998 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
999 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1000 TypeHandle type1 = *it1;
1001 TypeHandle type2 = *it2;
1002 TypeHandle type3 = *it3;
1003 TypeHandle intersect13 = T.Intersect(type1, type3);
1004 TypeHandle intersect23 = T.Intersect(type2, type3);
1005 CHECK(!type1->Is(type2) || intersect13->Is(intersect23));
1010 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3)
1011 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1012 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1013 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1014 TypeHandle type1 = *it1;
1015 TypeHandle type2 = *it2;
1016 TypeHandle type3 = *it3;
1017 TypeHandle intersect12 = T.Intersect(type1, type2);
1018 CHECK(!(type1->Is(type3) || type2->Is(type3)) ||
1019 intersect12->Is(type3));
1024 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
1025 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1026 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1027 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1028 TypeHandle type1 = *it1;
1029 TypeHandle type2 = *it2;
1030 TypeHandle type3 = *it3;
1031 TypeHandle intersect23 = T.Intersect(type2, type3);
1032 CHECK(!(type1->Is(type2) && type1->Is(type3)) ||
1033 type1->Is(intersect23));
1039 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
1040 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation);
1041 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation);
1045 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
1046 T.Union(T.ObjectConstant1, T.ObjectClass));
1048 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
1052 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
1053 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
1057 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
1060 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
1063 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass),
1069 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1072 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
1076 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1),
1082 T.Union(T.Number, T.ArrayClass),
1083 T.Union(T.SignedSmall, T.Array)),
1084 T.Union(T.SignedSmall, T.ArrayClass));
1087 T.Union(T.Number, T.ObjectClass),
1088 T.Union(T.Signed32, T.Array)),
1092 T.Union(T.ObjectConstant2, T.ObjectConstant1),
1093 T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1094 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1098 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
1101 T.Union(T.ArrayConstant, T.ObjectConstant2))),
1102 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1105 template<class Type2, class TypeHandle2, class Region2, class Rep2>
1107 Types<Type2, TypeHandle2, Region2> T2(
1108 Rep2::ToRegion(&zone, isolate), isolate);
1109 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1110 TypeHandle type1 = *it;
1111 TypeHandle2 type2 = T2.template Convert<Type>(type1);
1112 TypeHandle type3 = T.template Convert<Type2>(type2);
1113 CheckEqual(type1, type3);
1118 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
1119 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
1123 CcTest::InitializeVM();
1124 ZoneTests().Bitset();
1125 HeapTests().Bitset();
1130 CcTest::InitializeVM();
1131 ZoneTests().Class();
1132 HeapTests().Class();
1136 TEST(ConstantType) {
1137 CcTest::InitializeVM();
1138 ZoneTests().Constant();
1139 HeapTests().Constant();
1144 CcTest::InitializeVM();
1151 CcTest::InitializeVM();
1158 CcTest::InitializeVM();
1159 ZoneTests().Maybe();
1160 HeapTests().Maybe();
1165 CcTest::InitializeVM();
1166 ZoneTests().Union1();
1167 HeapTests().Union1();
1172 CcTest::InitializeVM();
1173 ZoneTests().Union2();
1174 HeapTests().Union2();
1179 CcTest::InitializeVM();
1180 ZoneTests().Intersect1();
1181 HeapTests().Intersect1();
1186 CcTest::InitializeVM();
1187 ZoneTests().Intersect2();
1188 HeapTests().Intersect2();
1193 CcTest::InitializeVM();
1194 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
1195 HeapTests().Convert<Type, Type*, Zone, ZoneRep>();