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 // TODO(jochen): Remove this after the setting is turned on globally. | 5 // TODO(jochen): Remove this after the setting is turned on globally. |
6 #define V8_IMMINENT_DEPRECATION_WARNINGS | 6 #define V8_IMMINENT_DEPRECATION_WARNINGS |
7 | 7 |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 SimplifiedLoweringTester<Object*> t; | 104 SimplifiedLoweringTester<Object*> t; |
105 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), | 105 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), |
106 kMachFloat64}; | 106 kMachFloat64}; |
107 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); | 107 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); |
108 NodeProperties::SetType(loaded, Type::Number()); | 108 NodeProperties::SetType(loaded, Type::Number()); |
109 Node* convert = t.NumberToInt32(loaded); | 109 Node* convert = t.NumberToInt32(loaded); |
110 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(), | 110 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(), |
111 kMachInt32}; | 111 kMachInt32}; |
112 t.StoreField(store, t.PointerConstant(&result), convert); | 112 t.StoreField(store, t.PointerConstant(&result), convert); |
113 t.Return(t.jsgraph.TrueConstant()); | 113 t.Return(t.jsgraph.TrueConstant()); |
114 t.LowerAllNodes(); | 114 t.LowerAllNodesAndLowerChanges(); |
115 t.GenerateCode(); | 115 t.GenerateCode(); |
116 | 116 |
117 FOR_FLOAT64_INPUTS(i) { | 117 FOR_FLOAT64_INPUTS(i) { |
118 input = *i; | 118 input = *i; |
119 int32_t expected = DoubleToInt32(*i); | 119 int32_t expected = DoubleToInt32(*i); |
120 t.Call(); | 120 t.Call(); |
121 CHECK_EQ(expected, result); | 121 CHECK_EQ(expected, result); |
122 } | 122 } |
123 } | 123 } |
124 | 124 |
125 | 125 |
126 // TODO(titzer): test tagged representation for input to NumberToUint32. | 126 // TODO(titzer): test tagged representation for input to NumberToUint32. |
127 TEST(RunNumberToUint32_float64) { | 127 TEST(RunNumberToUint32_float64) { |
128 // TODO(titzer): explicit load/stores here are only because of representations | 128 // TODO(titzer): explicit load/stores here are only because of representations |
129 double input; | 129 double input; |
130 uint32_t result; | 130 uint32_t result; |
131 SimplifiedLoweringTester<Object*> t; | 131 SimplifiedLoweringTester<Object*> t; |
132 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), | 132 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), |
133 kMachFloat64}; | 133 kMachFloat64}; |
134 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); | 134 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); |
135 NodeProperties::SetType(loaded, Type::Number()); | 135 NodeProperties::SetType(loaded, Type::Number()); |
136 Node* convert = t.NumberToUint32(loaded); | 136 Node* convert = t.NumberToUint32(loaded); |
137 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(), | 137 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(), |
138 kMachUint32}; | 138 kMachUint32}; |
139 t.StoreField(store, t.PointerConstant(&result), convert); | 139 t.StoreField(store, t.PointerConstant(&result), convert); |
140 t.Return(t.jsgraph.TrueConstant()); | 140 t.Return(t.jsgraph.TrueConstant()); |
141 t.LowerAllNodes(); | 141 t.LowerAllNodesAndLowerChanges(); |
142 t.GenerateCode(); | 142 t.GenerateCode(); |
143 | 143 |
144 FOR_FLOAT64_INPUTS(i) { | 144 FOR_FLOAT64_INPUTS(i) { |
145 input = *i; | 145 input = *i; |
146 uint32_t expected = DoubleToUint32(*i); | 146 uint32_t expected = DoubleToUint32(*i); |
147 t.Call(); | 147 t.Call(); |
148 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); | 148 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); |
149 } | 149 } |
150 } | 150 } |
151 | 151 |
152 | 152 |
153 // Create a simple JSObject with a unique map. | 153 // Create a simple JSObject with a unique map. |
154 static Handle<JSObject> TestObject() { | 154 static Handle<JSObject> TestObject() { |
155 static int index = 0; | 155 static int index = 0; |
156 char buffer[50]; | 156 char buffer[50]; |
157 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); | 157 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); |
158 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); | 158 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); |
159 } | 159 } |
160 | 160 |
161 | 161 |
162 TEST(RunLoadMap) { | 162 TEST(RunLoadMap) { |
163 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 163 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
164 FieldAccess access = AccessBuilder::ForMap(); | 164 FieldAccess access = AccessBuilder::ForMap(); |
165 Node* load = t.LoadField(access, t.Parameter(0)); | 165 Node* load = t.LoadField(access, t.Parameter(0)); |
166 t.Return(load); | 166 t.Return(load); |
167 | 167 |
168 t.LowerAllNodes(); | 168 t.LowerAllNodesAndLowerChanges(); |
169 t.GenerateCode(); | 169 t.GenerateCode(); |
170 | 170 |
171 Handle<JSObject> src = TestObject(); | 171 Handle<JSObject> src = TestObject(); |
172 Handle<Map> src_map(src->map()); | 172 Handle<Map> src_map(src->map()); |
173 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call | 173 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
174 CHECK_EQ(*src_map, result); | 174 CHECK_EQ(*src_map, result); |
175 } | 175 } |
176 | 176 |
177 | 177 |
178 TEST(RunStoreMap) { | 178 TEST(RunStoreMap) { |
179 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); | 179 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); |
180 FieldAccess access = AccessBuilder::ForMap(); | 180 FieldAccess access = AccessBuilder::ForMap(); |
181 t.StoreField(access, t.Parameter(1), t.Parameter(0)); | 181 t.StoreField(access, t.Parameter(1), t.Parameter(0)); |
182 t.Return(t.jsgraph.TrueConstant()); | 182 t.Return(t.jsgraph.TrueConstant()); |
183 | 183 |
184 t.LowerAllNodes(); | 184 t.LowerAllNodesAndLowerChanges(); |
185 t.GenerateCode(); | 185 t.GenerateCode(); |
186 | 186 |
187 Handle<JSObject> src = TestObject(); | 187 Handle<JSObject> src = TestObject(); |
188 Handle<Map> src_map(src->map()); | 188 Handle<Map> src_map(src->map()); |
189 Handle<JSObject> dst = TestObject(); | 189 Handle<JSObject> dst = TestObject(); |
190 CHECK(src->map() != dst->map()); | 190 CHECK(src->map() != dst->map()); |
191 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call | 191 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call |
192 CHECK(*src_map == dst->map()); | 192 CHECK(*src_map == dst->map()); |
193 } | 193 } |
194 | 194 |
195 | 195 |
196 TEST(RunLoadProperties) { | 196 TEST(RunLoadProperties) { |
197 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 197 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
198 FieldAccess access = AccessBuilder::ForJSObjectProperties(); | 198 FieldAccess access = AccessBuilder::ForJSObjectProperties(); |
199 Node* load = t.LoadField(access, t.Parameter(0)); | 199 Node* load = t.LoadField(access, t.Parameter(0)); |
200 t.Return(load); | 200 t.Return(load); |
201 | 201 |
202 t.LowerAllNodes(); | 202 t.LowerAllNodesAndLowerChanges(); |
203 t.GenerateCode(); | 203 t.GenerateCode(); |
204 | 204 |
205 Handle<JSObject> src = TestObject(); | 205 Handle<JSObject> src = TestObject(); |
206 Handle<FixedArray> src_props(src->properties()); | 206 Handle<FixedArray> src_props(src->properties()); |
207 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call | 207 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
208 CHECK_EQ(*src_props, result); | 208 CHECK_EQ(*src_props, result); |
209 } | 209 } |
210 | 210 |
211 | 211 |
212 TEST(RunLoadStoreMap) { | 212 TEST(RunLoadStoreMap) { |
213 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); | 213 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); |
214 FieldAccess access = AccessBuilder::ForMap(); | 214 FieldAccess access = AccessBuilder::ForMap(); |
215 Node* load = t.LoadField(access, t.Parameter(0)); | 215 Node* load = t.LoadField(access, t.Parameter(0)); |
216 t.StoreField(access, t.Parameter(1), load); | 216 t.StoreField(access, t.Parameter(1), load); |
217 t.Return(load); | 217 t.Return(load); |
218 | 218 |
219 t.LowerAllNodes(); | 219 t.LowerAllNodesAndLowerChanges(); |
220 t.GenerateCode(); | 220 t.GenerateCode(); |
221 | 221 |
222 Handle<JSObject> src = TestObject(); | 222 Handle<JSObject> src = TestObject(); |
223 Handle<Map> src_map(src->map()); | 223 Handle<Map> src_map(src->map()); |
224 Handle<JSObject> dst = TestObject(); | 224 Handle<JSObject> dst = TestObject(); |
225 CHECK(src->map() != dst->map()); | 225 CHECK(src->map() != dst->map()); |
226 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call | 226 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call |
227 CHECK(result->IsMap()); | 227 CHECK(result->IsMap()); |
228 CHECK_EQ(*src_map, result); | 228 CHECK_EQ(*src_map, result); |
229 CHECK(*src_map == dst->map()); | 229 CHECK(*src_map == dst->map()); |
230 } | 230 } |
231 | 231 |
232 | 232 |
233 TEST(RunLoadStoreFixedArrayIndex) { | 233 TEST(RunLoadStoreFixedArrayIndex) { |
234 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 234 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
235 ElementAccess access = AccessBuilder::ForFixedArrayElement(); | 235 ElementAccess access = AccessBuilder::ForFixedArrayElement(); |
236 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); | 236 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); |
237 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); | 237 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); |
238 t.Return(load); | 238 t.Return(load); |
239 | 239 |
240 t.LowerAllNodes(); | 240 t.LowerAllNodesAndLowerChanges(); |
241 t.GenerateCode(); | 241 t.GenerateCode(); |
242 | 242 |
243 Handle<FixedArray> array = t.factory()->NewFixedArray(2); | 243 Handle<FixedArray> array = t.factory()->NewFixedArray(2); |
244 Handle<JSObject> src = TestObject(); | 244 Handle<JSObject> src = TestObject(); |
245 Handle<JSObject> dst = TestObject(); | 245 Handle<JSObject> dst = TestObject(); |
246 array->set(0, *src); | 246 array->set(0, *src); |
247 array->set(1, *dst); | 247 array->set(1, *dst); |
248 Object* result = t.Call(*array); | 248 Object* result = t.Call(*array); |
249 CHECK_EQ(*src, result); | 249 CHECK_EQ(*src, result); |
250 CHECK_EQ(*src, array->get(0)); | 250 CHECK_EQ(*src, array->get(0)); |
251 CHECK_EQ(*src, array->get(1)); | 251 CHECK_EQ(*src, array->get(1)); |
252 } | 252 } |
253 | 253 |
254 | 254 |
255 TEST(RunLoadStoreArrayBuffer) { | 255 TEST(RunLoadStoreArrayBuffer) { |
256 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 256 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
257 const int index = 12; | 257 const int index = 12; |
258 const int array_length = 2 * index; | 258 const int array_length = 2 * index; |
259 ElementAccess buffer_access = | 259 ElementAccess buffer_access = |
260 AccessBuilder::ForTypedArrayElement(kExternalInt8Array, true); | 260 AccessBuilder::ForTypedArrayElement(kExternalInt8Array, true); |
261 Node* backing_store = t.LoadField( | 261 Node* backing_store = t.LoadField( |
262 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); | 262 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); |
263 Node* load = | 263 Node* load = |
264 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); | 264 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); |
265 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), | 265 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), |
266 load); | 266 load); |
267 t.Return(t.jsgraph.TrueConstant()); | 267 t.Return(t.jsgraph.TrueConstant()); |
268 | 268 |
269 t.LowerAllNodes(); | 269 t.LowerAllNodesAndLowerChanges(); |
270 t.GenerateCode(); | 270 t.GenerateCode(); |
271 | 271 |
272 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); | 272 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); |
273 JSArrayBuffer::SetupAllocatingData(array, t.isolate(), array_length); | 273 JSArrayBuffer::SetupAllocatingData(array, t.isolate(), array_length); |
274 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); | 274 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); |
275 for (int i = 0; i < array_length; i++) { | 275 for (int i = 0; i < array_length; i++) { |
276 data[i] = i; | 276 data[i] = i; |
277 } | 277 } |
278 | 278 |
279 // TODO(titzer): raw pointers in call | 279 // TODO(titzer): raw pointers in call |
(...skipping 11 matching lines...) Expand all Loading... |
291 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | 291 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
292 | 292 |
293 for (size_t i = 0; i < arraysize(smis); i++) { | 293 for (size_t i = 0; i < arraysize(smis); i++) { |
294 int offset = static_cast<int>(i * sizeof(Smi*)); | 294 int offset = static_cast<int>(i * sizeof(Smi*)); |
295 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), | 295 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), |
296 Type::Integral32(), kMachAnyTagged}; | 296 Type::Integral32(), kMachAnyTagged}; |
297 | 297 |
298 SimplifiedLoweringTester<Object*> t; | 298 SimplifiedLoweringTester<Object*> t; |
299 Node* load = t.LoadField(access, t.PointerConstant(smis)); | 299 Node* load = t.LoadField(access, t.PointerConstant(smis)); |
300 t.Return(load); | 300 t.Return(load); |
301 t.LowerAllNodes(); | 301 t.LowerAllNodesAndLowerChanges(); |
302 | 302 |
303 for (int j = -5; j <= 5; j++) { | 303 for (int j = -5; j <= 5; j++) { |
304 Smi* expected = Smi::FromInt(j); | 304 Smi* expected = Smi::FromInt(j); |
305 smis[i] = expected; | 305 smis[i] = expected; |
306 CHECK_EQ(expected, t.Call()); | 306 CHECK_EQ(expected, t.Call()); |
307 } | 307 } |
308 } | 308 } |
309 } | 309 } |
310 | 310 |
311 | 311 |
312 TEST(RunStoreFieldToUntaggedBase) { | 312 TEST(RunStoreFieldToUntaggedBase) { |
313 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | 313 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
314 | 314 |
315 for (size_t i = 0; i < arraysize(smis); i++) { | 315 for (size_t i = 0; i < arraysize(smis); i++) { |
316 int offset = static_cast<int>(i * sizeof(Smi*)); | 316 int offset = static_cast<int>(i * sizeof(Smi*)); |
317 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), | 317 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), |
318 Type::Integral32(), kMachAnyTagged}; | 318 Type::Integral32(), kMachAnyTagged}; |
319 | 319 |
320 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 320 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
321 Node* p0 = t.Parameter(0); | 321 Node* p0 = t.Parameter(0); |
322 t.StoreField(access, t.PointerConstant(smis), p0); | 322 t.StoreField(access, t.PointerConstant(smis), p0); |
323 t.Return(p0); | 323 t.Return(p0); |
324 t.LowerAllNodes(); | 324 t.LowerAllNodesAndLowerChanges(); |
325 | 325 |
326 for (int j = -5; j <= 5; j++) { | 326 for (int j = -5; j <= 5; j++) { |
327 Smi* expected = Smi::FromInt(j); | 327 Smi* expected = Smi::FromInt(j); |
328 smis[i] = Smi::FromInt(-100); | 328 smis[i] = Smi::FromInt(-100); |
329 CHECK_EQ(expected, t.Call(expected)); | 329 CHECK_EQ(expected, t.Call(expected)); |
330 CHECK_EQ(expected, smis[i]); | 330 CHECK_EQ(expected, smis[i]); |
331 } | 331 } |
332 } | 332 } |
333 } | 333 } |
334 | 334 |
335 | 335 |
336 TEST(RunLoadElementFromUntaggedBase) { | 336 TEST(RunLoadElementFromUntaggedBase) { |
337 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | 337 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
338 Smi::FromInt(4), Smi::FromInt(5)}; | 338 Smi::FromInt(4), Smi::FromInt(5)}; |
339 | 339 |
340 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes | 340 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes |
341 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index | 341 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index |
342 int offset = static_cast<int>(i * sizeof(Smi*)); | 342 int offset = static_cast<int>(i * sizeof(Smi*)); |
343 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), | 343 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), |
344 kMachAnyTagged}; | 344 kMachAnyTagged}; |
345 | 345 |
346 SimplifiedLoweringTester<Object*> t; | 346 SimplifiedLoweringTester<Object*> t; |
347 Node* load = t.LoadElement(access, t.PointerConstant(smis), | 347 Node* load = t.LoadElement(access, t.PointerConstant(smis), |
348 t.Int32Constant(static_cast<int>(j))); | 348 t.Int32Constant(static_cast<int>(j))); |
349 t.Return(load); | 349 t.Return(load); |
350 t.LowerAllNodes(); | 350 t.LowerAllNodesAndLowerChanges(); |
351 | 351 |
352 for (int k = -5; k <= 5; k++) { | 352 for (int k = -5; k <= 5; k++) { |
353 Smi* expected = Smi::FromInt(k); | 353 Smi* expected = Smi::FromInt(k); |
354 smis[i + j] = expected; | 354 smis[i + j] = expected; |
355 CHECK_EQ(expected, t.Call()); | 355 CHECK_EQ(expected, t.Call()); |
356 } | 356 } |
357 } | 357 } |
358 } | 358 } |
359 } | 359 } |
360 | 360 |
361 | 361 |
362 TEST(RunStoreElementFromUntaggedBase) { | 362 TEST(RunStoreElementFromUntaggedBase) { |
363 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | 363 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
364 Smi::FromInt(4), Smi::FromInt(5)}; | 364 Smi::FromInt(4), Smi::FromInt(5)}; |
365 | 365 |
366 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes | 366 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes |
367 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index | 367 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index |
368 int offset = static_cast<int>(i * sizeof(Smi*)); | 368 int offset = static_cast<int>(i * sizeof(Smi*)); |
369 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), | 369 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), |
370 kMachAnyTagged}; | 370 kMachAnyTagged}; |
371 | 371 |
372 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 372 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
373 Node* p0 = t.Parameter(0); | 373 Node* p0 = t.Parameter(0); |
374 t.StoreElement(access, t.PointerConstant(smis), | 374 t.StoreElement(access, t.PointerConstant(smis), |
375 t.Int32Constant(static_cast<int>(j)), p0); | 375 t.Int32Constant(static_cast<int>(j)), p0); |
376 t.Return(p0); | 376 t.Return(p0); |
377 t.LowerAllNodes(); | 377 t.LowerAllNodesAndLowerChanges(); |
378 | 378 |
379 for (int k = -5; k <= 5; k++) { | 379 for (int k = -5; k <= 5; k++) { |
380 Smi* expected = Smi::FromInt(k); | 380 Smi* expected = Smi::FromInt(k); |
381 smis[i + j] = Smi::FromInt(-100); | 381 smis[i + j] = Smi::FromInt(-100); |
382 CHECK_EQ(expected, t.Call(expected)); | 382 CHECK_EQ(expected, t.Call(expected)); |
383 CHECK_EQ(expected, smis[i + j]); | 383 CHECK_EQ(expected, smis[i + j]); |
384 } | 384 } |
385 | 385 |
386 // TODO(titzer): assert the contents of the array. | 386 // TODO(titzer): assert the contents of the array. |
387 } | 387 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 // a constant in the code. | 432 // a constant in the code. |
433 BoundsCheck(from_index); | 433 BoundsCheck(from_index); |
434 BoundsCheck(to_index); | 434 BoundsCheck(to_index); |
435 ElementAccess access = GetElementAccess(); | 435 ElementAccess access = GetElementAccess(); |
436 | 436 |
437 SimplifiedLoweringTester<Object*> t; | 437 SimplifiedLoweringTester<Object*> t; |
438 Node* ptr = GetBaseNode(&t); | 438 Node* ptr = GetBaseNode(&t); |
439 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); | 439 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); |
440 t.StoreElement(access, ptr, t.Int32Constant(to_index), load); | 440 t.StoreElement(access, ptr, t.Int32Constant(to_index), load); |
441 t.Return(t.jsgraph.TrueConstant()); | 441 t.Return(t.jsgraph.TrueConstant()); |
442 t.LowerAllNodes(); | 442 t.LowerAllNodesAndLowerChanges(); |
443 t.GenerateCode(); | 443 t.GenerateCode(); |
444 | 444 |
445 Object* result = t.Call(); | 445 Object* result = t.Call(); |
446 CHECK_EQ(t.isolate()->heap()->true_value(), result); | 446 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
447 } | 447 } |
448 | 448 |
449 // Create and run code that copies the field in either {untagged_array} | 449 // Create and run code that copies the field in either {untagged_array} |
450 // or {tagged_array} at index {from_index} to index {to_index}. | 450 // or {tagged_array} at index {from_index} to index {to_index}. |
451 void RunCopyField(int from_index, int to_index) { | 451 void RunCopyField(int from_index, int to_index) { |
452 BoundsCheck(from_index); | 452 BoundsCheck(from_index); |
453 BoundsCheck(to_index); | 453 BoundsCheck(to_index); |
454 FieldAccess from_access = GetFieldAccess(from_index); | 454 FieldAccess from_access = GetFieldAccess(from_index); |
455 FieldAccess to_access = GetFieldAccess(to_index); | 455 FieldAccess to_access = GetFieldAccess(to_index); |
456 | 456 |
457 SimplifiedLoweringTester<Object*> t; | 457 SimplifiedLoweringTester<Object*> t; |
458 Node* ptr = GetBaseNode(&t); | 458 Node* ptr = GetBaseNode(&t); |
459 Node* load = t.LoadField(from_access, ptr); | 459 Node* load = t.LoadField(from_access, ptr); |
460 t.StoreField(to_access, ptr, load); | 460 t.StoreField(to_access, ptr, load); |
461 t.Return(t.jsgraph.TrueConstant()); | 461 t.Return(t.jsgraph.TrueConstant()); |
462 t.LowerAllNodes(); | 462 t.LowerAllNodesAndLowerChanges(); |
463 t.GenerateCode(); | 463 t.GenerateCode(); |
464 | 464 |
465 Object* result = t.Call(); | 465 Object* result = t.Call(); |
466 CHECK_EQ(t.isolate()->heap()->true_value(), result); | 466 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
467 } | 467 } |
468 | 468 |
469 // Create and run code that copies the elements from {this} to {that}. | 469 // Create and run code that copies the elements from {this} to {that}. |
470 void RunCopyElements(AccessTester<E>* that) { | 470 void RunCopyElements(AccessTester<E>* that) { |
471 // TODO(titzer): Rewrite this test without StructuredGraphBuilder support. | 471 // TODO(titzer): Rewrite this test without StructuredGraphBuilder support. |
472 #if 0 | 472 #if 0 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 | 644 |
645 for (size_t i = 0; i < arraysize(flag); i++) { | 645 for (size_t i = 0; i < arraysize(flag); i++) { |
646 SimplifiedLoweringTester<HeapObject*> t; | 646 SimplifiedLoweringTester<HeapObject*> t; |
647 FieldAccess access = AccessBuilder::ForMap(); | 647 FieldAccess access = AccessBuilder::ForMap(); |
648 Node* size = t.jsgraph.Constant(HeapNumber::kSize); | 648 Node* size = t.jsgraph.Constant(HeapNumber::kSize); |
649 Node* alloc = t.NewNode(t.simplified()->Allocate(flag[i]), size); | 649 Node* alloc = t.NewNode(t.simplified()->Allocate(flag[i]), size); |
650 Node* map = t.jsgraph.Constant(t.factory()->heap_number_map()); | 650 Node* map = t.jsgraph.Constant(t.factory()->heap_number_map()); |
651 t.StoreField(access, alloc, map); | 651 t.StoreField(access, alloc, map); |
652 t.Return(alloc); | 652 t.Return(alloc); |
653 | 653 |
654 t.LowerAllNodes(); | 654 t.LowerAllNodesAndLowerChanges(); |
655 t.GenerateCode(); | 655 t.GenerateCode(); |
656 | 656 |
657 HeapObject* result = t.CallWithPotentialGC<HeapObject>(); | 657 HeapObject* result = t.CallWithPotentialGC<HeapObject>(); |
658 CHECK(t.heap()->new_space()->Contains(result) || flag[i] == TENURED); | 658 CHECK(t.heap()->new_space()->Contains(result) || flag[i] == TENURED); |
659 CHECK(t.heap()->old_space()->Contains(result) || flag[i] == NOT_TENURED); | 659 CHECK(t.heap()->old_space()->Contains(result) || flag[i] == NOT_TENURED); |
660 CHECK(result->IsHeapNumber()); | 660 CHECK(result->IsHeapNumber()); |
661 } | 661 } |
662 } | 662 } |
663 | 663 |
664 | 664 |
(...skipping 10 matching lines...) Expand all Loading... |
675 Node* end; | 675 Node* end; |
676 Node* ret; | 676 Node* ret; |
677 | 677 |
678 explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(), | 678 explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(), |
679 Type* p2_type = Type::None()) | 679 Type* p2_type = Type::None()) |
680 : GraphAndBuilders(main_zone()), | 680 : GraphAndBuilders(main_zone()), |
681 typer(main_isolate(), graph()), | 681 typer(main_isolate(), graph()), |
682 javascript(main_zone()), | 682 javascript(main_zone()), |
683 jsgraph(main_isolate(), graph(), common(), &javascript, simplified(), | 683 jsgraph(main_isolate(), graph(), common(), &javascript, simplified(), |
684 machine()) { | 684 machine()) { |
685 start = graph()->NewNode(common()->Start(2)); | 685 start = graph()->NewNode(common()->Start(4)); |
686 graph()->SetStart(start); | 686 graph()->SetStart(start); |
687 ret = | 687 ret = |
688 graph()->NewNode(common()->Return(), jsgraph.Constant(0), start, start); | 688 graph()->NewNode(common()->Return(), jsgraph.Constant(0), start, start); |
689 end = graph()->NewNode(common()->End(1), ret); | 689 end = graph()->NewNode(common()->End(1), ret); |
690 graph()->SetEnd(end); | 690 graph()->SetEnd(end); |
691 p0 = graph()->NewNode(common()->Parameter(0), start); | 691 p0 = graph()->NewNode(common()->Parameter(0), start); |
692 p1 = graph()->NewNode(common()->Parameter(1), start); | 692 p1 = graph()->NewNode(common()->Parameter(1), start); |
693 p2 = graph()->NewNode(common()->Parameter(2), start); | 693 p2 = graph()->NewNode(common()->Parameter(2), start); |
694 typer.Run(); | 694 typer.Run(); |
695 NodeProperties::SetType(p0, p0_type); | 695 NodeProperties::SetType(p0, p0_type); |
(...skipping 20 matching lines...) Expand all Loading... |
716 Return(graph()->NewNode(trunc, node)); | 716 Return(graph()->NewNode(trunc, node)); |
717 Lower(); | 717 Lower(); |
718 CHECK_EQ(expected, node->opcode()); | 718 CHECK_EQ(expected, node->opcode()); |
719 } | 719 } |
720 | 720 |
721 void Lower() { | 721 void Lower() { |
722 SourcePositionTable table(jsgraph.graph()); | 722 SourcePositionTable table(jsgraph.graph()); |
723 SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes(); | 723 SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes(); |
724 } | 724 } |
725 | 725 |
| 726 void LowerAllNodesAndLowerChanges() { |
| 727 SourcePositionTable table(jsgraph.graph()); |
| 728 SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes(); |
| 729 |
| 730 ChangeLowering lowering(&jsgraph); |
| 731 GraphReducer reducer(this->zone(), this->graph()); |
| 732 reducer.AddReducer(&lowering); |
| 733 reducer.ReduceGraph(); |
| 734 Verifier::Run(this->graph()); |
| 735 } |
| 736 |
726 // Inserts the node as the return value of the graph. | 737 // Inserts the node as the return value of the graph. |
727 Node* Return(Node* node) { | 738 Node* Return(Node* node) { |
728 ret->ReplaceInput(0, node); | 739 ret->ReplaceInput(0, node); |
729 return node; | 740 return node; |
730 } | 741 } |
731 | 742 |
732 // Inserts the node as the effect input to the return of the graph. | 743 // Inserts the node as the effect input to the return of the graph. |
733 void Effect(Node* node) { ret->ReplaceInput(1, node); } | 744 void Effect(Node* node) { ret->ReplaceInput(1, node); } |
734 | 745 |
735 Node* ExampleWithOutput(MachineType type) { | 746 Node* ExampleWithOutput(MachineType type) { |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 TestingGraph t(Type::Any(), Type::Signed32()); | 1372 TestingGraph t(Type::Any(), Type::Signed32()); |
1362 | 1373 |
1363 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1374 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1364 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1375 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1365 Handle<Name>::null(), Type::Any(), kMachineReps[i]}; | 1376 Handle<Name>::null(), Type::Any(), kMachineReps[i]}; |
1366 | 1377 |
1367 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, | 1378 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, |
1368 t.start, t.start); | 1379 t.start, t.start); |
1369 Node* use = t.Use(load, kMachineReps[i]); | 1380 Node* use = t.Use(load, kMachineReps[i]); |
1370 t.Return(use); | 1381 t.Return(use); |
1371 t.Lower(); | 1382 t.LowerAllNodesAndLowerChanges(); |
1372 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1383 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1373 CHECK_EQ(t.p0, load->InputAt(0)); | 1384 CHECK_EQ(t.p0, load->InputAt(0)); |
1374 CheckFieldAccessArithmetic(access, load); | 1385 CheckFieldAccessArithmetic(access, load); |
1375 | 1386 |
1376 MachineType rep = OpParameter<MachineType>(load); | 1387 MachineType rep = OpParameter<MachineType>(load); |
1377 CHECK_EQ(kMachineReps[i], rep); | 1388 CHECK_EQ(kMachineReps[i], rep); |
1378 } | 1389 } |
1379 } | 1390 } |
1380 | 1391 |
1381 | 1392 |
1382 TEST(LowerStoreField_to_store) { | 1393 TEST(LowerStoreField_to_store) { |
1383 { | 1394 { |
1384 TestingGraph t(Type::Any(), Type::Signed32()); | 1395 TestingGraph t(Type::Any(), Type::Signed32()); |
1385 | 1396 |
1386 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1397 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1387 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1398 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1388 Handle<Name>::null(), Type::Any(), kMachineReps[i]}; | 1399 Handle<Name>::null(), Type::Any(), kMachineReps[i]}; |
1389 | 1400 |
1390 | 1401 |
1391 Node* val = t.ExampleWithOutput(kMachineReps[i]); | 1402 Node* val = t.ExampleWithOutput(kMachineReps[i]); |
1392 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1403 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1393 val, t.start, t.start); | 1404 val, t.start, t.start); |
1394 t.Effect(store); | 1405 t.Effect(store); |
1395 t.Lower(); | 1406 t.LowerAllNodesAndLowerChanges(); |
1396 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1407 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1397 CHECK_EQ(val, store->InputAt(2)); | 1408 CHECK_EQ(val, store->InputAt(2)); |
1398 CheckFieldAccessArithmetic(access, store); | 1409 CheckFieldAccessArithmetic(access, store); |
1399 | 1410 |
1400 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); | 1411 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); |
1401 if (kMachineReps[i] & kRepTagged) { | 1412 if (kMachineReps[i] & kRepTagged) { |
1402 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); | 1413 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); |
1403 } | 1414 } |
1404 CHECK_EQ(kMachineReps[i], rep.machine_type()); | 1415 CHECK_EQ(kMachineReps[i], rep.machine_type()); |
1405 } | 1416 } |
1406 } | 1417 } |
1407 { | 1418 { |
1408 HandleAndZoneScope scope; | 1419 HandleAndZoneScope scope; |
1409 Zone* z = scope.main_zone(); | 1420 Zone* z = scope.main_zone(); |
1410 TestingGraph t(Type::Any(), Type::Intersect(Type::SignedSmall(), | 1421 TestingGraph t(Type::Any(), Type::Intersect(Type::SignedSmall(), |
1411 Type::TaggedSigned(), z)); | 1422 Type::TaggedSigned(), z)); |
1412 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1423 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1413 Handle<Name>::null(), Type::Any(), kMachAnyTagged}; | 1424 Handle<Name>::null(), Type::Any(), kMachAnyTagged}; |
1414 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1425 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1415 t.p1, t.start, t.start); | 1426 t.p1, t.start, t.start); |
1416 t.Effect(store); | 1427 t.Effect(store); |
1417 t.Lower(); | 1428 t.LowerAllNodesAndLowerChanges(); |
1418 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1429 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1419 CHECK_EQ(t.p1, store->InputAt(2)); | 1430 CHECK_EQ(t.p1, store->InputAt(2)); |
1420 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); | 1431 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); |
1421 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); | 1432 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); |
1422 } | 1433 } |
1423 } | 1434 } |
1424 | 1435 |
1425 | 1436 |
1426 TEST(LowerLoadElement_to_load) { | 1437 TEST(LowerLoadElement_to_load) { |
1427 TestingGraph t(Type::Any(), Type::Signed32()); | 1438 TestingGraph t(Type::Any(), Type::Signed32()); |
1428 | 1439 |
1429 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1440 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1430 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1441 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1431 Type::Any(), kMachineReps[i]}; | 1442 Type::Any(), kMachineReps[i]}; |
1432 | 1443 |
1433 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1444 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1434 t.p1, t.start, t.start); | 1445 t.p1, t.start, t.start); |
1435 Node* use = t.Use(load, kMachineReps[i]); | 1446 Node* use = t.Use(load, kMachineReps[i]); |
1436 t.Return(use); | 1447 t.Return(use); |
1437 t.Lower(); | 1448 t.LowerAllNodesAndLowerChanges(); |
1438 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1449 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1439 CHECK_EQ(t.p0, load->InputAt(0)); | 1450 CHECK_EQ(t.p0, load->InputAt(0)); |
1440 CheckElementAccessArithmetic(access, load); | 1451 CheckElementAccessArithmetic(access, load); |
1441 | 1452 |
1442 MachineType rep = OpParameter<MachineType>(load); | 1453 MachineType rep = OpParameter<MachineType>(load); |
1443 CHECK_EQ(kMachineReps[i], rep); | 1454 CHECK_EQ(kMachineReps[i], rep); |
1444 } | 1455 } |
1445 } | 1456 } |
1446 | 1457 |
1447 | 1458 |
1448 TEST(LowerStoreElement_to_store) { | 1459 TEST(LowerStoreElement_to_store) { |
1449 { | 1460 { |
1450 TestingGraph t(Type::Any(), Type::Signed32()); | 1461 TestingGraph t(Type::Any(), Type::Signed32()); |
1451 | 1462 |
1452 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1463 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1453 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1464 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1454 Type::Any(), kMachineReps[i]}; | 1465 Type::Any(), kMachineReps[i]}; |
1455 | 1466 |
1456 Node* val = t.ExampleWithOutput(kMachineReps[i]); | 1467 Node* val = t.ExampleWithOutput(kMachineReps[i]); |
1457 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), | 1468 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), |
1458 t.p0, t.p1, val, t.start, t.start); | 1469 t.p0, t.p1, val, t.start, t.start); |
1459 t.Effect(store); | 1470 t.Effect(store); |
1460 t.Lower(); | 1471 t.LowerAllNodesAndLowerChanges(); |
1461 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1472 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1462 CHECK_EQ(val, store->InputAt(2)); | 1473 CHECK_EQ(val, store->InputAt(2)); |
1463 CheckElementAccessArithmetic(access, store); | 1474 CheckElementAccessArithmetic(access, store); |
1464 | 1475 |
1465 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); | 1476 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); |
1466 if (kMachineReps[i] & kRepTagged) { | 1477 if (kMachineReps[i] & kRepTagged) { |
1467 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); | 1478 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); |
1468 } | 1479 } |
1469 CHECK_EQ(kMachineReps[i], rep.machine_type()); | 1480 CHECK_EQ(kMachineReps[i], rep.machine_type()); |
1470 } | 1481 } |
1471 } | 1482 } |
1472 { | 1483 { |
1473 HandleAndZoneScope scope; | 1484 HandleAndZoneScope scope; |
1474 Zone* z = scope.main_zone(); | 1485 Zone* z = scope.main_zone(); |
1475 TestingGraph t( | 1486 TestingGraph t( |
1476 Type::Any(), Type::Signed32(), | 1487 Type::Any(), Type::Signed32(), |
1477 Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z)); | 1488 Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z)); |
1478 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1489 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1479 Type::Any(), kMachAnyTagged}; | 1490 Type::Any(), kMachAnyTagged}; |
1480 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, | 1491 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, |
1481 t.p1, t.p2, t.start, t.start); | 1492 t.p1, t.p2, t.start, t.start); |
1482 t.Effect(store); | 1493 t.Effect(store); |
1483 t.Lower(); | 1494 t.LowerAllNodesAndLowerChanges(); |
1484 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1495 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1485 CHECK_EQ(t.p2, store->InputAt(2)); | 1496 CHECK_EQ(t.p2, store->InputAt(2)); |
1486 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); | 1497 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); |
1487 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); | 1498 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); |
1488 } | 1499 } |
1489 } | 1500 } |
1490 | 1501 |
1491 | 1502 |
1492 TEST(InsertChangeForLoadElementIndex) { | 1503 TEST(InsertChangeForLoadElementIndex) { |
1493 // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) => | 1504 // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) => |
1494 // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) | 1505 // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) |
1495 TestingGraph t(Type::Any(), Type::Signed32()); | 1506 TestingGraph t(Type::Any(), Type::Signed32()); |
1496 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), | 1507 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1497 kMachAnyTagged}; | 1508 kMachAnyTagged}; |
1498 | 1509 |
1499 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1510 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1500 t.p1, t.start, t.start); | 1511 t.p1, t.start, t.start); |
1501 t.Return(load); | 1512 t.Return(load); |
1502 t.Lower(); | 1513 t.Lower(); |
1503 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1514 CHECK_EQ(IrOpcode::kLoadElement, load->opcode()); |
1504 CHECK_EQ(t.p0, load->InputAt(0)); | 1515 CHECK_EQ(t.p0, load->InputAt(0)); |
1505 | 1516 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, load->InputAt(1)); |
1506 Node* index = CheckElementAccessArithmetic(access, load); | |
1507 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index); | |
1508 } | 1517 } |
1509 | 1518 |
1510 | 1519 |
1511 TEST(InsertChangeForStoreElementIndex) { | 1520 TEST(InsertChangeForStoreElementIndex) { |
1512 // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) => | 1521 // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) => |
1513 // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) | 1522 // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) |
1514 TestingGraph t(Type::Any(), Type::Signed32()); | 1523 TestingGraph t(Type::Any(), Type::Signed32()); |
1515 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), | 1524 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1516 kMachAnyTagged}; | 1525 kMachAnyTagged}; |
1517 | 1526 |
1518 Node* store = | 1527 Node* store = |
1519 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, | 1528 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, |
1520 t.jsgraph.TrueConstant(), t.start, t.start); | 1529 t.jsgraph.TrueConstant(), t.start, t.start); |
1521 t.Effect(store); | 1530 t.Effect(store); |
1522 t.Lower(); | 1531 t.Lower(); |
1523 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1532 CHECK_EQ(IrOpcode::kStoreElement, store->opcode()); |
1524 CHECK_EQ(t.p0, store->InputAt(0)); | 1533 CHECK_EQ(t.p0, store->InputAt(0)); |
1525 | 1534 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, store->InputAt(1)); |
1526 Node* index = CheckElementAccessArithmetic(access, store); | |
1527 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index); | |
1528 } | 1535 } |
1529 | 1536 |
1530 | 1537 |
1531 TEST(InsertChangeForLoadElement) { | 1538 TEST(InsertChangeForLoadElement) { |
1532 // TODO(titzer): test all load/store representation change insertions. | 1539 // TODO(titzer): test all load/store representation change insertions. |
1533 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); | 1540 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); |
1534 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), | 1541 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1535 kMachFloat64}; | 1542 kMachFloat64}; |
1536 | 1543 |
1537 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1544 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1538 t.p1, t.start, t.start); | 1545 t.p1, t.start, t.start); |
1539 t.Return(load); | 1546 t.Return(load); |
1540 t.Lower(); | 1547 t.Lower(); |
1541 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1548 CHECK_EQ(IrOpcode::kLoadElement, load->opcode()); |
1542 CHECK_EQ(t.p0, load->InputAt(0)); | 1549 CHECK_EQ(t.p0, load->InputAt(0)); |
1543 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); | 1550 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); |
1544 } | 1551 } |
1545 | 1552 |
1546 | 1553 |
1547 TEST(InsertChangeForLoadField) { | 1554 TEST(InsertChangeForLoadField) { |
1548 // TODO(titzer): test all load/store representation change insertions. | 1555 // TODO(titzer): test all load/store representation change insertions. |
1549 TestingGraph t(Type::Any(), Type::Signed32()); | 1556 TestingGraph t(Type::Any(), Type::Signed32()); |
1550 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1557 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1551 Handle<Name>::null(), Type::Any(), kMachFloat64}; | 1558 Handle<Name>::null(), Type::Any(), kMachFloat64}; |
1552 | 1559 |
1553 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, | 1560 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, |
1554 t.start, t.start); | 1561 t.start, t.start); |
1555 t.Return(load); | 1562 t.Return(load); |
1556 t.Lower(); | 1563 t.Lower(); |
1557 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1564 CHECK_EQ(IrOpcode::kLoadField, load->opcode()); |
1558 CHECK_EQ(t.p0, load->InputAt(0)); | 1565 CHECK_EQ(t.p0, load->InputAt(0)); |
1559 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); | 1566 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); |
1560 } | 1567 } |
1561 | 1568 |
1562 | 1569 |
1563 TEST(InsertChangeForStoreElement) { | 1570 TEST(InsertChangeForStoreElement) { |
1564 // TODO(titzer): test all load/store representation change insertions. | 1571 // TODO(titzer): test all load/store representation change insertions. |
1565 TestingGraph t(Type::Any(), Type::Signed32()); | 1572 TestingGraph t(Type::Any(), Type::Signed32()); |
1566 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), | 1573 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1567 kMachFloat64}; | 1574 kMachFloat64}; |
1568 | 1575 |
1569 Node* store = | 1576 Node* store = |
1570 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, | 1577 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, |
1571 t.jsgraph.Int32Constant(0), t.p1, t.start, t.start); | 1578 t.jsgraph.Int32Constant(0), t.p1, t.start, t.start); |
1572 t.Effect(store); | 1579 t.Effect(store); |
1573 t.Lower(); | 1580 t.Lower(); |
1574 | 1581 |
1575 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1582 CHECK_EQ(IrOpcode::kStoreElement, store->opcode()); |
1576 CHECK_EQ(t.p0, store->InputAt(0)); | 1583 CHECK_EQ(t.p0, store->InputAt(0)); |
1577 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); | 1584 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); |
1578 } | 1585 } |
1579 | 1586 |
1580 | 1587 |
1581 TEST(InsertChangeForStoreField) { | 1588 TEST(InsertChangeForStoreField) { |
1582 // TODO(titzer): test all load/store representation change insertions. | 1589 // TODO(titzer): test all load/store representation change insertions. |
1583 TestingGraph t(Type::Any(), Type::Signed32()); | 1590 TestingGraph t(Type::Any(), Type::Signed32()); |
1584 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1591 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1585 Handle<Name>::null(), Type::Any(), kMachFloat64}; | 1592 Handle<Name>::null(), Type::Any(), kMachFloat64}; |
1586 | 1593 |
1587 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1594 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1588 t.p1, t.start, t.start); | 1595 t.p1, t.start, t.start); |
1589 t.Effect(store); | 1596 t.Effect(store); |
1590 t.Lower(); | 1597 t.Lower(); |
1591 | 1598 |
1592 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1599 CHECK_EQ(IrOpcode::kStoreField, store->opcode()); |
1593 CHECK_EQ(t.p0, store->InputAt(0)); | 1600 CHECK_EQ(t.p0, store->InputAt(0)); |
1594 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); | 1601 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(1)); |
1595 } | 1602 } |
1596 | 1603 |
1597 | 1604 |
1598 TEST(UpdatePhi) { | 1605 TEST(UpdatePhi) { |
1599 TestingGraph t(Type::Any(), Type::Signed32()); | 1606 TestingGraph t(Type::Any(), Type::Signed32()); |
1600 static const MachineType kMachineTypes[] = {kMachInt32, kMachUint32, | 1607 static const MachineType kMachineTypes[] = {kMachInt32, kMachUint32, |
1601 kMachFloat64}; | 1608 kMachFloat64}; |
1602 Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()}; | 1609 Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()}; |
1603 | 1610 |
1604 for (size_t i = 0; i < arraysize(kMachineTypes); i++) { | 1611 for (size_t i = 0; i < arraysize(kMachineTypes); i++) { |
(...skipping 16 matching lines...) Expand all Loading... |
1621 } | 1628 } |
1622 | 1629 |
1623 | 1630 |
1624 TEST(RunNumberDivide_minus_1_TruncatingToInt32) { | 1631 TEST(RunNumberDivide_minus_1_TruncatingToInt32) { |
1625 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 1632 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
1626 Node* num = t.NumberToInt32(t.Parameter(0)); | 1633 Node* num = t.NumberToInt32(t.Parameter(0)); |
1627 Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1)); | 1634 Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1)); |
1628 Node* trunc = t.NumberToInt32(div); | 1635 Node* trunc = t.NumberToInt32(div); |
1629 t.Return(trunc); | 1636 t.Return(trunc); |
1630 | 1637 |
1631 t.LowerAllNodesAndLowerChanges(); | 1638 t.LowerAllNodesAndLowerChanges(); |
1632 t.GenerateCode(); | 1639 t.GenerateCode(); |
1633 | 1640 |
1634 FOR_INT32_INPUTS(i) { | 1641 FOR_INT32_INPUTS(i) { |
1635 int32_t x = 0 - *i; | 1642 int32_t x = 0 - *i; |
1636 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); | 1643 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); |
1637 } | 1644 } |
1638 } | 1645 } |
1639 | 1646 |
1640 | 1647 |
1641 TEST(NumberMultiply_TruncatingToInt32) { | 1648 TEST(NumberMultiply_TruncatingToInt32) { |
1642 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000}; | 1649 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000}; |
1643 | 1650 |
1644 for (size_t i = 0; i < arraysize(constants); i++) { | 1651 for (size_t i = 0; i < arraysize(constants); i++) { |
1645 TestingGraph t(Type::Signed32()); | 1652 TestingGraph t(Type::Signed32()); |
1646 Node* k = t.jsgraph.Constant(constants[i]); | 1653 Node* k = t.jsgraph.Constant(constants[i]); |
1647 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k); | 1654 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k); |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2004 t.Return(use); | 2011 t.Return(use); |
2005 t.Lower(); | 2012 t.Lower(); |
2006 | 2013 |
2007 CHECK_EQ(d.expected, OpParameter<MachineType>(phi)); | 2014 CHECK_EQ(d.expected, OpParameter<MachineType>(phi)); |
2008 } | 2015 } |
2009 } | 2016 } |
2010 | 2017 |
2011 } // namespace compiler | 2018 } // namespace compiler |
2012 } // namespace internal | 2019 } // namespace internal |
2013 } // namespace v8 | 2020 } // namespace v8 |
OLD | NEW |