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 <limits> | 5 #include <limits> |
6 | 6 |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/change-lowering.h" | 8 #include "src/compiler/change-lowering.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/graph-reducer.h" | 10 #include "src/compiler/graph-reducer.h" |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 CHECK(result->IsMap()); | 225 CHECK(result->IsMap()); |
226 CHECK_EQ(*src_map, result); | 226 CHECK_EQ(*src_map, result); |
227 CHECK(*src_map == dst->map()); | 227 CHECK(*src_map == dst->map()); |
228 } | 228 } |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 TEST(RunLoadStoreFixedArrayIndex) { | 232 TEST(RunLoadStoreFixedArrayIndex) { |
233 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 233 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
234 ElementAccess access = AccessBuilder::ForFixedArrayElement(); | 234 ElementAccess access = AccessBuilder::ForFixedArrayElement(); |
235 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0), | 235 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); |
236 t.Int32Constant(2)); | 236 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); |
237 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), t.Int32Constant(2), | |
238 load); | |
239 t.Return(load); | 237 t.Return(load); |
240 | 238 |
241 t.LowerAllNodes(); | 239 t.LowerAllNodes(); |
242 t.GenerateCode(); | 240 t.GenerateCode(); |
243 | 241 |
244 if (Pipeline::SupportedTarget()) { | 242 if (Pipeline::SupportedTarget()) { |
245 Handle<FixedArray> array = t.factory()->NewFixedArray(2); | 243 Handle<FixedArray> array = t.factory()->NewFixedArray(2); |
246 Handle<JSObject> src = TestObject(); | 244 Handle<JSObject> src = TestObject(); |
247 Handle<JSObject> dst = TestObject(); | 245 Handle<JSObject> dst = TestObject(); |
248 array->set(0, *src); | 246 array->set(0, *src); |
249 array->set(1, *dst); | 247 array->set(1, *dst); |
250 Object* result = t.Call(*array); | 248 Object* result = t.Call(*array); |
251 CHECK_EQ(*src, result); | 249 CHECK_EQ(*src, result); |
252 CHECK_EQ(*src, array->get(0)); | 250 CHECK_EQ(*src, array->get(0)); |
253 CHECK_EQ(*src, array->get(1)); | 251 CHECK_EQ(*src, array->get(1)); |
254 } | 252 } |
255 } | 253 } |
256 | 254 |
257 | 255 |
258 TEST(RunLoadStoreArrayBuffer) { | 256 TEST(RunLoadStoreArrayBuffer) { |
259 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 257 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
260 const int index = 12; | 258 const int index = 12; |
261 const int array_length = 2 * index; | 259 const int array_length = 2 * index; |
262 ElementAccess buffer_access = | 260 ElementAccess buffer_access = |
263 AccessBuilder::ForTypedArrayElement(v8::kExternalInt8Array, true); | 261 AccessBuilder::ForTypedArrayElement(v8::kExternalInt8Array, true); |
264 Node* backing_store = t.LoadField( | 262 Node* backing_store = t.LoadField( |
265 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); | 263 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); |
266 Node* load = | 264 Node* load = |
267 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index), | 265 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); |
268 t.Int32Constant(array_length)); | |
269 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), | 266 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), |
270 t.Int32Constant(array_length), load); | 267 load); |
271 t.Return(t.jsgraph.TrueConstant()); | 268 t.Return(t.jsgraph.TrueConstant()); |
272 | 269 |
273 t.LowerAllNodes(); | 270 t.LowerAllNodes(); |
274 t.GenerateCode(); | 271 t.GenerateCode(); |
275 | 272 |
276 if (Pipeline::SupportedTarget()) { | 273 if (Pipeline::SupportedTarget()) { |
277 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); | 274 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); |
278 Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length); | 275 Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length); |
279 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); | 276 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); |
280 for (int i = 0; i < array_length; i++) { | 277 for (int i = 0; i < array_length; i++) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 } | 340 } |
344 | 341 |
345 | 342 |
346 TEST(RunLoadElementFromUntaggedBase) { | 343 TEST(RunLoadElementFromUntaggedBase) { |
347 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | 344 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
348 Smi::FromInt(4), Smi::FromInt(5)}; | 345 Smi::FromInt(4), Smi::FromInt(5)}; |
349 | 346 |
350 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes | 347 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes |
351 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index | 348 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index |
352 int offset = static_cast<int>(i * sizeof(Smi*)); | 349 int offset = static_cast<int>(i * sizeof(Smi*)); |
353 ElementAccess access = {kNoBoundsCheck, kUntaggedBase, offset, | 350 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), |
354 Type::Integral32(), kMachAnyTagged}; | 351 kMachAnyTagged}; |
355 | 352 |
356 SimplifiedLoweringTester<Object*> t; | 353 SimplifiedLoweringTester<Object*> t; |
357 Node* load = t.LoadElement( | 354 Node* load = t.LoadElement(access, t.PointerConstant(smis), |
358 access, t.PointerConstant(smis), t.Int32Constant(static_cast<int>(j)), | 355 t.Int32Constant(static_cast<int>(j))); |
359 t.Int32Constant(static_cast<int>(arraysize(smis)))); | |
360 t.Return(load); | 356 t.Return(load); |
361 t.LowerAllNodes(); | 357 t.LowerAllNodes(); |
362 | 358 |
363 if (!Pipeline::SupportedTarget()) continue; | 359 if (!Pipeline::SupportedTarget()) continue; |
364 | 360 |
365 for (int k = -5; k <= 5; k++) { | 361 for (int k = -5; k <= 5; k++) { |
366 Smi* expected = Smi::FromInt(k); | 362 Smi* expected = Smi::FromInt(k); |
367 smis[i + j] = expected; | 363 smis[i + j] = expected; |
368 CHECK_EQ(expected, t.Call()); | 364 CHECK_EQ(expected, t.Call()); |
369 } | 365 } |
370 } | 366 } |
371 } | 367 } |
372 } | 368 } |
373 | 369 |
374 | 370 |
375 TEST(RunStoreElementFromUntaggedBase) { | 371 TEST(RunStoreElementFromUntaggedBase) { |
376 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | 372 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
377 Smi::FromInt(4), Smi::FromInt(5)}; | 373 Smi::FromInt(4), Smi::FromInt(5)}; |
378 | 374 |
379 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes | 375 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes |
380 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index | 376 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index |
381 int offset = static_cast<int>(i * sizeof(Smi*)); | 377 int offset = static_cast<int>(i * sizeof(Smi*)); |
382 ElementAccess access = {kNoBoundsCheck, kUntaggedBase, offset, | 378 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), |
383 Type::Integral32(), kMachAnyTagged}; | 379 kMachAnyTagged}; |
384 | 380 |
385 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 381 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
386 Node* p0 = t.Parameter(0); | 382 Node* p0 = t.Parameter(0); |
387 t.StoreElement(access, t.PointerConstant(smis), | 383 t.StoreElement(access, t.PointerConstant(smis), |
388 t.Int32Constant(static_cast<int>(j)), | 384 t.Int32Constant(static_cast<int>(j)), p0); |
389 t.Int32Constant(static_cast<int>(arraysize(smis))), p0); | |
390 t.Return(p0); | 385 t.Return(p0); |
391 t.LowerAllNodes(); | 386 t.LowerAllNodes(); |
392 | 387 |
393 if (!Pipeline::SupportedTarget()) continue; | 388 if (!Pipeline::SupportedTarget()) continue; |
394 | 389 |
395 for (int k = -5; k <= 5; k++) { | 390 for (int k = -5; k <= 5; k++) { |
396 Smi* expected = Smi::FromInt(k); | 391 Smi* expected = Smi::FromInt(k); |
397 smis[i + j] = Smi::FromInt(-100); | 392 smis[i + j] = Smi::FromInt(-100); |
398 CHECK_EQ(expected, t.Call(expected)); | 393 CHECK_EQ(expected, t.Call(expected)); |
399 CHECK_EQ(expected, smis[i + j]); | 394 CHECK_EQ(expected, smis[i + j]); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 // or {tagged_array} at index {from_index} to index {to_index}. | 440 // or {tagged_array} at index {from_index} to index {to_index}. |
446 void RunCopyElement(int from_index, int to_index) { | 441 void RunCopyElement(int from_index, int to_index) { |
447 // TODO(titzer): test element and field accesses where the base is not | 442 // TODO(titzer): test element and field accesses where the base is not |
448 // a constant in the code. | 443 // a constant in the code. |
449 BoundsCheck(from_index); | 444 BoundsCheck(from_index); |
450 BoundsCheck(to_index); | 445 BoundsCheck(to_index); |
451 ElementAccess access = GetElementAccess(); | 446 ElementAccess access = GetElementAccess(); |
452 | 447 |
453 SimplifiedLoweringTester<Object*> t; | 448 SimplifiedLoweringTester<Object*> t; |
454 Node* ptr = GetBaseNode(&t); | 449 Node* ptr = GetBaseNode(&t); |
455 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index), | 450 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); |
456 t.Int32Constant(static_cast<int>(num_elements))); | 451 t.StoreElement(access, ptr, t.Int32Constant(to_index), load); |
457 t.StoreElement(access, ptr, t.Int32Constant(to_index), | |
458 t.Int32Constant(static_cast<int>(num_elements)), load); | |
459 t.Return(t.jsgraph.TrueConstant()); | 452 t.Return(t.jsgraph.TrueConstant()); |
460 t.LowerAllNodes(); | 453 t.LowerAllNodes(); |
461 t.GenerateCode(); | 454 t.GenerateCode(); |
462 | 455 |
463 if (Pipeline::SupportedTarget()) { | 456 if (Pipeline::SupportedTarget()) { |
464 Object* result = t.Call(); | 457 Object* result = t.Call(); |
465 CHECK_EQ(t.isolate()->heap()->true_value(), result); | 458 CHECK_EQ(t.isolate()->heap()->true_value(), result); |
466 } | 459 } |
467 } | 460 } |
468 | 461 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 if (tagged) { | 528 if (tagged) { |
536 E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress()); | 529 E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress()); |
537 return raw[index]; | 530 return raw[index]; |
538 } else { | 531 } else { |
539 return untagged_array[index]; | 532 return untagged_array[index]; |
540 } | 533 } |
541 } | 534 } |
542 | 535 |
543 private: | 536 private: |
544 ElementAccess GetElementAccess() { | 537 ElementAccess GetElementAccess() { |
545 ElementAccess access = { | 538 ElementAccess access = {tagged ? kTaggedBase : kUntaggedBase, |
546 kNoBoundsCheck, tagged ? kTaggedBase : kUntaggedBase, | 539 tagged ? FixedArrayBase::kHeaderSize : 0, |
547 tagged ? FixedArrayBase::kHeaderSize : 0, Type::Any(), rep}; | 540 Type::Any(), rep}; |
548 return access; | 541 return access; |
549 } | 542 } |
550 | 543 |
551 FieldAccess GetFieldAccess(int field) { | 544 FieldAccess GetFieldAccess(int field) { |
552 int offset = field * sizeof(E); | 545 int offset = field * sizeof(E); |
553 FieldAccess access = {tagged ? kTaggedBase : kUntaggedBase, | 546 FieldAccess access = {tagged ? kTaggedBase : kUntaggedBase, |
554 offset + (tagged ? FixedArrayBase::kHeaderSize : 0), | 547 offset + (tagged ? FixedArrayBase::kHeaderSize : 0), |
555 Handle<Name>(), Type::Any(), rep}; | 548 Handle<Name>(), Type::Any(), rep}; |
556 return access; | 549 return access; |
557 } | 550 } |
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 } | 1449 } |
1457 CHECK_EQ(kMachineReps[i], rep.machine_type()); | 1450 CHECK_EQ(kMachineReps[i], rep.machine_type()); |
1458 } | 1451 } |
1459 } | 1452 } |
1460 | 1453 |
1461 | 1454 |
1462 TEST(LowerLoadElement_to_load) { | 1455 TEST(LowerLoadElement_to_load) { |
1463 TestingGraph t(Type::Any(), Type::Signed32()); | 1456 TestingGraph t(Type::Any(), Type::Signed32()); |
1464 | 1457 |
1465 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1458 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1466 ElementAccess access = {kNoBoundsCheck, kTaggedBase, | 1459 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1467 FixedArrayBase::kHeaderSize, Type::Any(), | 1460 Type::Any(), kMachineReps[i]}; |
1468 kMachineReps[i]}; | |
1469 | 1461 |
1470 Node* load = | 1462 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1471 t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, t.p1, | 1463 t.p1, t.start, t.start); |
1472 t.jsgraph.Int32Constant(1024), t.start, t.start); | |
1473 Node* use = t.Use(load, kMachineReps[i]); | 1464 Node* use = t.Use(load, kMachineReps[i]); |
1474 t.Return(use); | 1465 t.Return(use); |
1475 t.Lower(); | 1466 t.Lower(); |
1476 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1467 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1477 CHECK_EQ(t.p0, load->InputAt(0)); | 1468 CHECK_EQ(t.p0, load->InputAt(0)); |
1478 CheckElementAccessArithmetic(access, load); | 1469 CheckElementAccessArithmetic(access, load); |
1479 | 1470 |
1480 MachineType rep = OpParameter<MachineType>(load); | 1471 MachineType rep = OpParameter<MachineType>(load); |
1481 CHECK_EQ(kMachineReps[i], rep); | 1472 CHECK_EQ(kMachineReps[i], rep); |
1482 } | 1473 } |
1483 } | 1474 } |
1484 | 1475 |
1485 | 1476 |
1486 TEST(LowerStoreElement_to_store) { | 1477 TEST(LowerStoreElement_to_store) { |
1487 TestingGraph t(Type::Any(), Type::Signed32()); | 1478 TestingGraph t(Type::Any(), Type::Signed32()); |
1488 | 1479 |
1489 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1480 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1490 ElementAccess access = {kNoBoundsCheck, kTaggedBase, | 1481 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1491 FixedArrayBase::kHeaderSize, Type::Any(), | 1482 Type::Any(), kMachineReps[i]}; |
1492 kMachineReps[i]}; | |
1493 | 1483 |
1494 Node* val = t.ExampleWithOutput(kMachineReps[i]); | 1484 Node* val = t.ExampleWithOutput(kMachineReps[i]); |
1495 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, | 1485 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, |
1496 t.p1, t.jsgraph.Int32Constant(1024), val, | 1486 t.p1, val, t.start, t.start); |
1497 t.start, t.start); | |
1498 t.Effect(store); | 1487 t.Effect(store); |
1499 t.Lower(); | 1488 t.Lower(); |
1500 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1489 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1501 CHECK_EQ(val, store->InputAt(2)); | 1490 CHECK_EQ(val, store->InputAt(2)); |
1502 CheckElementAccessArithmetic(access, store); | 1491 CheckElementAccessArithmetic(access, store); |
1503 | 1492 |
1504 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); | 1493 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); |
1505 if (kMachineReps[i] & kRepTagged) { | 1494 if (kMachineReps[i] & kRepTagged) { |
1506 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); | 1495 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); |
1507 } | 1496 } |
1508 CHECK_EQ(kMachineReps[i], rep.machine_type()); | 1497 CHECK_EQ(kMachineReps[i], rep.machine_type()); |
1509 } | 1498 } |
1510 } | 1499 } |
1511 | 1500 |
1512 | 1501 |
1513 TEST(InsertChangeForLoadElementIndex) { | 1502 TEST(InsertChangeForLoadElementIndex) { |
1514 // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) => | 1503 // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) => |
1515 // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) | 1504 // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) |
1516 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); | 1505 TestingGraph t(Type::Any(), Type::Signed32()); |
1517 ElementAccess access = {kNoBoundsCheck, kTaggedBase, | 1506 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1518 FixedArrayBase::kHeaderSize, Type::Any(), | |
1519 kMachAnyTagged}; | 1507 kMachAnyTagged}; |
1520 | 1508 |
1521 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1509 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1522 t.p1, t.p2, t.start, t.start); | 1510 t.p1, t.start, t.start); |
1523 t.Return(load); | 1511 t.Return(load); |
1524 t.Lower(); | 1512 t.Lower(); |
1525 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1513 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1526 CHECK_EQ(t.p0, load->InputAt(0)); | 1514 CHECK_EQ(t.p0, load->InputAt(0)); |
1527 | 1515 |
1528 Node* index = CheckElementAccessArithmetic(access, load); | 1516 Node* index = CheckElementAccessArithmetic(access, load); |
1529 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index); | 1517 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index); |
1530 } | 1518 } |
1531 | 1519 |
1532 | 1520 |
1533 TEST(InsertChangeForStoreElementIndex) { | 1521 TEST(InsertChangeForStoreElementIndex) { |
1534 // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) => | 1522 // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) => |
1535 // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) | 1523 // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) |
1536 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); | 1524 TestingGraph t(Type::Any(), Type::Signed32()); |
1537 ElementAccess access = {kNoBoundsCheck, kTaggedBase, | 1525 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1538 FixedArrayBase::kHeaderSize, Type::Any(), | |
1539 kMachAnyTagged}; | 1526 kMachAnyTagged}; |
1540 | 1527 |
1541 Node* store = | 1528 Node* store = |
1542 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, t.p2, | 1529 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, |
1543 t.jsgraph.TrueConstant(), t.start, t.start); | 1530 t.jsgraph.TrueConstant(), t.start, t.start); |
1544 t.Effect(store); | 1531 t.Effect(store); |
1545 t.Lower(); | 1532 t.Lower(); |
1546 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1533 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1547 CHECK_EQ(t.p0, store->InputAt(0)); | 1534 CHECK_EQ(t.p0, store->InputAt(0)); |
1548 | 1535 |
1549 Node* index = CheckElementAccessArithmetic(access, store); | 1536 Node* index = CheckElementAccessArithmetic(access, store); |
1550 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index); | 1537 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index); |
1551 } | 1538 } |
1552 | 1539 |
1553 | 1540 |
1554 TEST(InsertChangeForLoadElement) { | 1541 TEST(InsertChangeForLoadElement) { |
1555 // TODO(titzer): test all load/store representation change insertions. | 1542 // TODO(titzer): test all load/store representation change insertions. |
1556 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); | 1543 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); |
1557 ElementAccess access = {kNoBoundsCheck, kTaggedBase, | 1544 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1558 FixedArrayBase::kHeaderSize, Type::Any(), | |
1559 kMachFloat64}; | 1545 kMachFloat64}; |
1560 | 1546 |
1561 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1547 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1562 t.p1, t.p1, t.start, t.start); | 1548 t.p1, t.start, t.start); |
1563 t.Return(load); | 1549 t.Return(load); |
1564 t.Lower(); | 1550 t.Lower(); |
1565 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1551 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1566 CHECK_EQ(t.p0, load->InputAt(0)); | 1552 CHECK_EQ(t.p0, load->InputAt(0)); |
1567 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); | 1553 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); |
1568 } | 1554 } |
1569 | 1555 |
1570 | 1556 |
1571 TEST(InsertChangeForLoadField) { | 1557 TEST(InsertChangeForLoadField) { |
1572 // TODO(titzer): test all load/store representation change insertions. | 1558 // TODO(titzer): test all load/store representation change insertions. |
1573 TestingGraph t(Type::Any(), Type::Signed32()); | 1559 TestingGraph t(Type::Any(), Type::Signed32()); |
1574 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1560 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1575 Handle<Name>::null(), Type::Any(), kMachFloat64}; | 1561 Handle<Name>::null(), Type::Any(), kMachFloat64}; |
1576 | 1562 |
1577 Node* load = | 1563 Node* load = |
1578 t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start); | 1564 t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start); |
1579 t.Return(load); | 1565 t.Return(load); |
1580 t.Lower(); | 1566 t.Lower(); |
1581 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1567 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1582 CHECK_EQ(t.p0, load->InputAt(0)); | 1568 CHECK_EQ(t.p0, load->InputAt(0)); |
1583 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); | 1569 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); |
1584 } | 1570 } |
1585 | 1571 |
1586 | 1572 |
1587 TEST(InsertChangeForStoreElement) { | 1573 TEST(InsertChangeForStoreElement) { |
1588 // TODO(titzer): test all load/store representation change insertions. | 1574 // TODO(titzer): test all load/store representation change insertions. |
1589 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); | 1575 TestingGraph t(Type::Any(), Type::Signed32()); |
1590 ElementAccess access = {kNoBoundsCheck, kTaggedBase, | 1576 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1591 FixedArrayBase::kHeaderSize, Type::Any(), | |
1592 kMachFloat64}; | 1577 kMachFloat64}; |
1593 | 1578 |
1594 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, | 1579 Node* store = |
1595 t.jsgraph.Int32Constant(0), t.p2, t.p1, | 1580 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, |
1596 t.start, t.start); | 1581 t.jsgraph.Int32Constant(0), t.p1, t.start, t.start); |
1597 t.Effect(store); | 1582 t.Effect(store); |
1598 t.Lower(); | 1583 t.Lower(); |
1599 | 1584 |
1600 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1585 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1601 CHECK_EQ(t.p0, store->InputAt(0)); | 1586 CHECK_EQ(t.p0, store->InputAt(0)); |
1602 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); | 1587 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); |
1603 } | 1588 } |
1604 | 1589 |
1605 | 1590 |
1606 TEST(InsertChangeForStoreField) { | 1591 TEST(InsertChangeForStoreField) { |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2045 Bounds phi_bounds = Bounds::Either(Bounds(d.arg1), Bounds(d.arg2), z); | 2030 Bounds phi_bounds = Bounds::Either(Bounds(d.arg1), Bounds(d.arg2), z); |
2046 NodeProperties::SetBounds(phi, phi_bounds); | 2031 NodeProperties::SetBounds(phi, phi_bounds); |
2047 | 2032 |
2048 Node* use = t.Use(phi, d.use); | 2033 Node* use = t.Use(phi, d.use); |
2049 t.Return(use); | 2034 t.Return(use); |
2050 t.Lower(); | 2035 t.Lower(); |
2051 | 2036 |
2052 CHECK_EQ(d.expected, OpParameter<MachineType>(phi)); | 2037 CHECK_EQ(d.expected, OpParameter<MachineType>(phi)); |
2053 } | 2038 } |
2054 } | 2039 } |
OLD | NEW |