1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/crankshaft/hydrogen-types.h"
6 
7 #include "test/cctest/cctest.h"
8 
9 using namespace v8::internal;
10 
11 static const HType kTypes[] = {
12   #define DECLARE_TYPE(Name, mask) HType::Name(),
13   HTYPE_LIST(DECLARE_TYPE)
14   #undef DECLARE_TYPE
15 };
16 
17 static const int kNumberOfTypes = sizeof(kTypes) / sizeof(kTypes[0]);
18 
19 
TEST(HTypeDistinct)20 TEST(HTypeDistinct) {
21   for (int i = 0; i < kNumberOfTypes; ++i) {
22     for (int j = 0; j < kNumberOfTypes; ++j) {
23       CHECK(i == j || !kTypes[i].Equals(kTypes[j]));
24     }
25   }
26 }
27 
28 
TEST(HTypeReflexivity)29 TEST(HTypeReflexivity) {
30   // Reflexivity of =
31   for (int i = 0; i < kNumberOfTypes; ++i) {
32     CHECK(kTypes[i].Equals(kTypes[i]));
33   }
34 
35   // Reflexivity of <
36   for (int i = 0; i < kNumberOfTypes; ++i) {
37     CHECK(kTypes[i].IsSubtypeOf(kTypes[i]));
38   }
39 }
40 
41 
TEST(HTypeTransitivity)42 TEST(HTypeTransitivity) {
43   // Transitivity of =
44   for (int i = 0; i < kNumberOfTypes; ++i) {
45     for (int j = 0; j < kNumberOfTypes; ++j) {
46       for (int k = 0; k < kNumberOfTypes; ++k) {
47         HType ti = kTypes[i];
48         HType tj = kTypes[j];
49         HType tk = kTypes[k];
50         CHECK(!ti.Equals(tj) || !tj.Equals(tk) || ti.Equals(tk));
51       }
52     }
53   }
54 
55   // Transitivity of <
56   for (int i = 0; i < kNumberOfTypes; ++i) {
57     for (int j = 0; j < kNumberOfTypes; ++j) {
58       for (int k = 0; k < kNumberOfTypes; ++k) {
59         HType ti = kTypes[i];
60         HType tj = kTypes[j];
61         HType tk = kTypes[k];
62         CHECK(!ti.IsSubtypeOf(tj) || !tj.IsSubtypeOf(tk) || ti.IsSubtypeOf(tk));
63       }
64     }
65   }
66 }
67 
68 
TEST(HTypeCombine)69 TEST(HTypeCombine) {
70   // T < T /\ T' and T' < T /\ T' for all T,T'
71   for (int i = 0; i < kNumberOfTypes; ++i) {
72     for (int j = 0; j < kNumberOfTypes; ++j) {
73       HType ti = kTypes[i];
74       HType tj = kTypes[j];
75       CHECK(ti.IsSubtypeOf(ti.Combine(tj)));
76       CHECK(tj.IsSubtypeOf(ti.Combine(tj)));
77     }
78   }
79 }
80 
81 
TEST(HTypeAny)82 TEST(HTypeAny) {
83   // T < Any for all T
84   for (int i = 0; i < kNumberOfTypes; ++i) {
85     HType ti = kTypes[i];
86     CHECK(ti.IsAny());
87   }
88 
89   // Any < T implies T = Any for all T
90   for (int i = 0; i < kNumberOfTypes; ++i) {
91     HType ti = kTypes[i];
92     CHECK(!HType::Any().IsSubtypeOf(ti) || HType::Any().Equals(ti));
93   }
94 }
95 
96 
TEST(HTypeTagged)97 TEST(HTypeTagged) {
98   // T < Tagged for all T \ {Any}
99   for (int i = 0; i < kNumberOfTypes; ++i) {
100     HType ti = kTypes[i];
101     CHECK(ti.IsTagged() || HType::Any().Equals(ti));
102   }
103 
104   // Tagged < T implies T = Tagged or T = Any
105   for (int i = 0; i < kNumberOfTypes; ++i) {
106     HType ti = kTypes[i];
107     CHECK(!HType::Tagged().IsSubtypeOf(ti) ||
108           HType::Tagged().Equals(ti) ||
109           HType::Any().Equals(ti));
110   }
111 }
112 
113 
TEST(HTypeSmi)114 TEST(HTypeSmi) {
115   // T < Smi implies T = None or T = Smi for all T
116   for (int i = 0; i < kNumberOfTypes; ++i) {
117     HType ti = kTypes[i];
118     CHECK(!ti.IsSmi() ||
119           ti.Equals(HType::Smi()) ||
120           ti.Equals(HType::None()));
121   }
122 }
123 
124 
TEST(HTypeHeapObject)125 TEST(HTypeHeapObject) {
126   CHECK(!HType::TaggedPrimitive().IsHeapObject());
127   CHECK(!HType::TaggedNumber().IsHeapObject());
128   CHECK(!HType::Smi().IsHeapObject());
129   CHECK(HType::HeapObject().IsHeapObject());
130   CHECK(HType::HeapPrimitive().IsHeapObject());
131   CHECK(HType::Null().IsHeapObject());
132   CHECK(HType::HeapNumber().IsHeapObject());
133   CHECK(HType::String().IsHeapObject());
134   CHECK(HType::Boolean().IsHeapObject());
135   CHECK(HType::Undefined().IsHeapObject());
136   CHECK(HType::JSObject().IsHeapObject());
137   CHECK(HType::JSArray().IsHeapObject());
138 }
139 
140 
TEST(HTypePrimitive)141 TEST(HTypePrimitive) {
142   CHECK(HType::TaggedNumber().IsTaggedPrimitive());
143   CHECK(HType::Smi().IsTaggedPrimitive());
144   CHECK(!HType::HeapObject().IsTaggedPrimitive());
145   CHECK(HType::HeapPrimitive().IsTaggedPrimitive());
146   CHECK(HType::Null().IsHeapPrimitive());
147   CHECK(HType::HeapNumber().IsHeapPrimitive());
148   CHECK(HType::String().IsHeapPrimitive());
149   CHECK(HType::Boolean().IsHeapPrimitive());
150   CHECK(HType::Undefined().IsHeapPrimitive());
151   CHECK(!HType::JSObject().IsTaggedPrimitive());
152   CHECK(!HType::JSArray().IsTaggedPrimitive());
153 }
154 
155 
TEST(HTypeJSObject)156 TEST(HTypeJSObject) {
157   CHECK(HType::JSArray().IsJSObject());
158 }
159 
160 
TEST(HTypeNone)161 TEST(HTypeNone) {
162   // None < T for all T
163   for (int i = 0; i < kNumberOfTypes; ++i) {
164     HType ti = kTypes[i];
165     CHECK(HType::None().IsSubtypeOf(ti));
166   }
167 }
168