Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(583)

Side by Side Diff: test/cctest/test-types.cc

Issue 577563002: Re-reland "Use unsigned type bitsets to limit undefined behaviour" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/types-inl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 typedef uint32_t bitset;
16
15 struct ZoneRep { 17 struct ZoneRep {
16 typedef void* Struct; 18 typedef void* Struct;
17 19
18 static bool IsStruct(Type* t, int tag) { 20 static bool IsStruct(Type* t, int tag) {
19 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; 21 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
20 } 22 }
21 static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } 23 static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; }
22 static bool IsUnion(Type* t) { return IsStruct(t, 6); } 24 static bool IsUnion(Type* t) { return IsStruct(t, 6); }
23 25
24 static Struct* AsStruct(Type* t) { 26 static Struct* AsStruct(Type* t) {
25 return reinterpret_cast<Struct*>(t); 27 return reinterpret_cast<Struct*>(t);
26 } 28 }
27 static int AsBitset(Type* t) { 29 static bitset AsBitset(Type* t) {
28 return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); 30 return static_cast<bitset>(reinterpret_cast<uintptr_t>(t) ^ 1u);
29 } 31 }
30 static Struct* AsUnion(Type* t) { 32 static Struct* AsUnion(Type* t) {
31 return AsStruct(t); 33 return AsStruct(t);
32 } 34 }
33 static int Length(Struct* structured) { 35 static int Length(Struct* structured) {
34 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1])); 36 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1]));
35 } 37 }
36 38
37 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } 39 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
38 40
39 struct BitsetType : Type::BitsetType { 41 struct BitsetType : Type::BitsetType {
40 using Type::BitsetType::New; 42 using Type::BitsetType::New;
41 using Type::BitsetType::Glb; 43 using Type::BitsetType::Glb;
42 using Type::BitsetType::Lub; 44 using Type::BitsetType::Lub;
43 using Type::BitsetType::InherentLub; 45 using Type::BitsetType::InherentLub;
44 }; 46 };
45 }; 47 };
46 48
47 49
48 struct HeapRep { 50 struct HeapRep {
49 typedef FixedArray Struct; 51 typedef FixedArray Struct;
50 52
51 static bool IsStruct(Handle<HeapType> t, int tag) { 53 static bool IsStruct(Handle<HeapType> t, int tag) {
52 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; 54 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
53 } 55 }
54 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } 56 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
55 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); } 57 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); }
56 58
57 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } 59 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
58 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } 60 static bitset AsBitset(Handle<HeapType> t) {
61 return static_cast<bitset>(reinterpret_cast<uintptr_t>(*t));
62 }
59 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } 63 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
60 static int Length(Struct* structured) { return structured->length() - 1; } 64 static int Length(Struct* structured) { return structured->length() - 1; }
61 65
62 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } 66 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
63 67
64 struct BitsetType : HeapType::BitsetType { 68 struct BitsetType : HeapType::BitsetType {
65 using HeapType::BitsetType::New; 69 using HeapType::BitsetType::New;
66 using HeapType::BitsetType::Glb; 70 using HeapType::BitsetType::Glb;
67 using HeapType::BitsetType::Lub; 71 using HeapType::BitsetType::Lub;
68 using HeapType::BitsetType::InherentLub; 72 using HeapType::BitsetType::InherentLub;
69 static int Glb(Handle<HeapType> type) { return Glb(*type); } 73 static bitset Glb(Handle<HeapType> type) { return Glb(*type); }
70 static int Lub(Handle<HeapType> type) { return Lub(*type); } 74 static bitset Lub(Handle<HeapType> type) { return Lub(*type); }
71 static int InherentLub(Handle<HeapType> type) { return InherentLub(*type); } 75 static bitset InherentLub(Handle<HeapType> type) {
76 return InherentLub(*type);
77 }
72 }; 78 };
73 }; 79 };
74 80
75 81
76 template<class Type, class TypeHandle, class Region> 82 template<class Type, class TypeHandle, class Region>
77 class Types { 83 class Types {
78 public: 84 public:
79 Types(Region* region, Isolate* isolate) 85 Types(Region* region, Isolate* isolate)
80 : region_(region), rng_(isolate->random_number_generator()) { 86 : region_(region), rng_(isolate->random_number_generator()) {
81 #define DECLARE_TYPE(name, value) \ 87 #define DECLARE_TYPE(name, value) \
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 } 364 }
359 365
360 void CheckEqual(TypeHandle type1, TypeHandle type2) { 366 void CheckEqual(TypeHandle type1, TypeHandle type2) {
361 CHECK(Equal(type1, type2)); 367 CHECK(Equal(type1, type2));
362 } 368 }
363 369
364 void CheckSub(TypeHandle type1, TypeHandle type2) { 370 void CheckSub(TypeHandle type1, TypeHandle type2) {
365 CHECK(type1->Is(type2)); 371 CHECK(type1->Is(type2));
366 CHECK(!type2->Is(type1)); 372 CHECK(!type2->Is(type1));
367 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { 373 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
368 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); 374 CHECK(Rep::AsBitset(type1) != Rep::AsBitset(type2));
369 } 375 }
370 } 376 }
371 377
372 void CheckUnordered(TypeHandle type1, TypeHandle type2) { 378 void CheckUnordered(TypeHandle type1, TypeHandle type2) {
373 CHECK(!type1->Is(type2)); 379 CHECK(!type1->Is(type2));
374 CHECK(!type2->Is(type1)); 380 CHECK(!type2->Is(type1));
375 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { 381 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
376 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); 382 CHECK(Rep::AsBitset(type1) != Rep::AsBitset(type2));
377 } 383 }
378 } 384 }
379 385
380 void CheckOverlap(TypeHandle type1, TypeHandle type2, TypeHandle mask) { 386 void CheckOverlap(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
381 CHECK(type1->Maybe(type2)); 387 CHECK(type1->Maybe(type2));
382 CHECK(type2->Maybe(type1)); 388 CHECK(type2->Maybe(type1));
383 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { 389 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
384 CHECK_NE(0, 390 CHECK(0 !=
385 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)); 391 (Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)));
386 } 392 }
387 } 393 }
388 394
389 void CheckDisjoint(TypeHandle type1, TypeHandle type2, TypeHandle mask) { 395 void CheckDisjoint(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
390 CHECK(!type1->Is(type2)); 396 CHECK(!type1->Is(type2));
391 CHECK(!type2->Is(type1)); 397 CHECK(!type2->Is(type1));
392 CHECK(!type1->Maybe(type2)); 398 CHECK(!type1->Maybe(type2));
393 CHECK(!type2->Maybe(type1)); 399 CHECK(!type2->Maybe(type1));
394 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { 400 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
395 CHECK_EQ(0, 401 CHECK(0 ==
396 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)); 402 (Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)));
397 } 403 }
398 } 404 }
399 405
400 void Bitset() { 406 void Bitset() {
401 // None and Any are bitsets. 407 // None and Any are bitsets.
402 CHECK(this->IsBitset(T.None)); 408 CHECK(this->IsBitset(T.None));
403 CHECK(this->IsBitset(T.Any)); 409 CHECK(this->IsBitset(T.Any));
404 410
405 CHECK_EQ(0, this->AsBitset(T.None)); 411 CHECK(bitset(0) == this->AsBitset(T.None));
406 CHECK_EQ(-1, this->AsBitset(T.Any)); 412 CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any));
407 413
408 // Union(T1, T2) is bitset for bitsets T1,T2 414 // Union(T1, T2) is bitset for bitsets T1,T2
409 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 415 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
410 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 416 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
411 TypeHandle type1 = *it1; 417 TypeHandle type1 = *it1;
412 TypeHandle type2 = *it2; 418 TypeHandle type2 = *it2;
413 TypeHandle union12 = T.Union(type1, type2); 419 TypeHandle union12 = T.Union(type1, type2);
414 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || 420 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
415 this->IsBitset(union12)); 421 this->IsBitset(union12));
416 } 422 }
(...skipping 21 matching lines...) Expand all
438 } 444 }
439 } 445 }
440 446
441 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 447 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2
442 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 448 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
443 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 449 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
444 TypeHandle type1 = *it1; 450 TypeHandle type1 = *it1;
445 TypeHandle type2 = *it2; 451 TypeHandle type2 = *it2;
446 TypeHandle union12 = T.Union(type1, type2); 452 TypeHandle union12 = T.Union(type1, type2);
447 if (this->IsBitset(type1) && this->IsBitset(type2)) { 453 if (this->IsBitset(type1) && this->IsBitset(type2)) {
448 CHECK_EQ( 454 CHECK(
449 this->AsBitset(type1) | this->AsBitset(type2), 455 (this->AsBitset(type1) | this->AsBitset(type2)) ==
450 this->AsBitset(union12)); 456 this->AsBitset(union12));
451 } 457 }
452 } 458 }
453 } 459 }
454 460
455 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 461 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2
456 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 462 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
457 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 463 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
458 TypeHandle type1 = *it1; 464 TypeHandle type1 = *it1;
459 TypeHandle type2 = *it2; 465 TypeHandle type2 = *it2;
460 TypeHandle intersect12 = T.Intersect(type1, type2); 466 TypeHandle intersect12 = T.Intersect(type1, type2);
461 if (this->IsBitset(type1) && this->IsBitset(type2)) { 467 if (this->IsBitset(type1) && this->IsBitset(type2)) {
462 CHECK_EQ( 468 CHECK(
463 this->AsBitset(type1) & this->AsBitset(type2), 469 (this->AsBitset(type1) & this->AsBitset(type2)) ==
464 this->AsBitset(intersect12)); 470 this->AsBitset(intersect12));
465 } 471 }
466 } 472 }
467 } 473 }
468 } 474 }
469 475
470 void Class() { 476 void Class() {
471 // Constructor 477 // Constructor
472 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 478 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
473 Handle<i::Map> map = *mt; 479 Handle<i::Map> map = *mt;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 TypeHandle type = T.Range(min, max); 575 TypeHandle type = T.Range(min, max);
570 CHECK(type->IsRange()); 576 CHECK(type->IsRange());
571 } 577 }
572 } 578 }
573 579
574 // Range attributes 580 // Range attributes
575 for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { 581 for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) {
576 for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { 582 for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) {
577 double min = T.dmin(*i, *j); 583 double min = T.dmin(*i, *j);
578 double max = T.dmax(*i, *j); 584 double max = T.dmax(*i, *j);
579 printf("RangeType: min, max = %f, %f\n", min, max);
580 TypeHandle type = T.Range(min, max); 585 TypeHandle type = T.Range(min, max);
581 printf("RangeType: Min, Max = %f, %f\n",
582 type->AsRange()->Min(), type->AsRange()->Max());
583 CHECK(min == type->AsRange()->Min()); 586 CHECK(min == type->AsRange()->Min());
584 CHECK(max == type->AsRange()->Max()); 587 CHECK(max == type->AsRange()->Max());
585 } 588 }
586 } 589 }
587 590
588 // TODO(neis): enable once subtyping is updated. 591 // TODO(neis): enable once subtyping is updated.
589 // // Functionality & Injectivity: Range(min1, max1) = Range(min2, max2) <=> 592 // // Functionality & Injectivity: Range(min1, max1) = Range(min2, max2) <=>
590 // // min1 = min2 /\ max1 = max2 593 // // min1 = min2 /\ max1 = max2
591 // for (DoubleIterator i1 = T.doubles.begin(); i1 != T.doubles.end(); ++i1) { 594 // for (DoubleIterator i1 = T.doubles.begin(); i1 != T.doubles.end(); ++i1) {
592 // for (DoubleIterator j1 = T.doubles.begin(); j1 != T.doubles.end(); ++j1) { 595 // for (DoubleIterator j1 = T.doubles.begin(); j1 != T.doubles.end(); ++j1) {
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); 1965 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
1963 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); 1966 HeapTests().Convert<Type, Type*, Zone, ZoneRep>();
1964 } 1967 }
1965 1968
1966 1969
1967 TEST(HTypeFromType) { 1970 TEST(HTypeFromType) {
1968 CcTest::InitializeVM(); 1971 CcTest::InitializeVM();
1969 ZoneTests().HTypeFromType(); 1972 ZoneTests().HTypeFromType();
1970 HeapTests().HTypeFromType(); 1973 HeapTests().HTypeFromType();
1971 } 1974 }
OLDNEW
« no previous file with comments | « src/types-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698