OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 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 "src/assembler.h" | 5 #include "src/assembler.h" |
6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 #include "src/compiler/typer.h" | |
9 #include "src/types.h" | |
10 #include "test/cctest/cctest.h" | 8 #include "test/cctest/cctest.h" |
11 #include "test/cctest/compiler/value-helper.h" | 9 #include "test/cctest/compiler/value-helper.h" |
12 | 10 |
13 namespace v8 { | 11 namespace v8 { |
14 namespace internal { | 12 namespace internal { |
15 namespace compiler { | 13 namespace compiler { |
16 | 14 |
17 class JSCacheTesterHelper { | 15 class JSCacheTesterHelper { |
18 protected: | 16 protected: |
19 JSCacheTesterHelper(Isolate* isolate, Zone* zone) | 17 JSCacheTesterHelper(Isolate* isolate, Zone* zone) |
20 : main_graph_(zone), | 18 : main_graph_(zone), |
21 main_common_(zone), | 19 main_common_(zone), |
22 main_javascript_(zone), | 20 main_javascript_(zone), |
23 main_typer_(isolate, &main_graph_), | |
24 main_machine_(zone) {} | 21 main_machine_(zone) {} |
25 Graph main_graph_; | 22 Graph main_graph_; |
26 CommonOperatorBuilder main_common_; | 23 CommonOperatorBuilder main_common_; |
27 JSOperatorBuilder main_javascript_; | 24 JSOperatorBuilder main_javascript_; |
28 Typer main_typer_; | |
29 MachineOperatorBuilder main_machine_; | 25 MachineOperatorBuilder main_machine_; |
30 }; | 26 }; |
31 | 27 |
32 | 28 |
33 // TODO(dcarney): JSConstantCacheTester inherits from JSGraph??? | 29 // TODO(dcarney): JSConstantCacheTester inherits from JSGraph??? |
34 class JSConstantCacheTester : public HandleAndZoneScope, | 30 class JSConstantCacheTester : public HandleAndZoneScope, |
35 public JSCacheTesterHelper, | 31 public JSCacheTesterHelper, |
36 public JSGraph { | 32 public JSGraph { |
37 public: | 33 public: |
38 JSConstantCacheTester() | 34 JSConstantCacheTester() |
39 : JSCacheTesterHelper(main_isolate(), main_zone()), | 35 : JSCacheTesterHelper(main_isolate(), main_zone()), |
40 JSGraph(main_isolate(), &main_graph_, &main_common_, &main_javascript_, | 36 JSGraph(main_isolate(), &main_graph_, &main_common_, &main_javascript_, |
41 nullptr, &main_machine_) { | 37 nullptr, &main_machine_) { |
42 main_graph_.SetStart(main_graph_.NewNode(common()->Start(0))); | 38 main_graph_.SetStart(main_graph_.NewNode(common()->Start(0))); |
43 main_graph_.SetEnd( | 39 main_graph_.SetEnd( |
44 main_graph_.NewNode(common()->End(1), main_graph_.start())); | 40 main_graph_.NewNode(common()->End(1), main_graph_.start())); |
45 main_typer_.Run(); | |
46 } | 41 } |
47 | 42 |
48 Type* TypeOf(Node* node) { return NodeProperties::GetType(node); } | |
49 | |
50 Handle<HeapObject> handle(Node* node) { | 43 Handle<HeapObject> handle(Node* node) { |
51 CHECK_EQ(IrOpcode::kHeapConstant, node->opcode()); | 44 CHECK_EQ(IrOpcode::kHeapConstant, node->opcode()); |
52 return OpParameter<Handle<HeapObject>>(node); | 45 return OpParameter<Handle<HeapObject>>(node); |
53 } | 46 } |
54 | 47 |
55 Factory* factory() { return main_isolate()->factory(); } | 48 Factory* factory() { return main_isolate()->factory(); } |
56 }; | 49 }; |
57 | 50 |
58 | 51 |
59 TEST(ZeroConstant1) { | 52 TEST(ZeroConstant1) { |
60 JSConstantCacheTester T; | 53 JSConstantCacheTester T; |
61 | 54 |
62 Node* zero = T.ZeroConstant(); | 55 Node* zero = T.ZeroConstant(); |
63 | 56 |
64 CHECK_EQ(IrOpcode::kNumberConstant, zero->opcode()); | 57 CHECK_EQ(IrOpcode::kNumberConstant, zero->opcode()); |
65 CHECK_EQ(zero, T.Constant(0)); | 58 CHECK_EQ(zero, T.Constant(0)); |
66 CHECK_NE(zero, T.Constant(-0.0)); | 59 CHECK_NE(zero, T.Constant(-0.0)); |
67 CHECK_NE(zero, T.Constant(1.0)); | 60 CHECK_NE(zero, T.Constant(1.0)); |
68 CHECK_NE(zero, T.Constant(std::numeric_limits<double>::quiet_NaN())); | 61 CHECK_NE(zero, T.Constant(std::numeric_limits<double>::quiet_NaN())); |
69 CHECK_NE(zero, T.Float64Constant(0)); | 62 CHECK_NE(zero, T.Float64Constant(0)); |
70 CHECK_NE(zero, T.Int32Constant(0)); | 63 CHECK_NE(zero, T.Int32Constant(0)); |
71 | |
72 Type* t = T.TypeOf(zero); | |
73 | |
74 CHECK(t->Is(Type::Number())); | |
75 CHECK(t->Is(Type::Integral32())); | |
76 CHECK(t->Is(Type::Signed32())); | |
77 CHECK(t->Is(Type::Unsigned32())); | |
78 CHECK(t->Is(Type::SignedSmall())); | |
79 CHECK(t->Is(Type::UnsignedSmall())); | |
80 } | 64 } |
81 | 65 |
82 | 66 |
83 TEST(MinusZeroConstant) { | 67 TEST(MinusZeroConstant) { |
84 JSConstantCacheTester T; | 68 JSConstantCacheTester T; |
85 | 69 |
86 Node* minus_zero = T.Constant(-0.0); | 70 Node* minus_zero = T.Constant(-0.0); |
87 Node* zero = T.ZeroConstant(); | 71 Node* zero = T.ZeroConstant(); |
88 | 72 |
89 CHECK_EQ(IrOpcode::kNumberConstant, minus_zero->opcode()); | 73 CHECK_EQ(IrOpcode::kNumberConstant, minus_zero->opcode()); |
90 CHECK_EQ(minus_zero, T.Constant(-0.0)); | 74 CHECK_EQ(minus_zero, T.Constant(-0.0)); |
91 CHECK_NE(zero, minus_zero); | 75 CHECK_NE(zero, minus_zero); |
92 | 76 |
93 Type* t = T.TypeOf(minus_zero); | |
94 | |
95 CHECK(t->Is(Type::Number())); | |
96 CHECK(t->Is(Type::MinusZero())); | |
97 CHECK(!t->Is(Type::Integral32())); | |
98 CHECK(!t->Is(Type::Signed32())); | |
99 CHECK(!t->Is(Type::Unsigned32())); | |
100 CHECK(!t->Is(Type::SignedSmall())); | |
101 CHECK(!t->Is(Type::UnsignedSmall())); | |
102 | |
103 double zero_value = OpParameter<double>(zero); | 77 double zero_value = OpParameter<double>(zero); |
104 double minus_zero_value = OpParameter<double>(minus_zero); | 78 double minus_zero_value = OpParameter<double>(minus_zero); |
105 | 79 |
106 CHECK(bit_cast<uint64_t>(0.0) == bit_cast<uint64_t>(zero_value)); | 80 CHECK(bit_cast<uint64_t>(0.0) == bit_cast<uint64_t>(zero_value)); |
107 CHECK(bit_cast<uint64_t>(-0.0) != bit_cast<uint64_t>(zero_value)); | 81 CHECK(bit_cast<uint64_t>(-0.0) != bit_cast<uint64_t>(zero_value)); |
108 CHECK(bit_cast<uint64_t>(0.0) != bit_cast<uint64_t>(minus_zero_value)); | 82 CHECK(bit_cast<uint64_t>(0.0) != bit_cast<uint64_t>(minus_zero_value)); |
109 CHECK(bit_cast<uint64_t>(-0.0) == bit_cast<uint64_t>(minus_zero_value)); | 83 CHECK(bit_cast<uint64_t>(-0.0) == bit_cast<uint64_t>(minus_zero_value)); |
110 } | 84 } |
111 | 85 |
112 | 86 |
113 TEST(ZeroConstant2) { | 87 TEST(ZeroConstant2) { |
114 JSConstantCacheTester T; | 88 JSConstantCacheTester T; |
115 | 89 |
116 Node* zero = T.Constant(0); | 90 Node* zero = T.Constant(0); |
117 | 91 |
118 CHECK_EQ(IrOpcode::kNumberConstant, zero->opcode()); | 92 CHECK_EQ(IrOpcode::kNumberConstant, zero->opcode()); |
119 CHECK_EQ(zero, T.ZeroConstant()); | 93 CHECK_EQ(zero, T.ZeroConstant()); |
120 CHECK_NE(zero, T.Constant(-0.0)); | 94 CHECK_NE(zero, T.Constant(-0.0)); |
121 CHECK_NE(zero, T.Constant(1.0)); | 95 CHECK_NE(zero, T.Constant(1.0)); |
122 CHECK_NE(zero, T.Constant(std::numeric_limits<double>::quiet_NaN())); | 96 CHECK_NE(zero, T.Constant(std::numeric_limits<double>::quiet_NaN())); |
123 CHECK_NE(zero, T.Float64Constant(0)); | 97 CHECK_NE(zero, T.Float64Constant(0)); |
124 CHECK_NE(zero, T.Int32Constant(0)); | 98 CHECK_NE(zero, T.Int32Constant(0)); |
125 | |
126 Type* t = T.TypeOf(zero); | |
127 | |
128 CHECK(t->Is(Type::Number())); | |
129 CHECK(t->Is(Type::Integral32())); | |
130 CHECK(t->Is(Type::Signed32())); | |
131 CHECK(t->Is(Type::Unsigned32())); | |
132 CHECK(t->Is(Type::SignedSmall())); | |
133 CHECK(t->Is(Type::UnsignedSmall())); | |
134 } | 99 } |
135 | 100 |
136 | 101 |
137 TEST(OneConstant1) { | 102 TEST(OneConstant1) { |
138 JSConstantCacheTester T; | 103 JSConstantCacheTester T; |
139 | 104 |
140 Node* one = T.OneConstant(); | 105 Node* one = T.OneConstant(); |
141 | 106 |
142 CHECK_EQ(IrOpcode::kNumberConstant, one->opcode()); | 107 CHECK_EQ(IrOpcode::kNumberConstant, one->opcode()); |
143 CHECK_EQ(one, T.Constant(1)); | 108 CHECK_EQ(one, T.Constant(1)); |
144 CHECK_EQ(one, T.Constant(1.0)); | 109 CHECK_EQ(one, T.Constant(1.0)); |
145 CHECK_NE(one, T.Constant(1.01)); | 110 CHECK_NE(one, T.Constant(1.01)); |
146 CHECK_NE(one, T.Constant(-1.01)); | 111 CHECK_NE(one, T.Constant(-1.01)); |
147 CHECK_NE(one, T.Constant(std::numeric_limits<double>::quiet_NaN())); | 112 CHECK_NE(one, T.Constant(std::numeric_limits<double>::quiet_NaN())); |
148 CHECK_NE(one, T.Float64Constant(1.0)); | 113 CHECK_NE(one, T.Float64Constant(1.0)); |
149 CHECK_NE(one, T.Int32Constant(1)); | 114 CHECK_NE(one, T.Int32Constant(1)); |
150 | |
151 Type* t = T.TypeOf(one); | |
152 | |
153 CHECK(t->Is(Type::Number())); | |
154 CHECK(t->Is(Type::Integral32())); | |
155 CHECK(t->Is(Type::Signed32())); | |
156 CHECK(t->Is(Type::Unsigned32())); | |
157 CHECK(t->Is(Type::SignedSmall())); | |
158 CHECK(t->Is(Type::UnsignedSmall())); | |
159 } | 115 } |
160 | 116 |
161 | 117 |
162 TEST(OneConstant2) { | 118 TEST(OneConstant2) { |
163 JSConstantCacheTester T; | 119 JSConstantCacheTester T; |
164 | 120 |
165 Node* one = T.Constant(1); | 121 Node* one = T.Constant(1); |
166 | 122 |
167 CHECK_EQ(IrOpcode::kNumberConstant, one->opcode()); | 123 CHECK_EQ(IrOpcode::kNumberConstant, one->opcode()); |
168 CHECK_EQ(one, T.OneConstant()); | 124 CHECK_EQ(one, T.OneConstant()); |
169 CHECK_EQ(one, T.Constant(1.0)); | 125 CHECK_EQ(one, T.Constant(1.0)); |
170 CHECK_NE(one, T.Constant(1.01)); | 126 CHECK_NE(one, T.Constant(1.01)); |
171 CHECK_NE(one, T.Constant(-1.01)); | 127 CHECK_NE(one, T.Constant(-1.01)); |
172 CHECK_NE(one, T.Constant(std::numeric_limits<double>::quiet_NaN())); | 128 CHECK_NE(one, T.Constant(std::numeric_limits<double>::quiet_NaN())); |
173 CHECK_NE(one, T.Float64Constant(1.0)); | 129 CHECK_NE(one, T.Float64Constant(1.0)); |
174 CHECK_NE(one, T.Int32Constant(1)); | 130 CHECK_NE(one, T.Int32Constant(1)); |
175 | |
176 Type* t = T.TypeOf(one); | |
177 | |
178 CHECK(t->Is(Type::Number())); | |
179 CHECK(t->Is(Type::Integral32())); | |
180 CHECK(t->Is(Type::Signed32())); | |
181 CHECK(t->Is(Type::Unsigned32())); | |
182 CHECK(t->Is(Type::SignedSmall())); | |
183 CHECK(t->Is(Type::UnsignedSmall())); | |
184 } | 131 } |
185 | 132 |
186 | 133 |
187 TEST(Canonicalizations) { | 134 TEST(Canonicalizations) { |
188 JSConstantCacheTester T; | 135 JSConstantCacheTester T; |
189 | 136 |
190 CHECK_EQ(T.ZeroConstant(), T.ZeroConstant()); | 137 CHECK_EQ(T.ZeroConstant(), T.ZeroConstant()); |
191 CHECK_EQ(T.UndefinedConstant(), T.UndefinedConstant()); | 138 CHECK_EQ(T.UndefinedConstant(), T.UndefinedConstant()); |
192 CHECK_EQ(T.TheHoleConstant(), T.TheHoleConstant()); | 139 CHECK_EQ(T.TheHoleConstant(), T.TheHoleConstant()); |
193 CHECK_EQ(T.TrueConstant(), T.TrueConstant()); | 140 CHECK_EQ(T.TrueConstant(), T.TrueConstant()); |
(...skipping 26 matching lines...) Expand all Loading... |
220 | 167 |
221 FOR_FLOAT64_INPUTS(i) { | 168 FOR_FLOAT64_INPUTS(i) { |
222 Node* node = T.Constant(*i); | 169 Node* node = T.Constant(*i); |
223 for (int j = 0; j < 5; j++) { | 170 for (int j = 0; j < 5; j++) { |
224 CHECK_EQ(node, T.Constant(*i)); | 171 CHECK_EQ(node, T.Constant(*i)); |
225 } | 172 } |
226 } | 173 } |
227 } | 174 } |
228 | 175 |
229 | 176 |
230 TEST(NumberTypes) { | |
231 JSConstantCacheTester T; | |
232 | |
233 FOR_FLOAT64_INPUTS(i) { | |
234 double value = *i; | |
235 Node* node = T.Constant(value); | |
236 CHECK(T.TypeOf(node)->Is(Type::Of(value, T.main_zone()))); | |
237 } | |
238 } | |
239 | |
240 | |
241 TEST(HeapNumbers) { | 177 TEST(HeapNumbers) { |
242 JSConstantCacheTester T; | 178 JSConstantCacheTester T; |
243 | 179 |
244 FOR_FLOAT64_INPUTS(i) { | 180 FOR_FLOAT64_INPUTS(i) { |
245 double value = *i; | 181 double value = *i; |
246 Handle<Object> num = T.factory()->NewNumber(value); | 182 Handle<Object> num = T.factory()->NewNumber(value); |
247 Handle<HeapNumber> heap = T.factory()->NewHeapNumber(value); | 183 Handle<HeapNumber> heap = T.factory()->NewHeapNumber(value); |
248 Node* node1 = T.Constant(value); | 184 Node* node1 = T.Constant(value); |
249 Node* node2 = T.Constant(num); | 185 Node* node2 = T.Constant(num); |
250 Node* node3 = T.Constant(heap); | 186 Node* node3 = T.Constant(heap); |
(...skipping 19 matching lines...) Expand all Loading... |
270 JSConstantCacheTester T; | 206 JSConstantCacheTester T; |
271 | 207 |
272 CHECK_EQ(*T.factory()->undefined_value(), *T.handle(T.UndefinedConstant())); | 208 CHECK_EQ(*T.factory()->undefined_value(), *T.handle(T.UndefinedConstant())); |
273 CHECK_EQ(*T.factory()->the_hole_value(), *T.handle(T.TheHoleConstant())); | 209 CHECK_EQ(*T.factory()->the_hole_value(), *T.handle(T.TheHoleConstant())); |
274 CHECK_EQ(*T.factory()->true_value(), *T.handle(T.TrueConstant())); | 210 CHECK_EQ(*T.factory()->true_value(), *T.handle(T.TrueConstant())); |
275 CHECK_EQ(*T.factory()->false_value(), *T.handle(T.FalseConstant())); | 211 CHECK_EQ(*T.factory()->false_value(), *T.handle(T.FalseConstant())); |
276 CHECK_EQ(*T.factory()->null_value(), *T.handle(T.NullConstant())); | 212 CHECK_EQ(*T.factory()->null_value(), *T.handle(T.NullConstant())); |
277 } | 213 } |
278 | 214 |
279 | 215 |
280 TEST(OddballTypes) { | |
281 JSConstantCacheTester T; | |
282 | |
283 CHECK(T.TypeOf(T.UndefinedConstant())->Is(Type::Undefined())); | |
284 // TODO(dcarney): figure this out. | |
285 // CHECK(T.TypeOf(T.TheHoleConstant())->Is(Type::Internal())); | |
286 CHECK(T.TypeOf(T.TrueConstant())->Is(Type::Boolean())); | |
287 CHECK(T.TypeOf(T.FalseConstant())->Is(Type::Boolean())); | |
288 CHECK(T.TypeOf(T.NullConstant())->Is(Type::Null())); | |
289 CHECK(T.TypeOf(T.ZeroConstant())->Is(Type::Number())); | |
290 CHECK(T.TypeOf(T.OneConstant())->Is(Type::Number())); | |
291 CHECK(T.TypeOf(T.NaNConstant())->Is(Type::NaN())); | |
292 } | |
293 | |
294 | |
295 TEST(ExternalReferences) { | 216 TEST(ExternalReferences) { |
296 // TODO(titzer): test canonicalization of external references. | 217 // TODO(titzer): test canonicalization of external references. |
297 } | 218 } |
298 | 219 |
299 | 220 |
300 static bool Contains(NodeVector* nodes, Node* n) { | 221 static bool Contains(NodeVector* nodes, Node* n) { |
301 for (size_t i = 0; i < nodes->size(); i++) { | 222 for (size_t i = 0; i < nodes->size(); i++) { |
302 if (nodes->at(i) == n) return true; | 223 if (nodes->at(i) == n) return true; |
303 } | 224 } |
304 return false; | 225 return false; |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 T.GetCachedNodes(&nodes); | 390 T.GetCachedNodes(&nodes); |
470 | 391 |
471 for (size_t i = 0; i < arraysize(constants); i++) { | 392 for (size_t i = 0; i < arraysize(constants); i++) { |
472 CHECK(Contains(&nodes, constants[i])); | 393 CHECK(Contains(&nodes, constants[i])); |
473 } | 394 } |
474 } | 395 } |
475 | 396 |
476 } // namespace compiler | 397 } // namespace compiler |
477 } // namespace internal | 398 } // namespace internal |
478 } // namespace v8 | 399 } // namespace v8 |
OLD | NEW |