| 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 "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
| 6 | 6 |
| 7 #include "src/compiler/graph-inl.h" | 7 #include "src/compiler/graph-inl.h" |
| 8 #include "src/flags.h" | 8 #include "src/flags.h" |
| 9 #include "test/unittests/compiler/compiler-test-utils.h" | 9 #include "test/unittests/compiler/compiler-test-utils.h" |
| 10 | 10 |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 | 368 |
| 369 BailoutId bailout_id_before(42); | 369 BailoutId bailout_id_before(42); |
| 370 | 370 |
| 371 // Some arguments for the call node. | 371 // Some arguments for the call node. |
| 372 Node* function_node = m.Parameter(0); | 372 Node* function_node = m.Parameter(0); |
| 373 Node* receiver = m.Parameter(1); | 373 Node* receiver = m.Parameter(1); |
| 374 Node* context = m.Int32Constant(1); // Context is ignored. | 374 Node* context = m.Int32Constant(1); // Context is ignored. |
| 375 | 375 |
| 376 // Build frame state for the state before the call. | 376 // Build frame state for the state before the call. |
| 377 Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(43)); | 377 Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(43)); |
| 378 Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44)); | 378 Node* locals = m.NewNode(m.common()->StateValues(1), m.Float64Constant(0.5)); |
| 379 Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45)); | 379 Node* stack = m.NewNode(m.common()->StateValues(1), m.UndefinedConstant()); |
| 380 | 380 |
| 381 Node* context_sentinel = m.Int32Constant(0); | 381 Node* context_sentinel = m.Int32Constant(0); |
| 382 Node* frame_state_before = m.NewNode( | 382 Node* frame_state_before = m.NewNode( |
| 383 m.common()->FrameState(JS_FRAME, bailout_id_before, | 383 m.common()->FrameState(JS_FRAME, bailout_id_before, |
| 384 OutputFrameStateCombine::Push()), | 384 OutputFrameStateCombine::Push()), |
| 385 parameters, locals, stack, context_sentinel, m.UndefinedConstant()); | 385 parameters, locals, stack, context_sentinel, m.UndefinedConstant()); |
| 386 | 386 |
| 387 // Build the call. | 387 // Build the call. |
| 388 Node* call = m.CallFunctionStub0(function_node, receiver, context, | 388 Node* call = m.CallFunctionStub0(function_node, receiver, context, |
| 389 frame_state_before, CALL_AS_METHOD); | 389 frame_state_before, CALL_AS_METHOD); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 418 int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1)); | 418 int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1)); |
| 419 FrameStateDescriptor* desc_before = | 419 FrameStateDescriptor* desc_before = |
| 420 s.GetFrameStateDescriptor(deopt_id_before); | 420 s.GetFrameStateDescriptor(deopt_id_before); |
| 421 EXPECT_EQ(bailout_id_before, desc_before->bailout_id()); | 421 EXPECT_EQ(bailout_id_before, desc_before->bailout_id()); |
| 422 EXPECT_EQ(OutputFrameStateCombine::kPushOutput, | 422 EXPECT_EQ(OutputFrameStateCombine::kPushOutput, |
| 423 desc_before->state_combine().kind()); | 423 desc_before->state_combine().kind()); |
| 424 EXPECT_EQ(1u, desc_before->parameters_count()); | 424 EXPECT_EQ(1u, desc_before->parameters_count()); |
| 425 EXPECT_EQ(1u, desc_before->locals_count()); | 425 EXPECT_EQ(1u, desc_before->locals_count()); |
| 426 EXPECT_EQ(1u, desc_before->stack_count()); | 426 EXPECT_EQ(1u, desc_before->stack_count()); |
| 427 EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(2))); | 427 EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(2))); |
| 428 EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(3))); | 428 EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(3))); // This should be a context. |
| 429 EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(4))); | 429 // We inserted 0 here. |
| 430 EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(5))); | 430 EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(4))); |
| 431 EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(5))->IsUndefined()); |
| 432 EXPECT_EQ(kMachInt32, desc_before->GetType(0)); |
| 433 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(1)); // context is always |
| 434 // tagged/any. |
| 435 EXPECT_EQ(kMachFloat64, desc_before->GetType(2)); |
| 436 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(3)); |
| 431 | 437 |
| 432 // Function. | 438 // Function. |
| 433 EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(6))); | 439 EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(6))); |
| 434 // Context. | 440 // Context. |
| 435 EXPECT_EQ(s.ToVreg(context), s.ToVreg(call_instr->InputAt(7))); | 441 EXPECT_EQ(s.ToVreg(context), s.ToVreg(call_instr->InputAt(7))); |
| 436 | 442 |
| 437 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); | 443 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); |
| 438 | 444 |
| 439 EXPECT_EQ(index, s.size()); | 445 EXPECT_EQ(index, s.size()); |
| 440 } | 446 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 458 Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(64)); | 464 Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(64)); |
| 459 Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(65)); | 465 Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(65)); |
| 460 Node* frame_state_parent = | 466 Node* frame_state_parent = |
| 461 m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_parent, | 467 m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_parent, |
| 462 OutputFrameStateCombine::Ignore()), | 468 OutputFrameStateCombine::Ignore()), |
| 463 parameters, locals, stack, context, m.UndefinedConstant()); | 469 parameters, locals, stack, context, m.UndefinedConstant()); |
| 464 | 470 |
| 465 Node* context2 = m.Int32Constant(46); | 471 Node* context2 = m.Int32Constant(46); |
| 466 Node* parameters2 = | 472 Node* parameters2 = |
| 467 m.NewNode(m.common()->StateValues(1), m.Int32Constant(43)); | 473 m.NewNode(m.common()->StateValues(1), m.Int32Constant(43)); |
| 468 Node* locals2 = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44)); | 474 Node* locals2 = |
| 469 Node* stack2 = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45)); | 475 m.NewNode(m.common()->StateValues(1), m.Float64Constant(0.25)); |
| 476 Node* stack2 = m.NewNode(m.common()->StateValues(2), m.Int32Constant(44), |
| 477 m.Int32Constant(45)); |
| 470 Node* frame_state_before = | 478 Node* frame_state_before = |
| 471 m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_before, | 479 m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_before, |
| 472 OutputFrameStateCombine::Push()), | 480 OutputFrameStateCombine::Push()), |
| 473 parameters2, locals2, stack2, context2, frame_state_parent); | 481 parameters2, locals2, stack2, context2, frame_state_parent); |
| 474 | 482 |
| 475 // Build the call. | 483 // Build the call. |
| 476 Node* call = m.CallFunctionStub0(function_node, receiver, context2, | 484 Node* call = m.CallFunctionStub0(function_node, receiver, context2, |
| 477 frame_state_before, CALL_AS_METHOD); | 485 frame_state_before, CALL_AS_METHOD); |
| 478 | 486 |
| 479 m.Return(call); | 487 m.Return(call); |
| 480 | 488 |
| 481 Stream s = m.Build(kAllExceptNopInstructions); | 489 Stream s = m.Build(kAllExceptNopInstructions); |
| 482 | 490 |
| 483 // Skip until kArchCallJSFunction. | 491 // Skip until kArchCallJSFunction. |
| 484 size_t index = 0; | 492 size_t index = 0; |
| 485 for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject; | 493 for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject; |
| 486 index++) { | 494 index++) { |
| 487 } | 495 } |
| 488 // Now we should have three instructions: call, return. | 496 // Now we should have three instructions: call, return. |
| 489 EXPECT_EQ(index + 2, s.size()); | 497 EXPECT_EQ(index + 2, s.size()); |
| 490 | 498 |
| 491 // Check the call instruction | 499 // Check the call instruction |
| 492 const Instruction* call_instr = s[index++]; | 500 const Instruction* call_instr = s[index++]; |
| 493 EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode()); | 501 EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode()); |
| 494 size_t num_operands = | 502 size_t num_operands = |
| 495 1 + // Code object. | 503 1 + // Code object. |
| 496 1 + // Frame state deopt id | 504 1 + // Frame state deopt id |
| 497 4 + // One input for each value in frame state + context. | 505 5 + // One input for each value in frame state + context. |
| 498 4 + // One input for each value in the parent frame state + context. | 506 4 + // One input for each value in the parent frame state + context. |
| 499 1 + // Function. | 507 1 + // Function. |
| 500 1; // Context. | 508 1; // Context. |
| 501 EXPECT_EQ(num_operands, call_instr->InputCount()); | 509 EXPECT_EQ(num_operands, call_instr->InputCount()); |
| 502 // Code object. | 510 // Code object. |
| 503 EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate()); | 511 EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate()); |
| 504 | 512 |
| 505 // Deoptimization id. | 513 // Deoptimization id. |
| 506 int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1)); | 514 int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1)); |
| 507 FrameStateDescriptor* desc_before = | 515 FrameStateDescriptor* desc_before = |
| 508 s.GetFrameStateDescriptor(deopt_id_before); | 516 s.GetFrameStateDescriptor(deopt_id_before); |
| 517 FrameStateDescriptor* desc_before_outer = desc_before->outer_state(); |
| 509 EXPECT_EQ(bailout_id_before, desc_before->bailout_id()); | 518 EXPECT_EQ(bailout_id_before, desc_before->bailout_id()); |
| 519 EXPECT_EQ(1u, desc_before_outer->parameters_count()); |
| 520 EXPECT_EQ(1u, desc_before_outer->locals_count()); |
| 521 EXPECT_EQ(1u, desc_before_outer->stack_count()); |
| 522 // Values from parent environment. |
| 523 EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(2))); |
| 524 EXPECT_EQ(kMachInt32, desc_before_outer->GetType(0)); |
| 525 // Context: |
| 526 EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(3))); |
| 527 EXPECT_EQ(kMachAnyTagged, desc_before_outer->GetType(1)); |
| 528 EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(4))); |
| 529 EXPECT_EQ(kMachInt32, desc_before_outer->GetType(2)); |
| 530 EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(5))); |
| 531 EXPECT_EQ(kMachInt32, desc_before_outer->GetType(3)); |
| 532 // Values from the nested frame. |
| 510 EXPECT_EQ(1u, desc_before->parameters_count()); | 533 EXPECT_EQ(1u, desc_before->parameters_count()); |
| 511 EXPECT_EQ(1u, desc_before->locals_count()); | 534 EXPECT_EQ(1u, desc_before->locals_count()); |
| 512 EXPECT_EQ(1u, desc_before->stack_count()); | 535 EXPECT_EQ(2u, desc_before->stack_count()); |
| 513 EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(2))); | |
| 514 // Context: | |
| 515 EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(3))); | |
| 516 EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(4))); | |
| 517 EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(5))); | |
| 518 // Values from parent environment should follow. | |
| 519 EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(6))); | 536 EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(6))); |
| 537 EXPECT_EQ(kMachInt32, desc_before->GetType(0)); |
| 520 EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(7))); | 538 EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(7))); |
| 521 EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(8))); | 539 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(1)); |
| 522 EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(9))); | 540 EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(8))); |
| 541 EXPECT_EQ(kMachFloat64, desc_before->GetType(2)); |
| 542 EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(9))); |
| 543 EXPECT_EQ(kMachInt32, desc_before->GetType(3)); |
| 544 EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(10))); |
| 545 EXPECT_EQ(kMachInt32, desc_before->GetType(4)); |
| 523 | 546 |
| 524 // Function. | 547 // Function. |
| 525 EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(10))); | 548 EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(11))); |
| 526 // Context. | 549 // Context. |
| 527 EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(11))); | 550 EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(12))); |
| 528 // Continuation. | 551 // Continuation. |
| 529 | 552 |
| 530 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); | 553 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); |
| 531 EXPECT_EQ(index, s.size()); | 554 EXPECT_EQ(index, s.size()); |
| 532 } | 555 } |
| 533 | 556 |
| 534 } // namespace compiler | 557 } // namespace compiler |
| 535 } // namespace internal | 558 } // namespace internal |
| 536 } // namespace v8 | 559 } // namespace v8 |
| OLD | NEW |