| 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 |