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 |