| Index: test/unittests/interpreter/bytecode-register-optimizer-unittest.cc
|
| diff --git a/test/unittests/interpreter/bytecode-register-optimizer-unittest.cc b/test/unittests/interpreter/bytecode-register-optimizer-unittest.cc
|
| index 072a3121d37cd7b711d78e171229e4e056965c43..ae7c159563cd9eb9fdc3845aee65a2219d7326ae 100644
|
| --- a/test/unittests/interpreter/bytecode-register-optimizer-unittest.cc
|
| +++ b/test/unittests/interpreter/bytecode-register-optimizer-unittest.cc
|
| @@ -22,10 +22,10 @@ class BytecodeRegisterOptimizerTest : public BytecodePipelineStage,
|
| ~BytecodeRegisterOptimizerTest() override { delete register_allocator_; }
|
|
|
| void Initialize(int number_of_parameters, int number_of_locals) {
|
| - register_allocator_ =
|
| - new TemporaryRegisterAllocator(zone(), number_of_locals);
|
| - register_optimizer_ = new (zone()) BytecodeRegisterOptimizer(
|
| - zone(), register_allocator_, number_of_parameters, this);
|
| + register_allocator_ = new BytecodeRegisterAllocator(number_of_locals);
|
| + register_optimizer_ = new (zone())
|
| + BytecodeRegisterOptimizer(zone(), register_allocator_, number_of_locals,
|
| + number_of_parameters, this);
|
| }
|
|
|
| void Write(BytecodeNode* node) override { output_.push_back(*node); }
|
| @@ -40,15 +40,13 @@ class BytecodeRegisterOptimizerTest : public BytecodePipelineStage,
|
| return Handle<BytecodeArray>();
|
| }
|
|
|
| - TemporaryRegisterAllocator* allocator() { return register_allocator_; }
|
| + BytecodeRegisterAllocator* allocator() { return register_allocator_; }
|
| BytecodeRegisterOptimizer* optimizer() { return register_optimizer_; }
|
|
|
| - Register NewTemporary() {
|
| - return Register(allocator()->BorrowTemporaryRegister());
|
| - }
|
| + Register NewTemporary() { return allocator()->NewRegister(); }
|
|
|
| - void KillTemporary(Register reg) {
|
| - allocator()->ReturnTemporaryRegister(reg.index());
|
| + void ReleaseTemporaries(Register reg) {
|
| + allocator()->ReleaseRegisters(reg.index());
|
| }
|
|
|
| size_t write_count() const { return output_.size(); }
|
| @@ -56,7 +54,7 @@ class BytecodeRegisterOptimizerTest : public BytecodePipelineStage,
|
| const std::vector<BytecodeNode>* output() { return &output_; }
|
|
|
| private:
|
| - TemporaryRegisterAllocator* register_allocator_;
|
| + BytecodeRegisterAllocator* register_allocator_;
|
| BytecodeRegisterOptimizer* register_optimizer_;
|
|
|
| std::vector<BytecodeNode> output_;
|
| @@ -130,7 +128,7 @@ TEST_F(BytecodeRegisterOptimizerTest, TemporaryNotEmitted) {
|
| BytecodeNode node1(Bytecode::kStar, NewTemporary().ToOperand());
|
| optimizer()->Write(&node1);
|
| CHECK_EQ(write_count(), 0);
|
| - KillTemporary(temp);
|
| + ReleaseTemporaries(temp);
|
| CHECK_EQ(write_count(), 0);
|
| BytecodeNode node2(Bytecode::kReturn);
|
| optimizer()->Write(&node2);
|
| @@ -140,6 +138,61 @@ TEST_F(BytecodeRegisterOptimizerTest, TemporaryNotEmitted) {
|
| CHECK_EQ(output()->at(1).bytecode(), Bytecode::kReturn);
|
| }
|
|
|
| +TEST_F(BytecodeRegisterOptimizerTest, ReleasedRegisterUsed) {
|
| + Initialize(3, 1);
|
| + BytecodeNode node0(Bytecode::kLdaSmi, 3);
|
| + optimizer()->Write(&node0);
|
| + CHECK_EQ(write_count(), 1);
|
| + Register temp0 = NewTemporary();
|
| + Register temp1 = NewTemporary();
|
| + BytecodeNode node1(Bytecode::kStar, temp1.ToOperand());
|
| + optimizer()->Write(&node1);
|
| + CHECK_EQ(write_count(), 1);
|
| + BytecodeNode node2(Bytecode::kLdaSmi, 1);
|
| + optimizer()->Write(&node2);
|
| + CHECK_EQ(write_count(), 3);
|
| + BytecodeNode node3(Bytecode::kMov, temp1.ToOperand(), temp0.ToOperand());
|
| + optimizer()->Write(&node3);
|
| + CHECK_EQ(write_count(), 3);
|
| + ReleaseTemporaries(temp1);
|
| + CHECK_EQ(write_count(), 3);
|
| + BytecodeNode node4(Bytecode::kLdar, temp0.ToOperand());
|
| + optimizer()->Write(&node4);
|
| + CHECK_EQ(write_count(), 3);
|
| + BytecodeNode node5(Bytecode::kReturn);
|
| + optimizer()->Write(&node5);
|
| + CHECK_EQ(write_count(), 5);
|
| + CHECK_EQ(output()->at(3).bytecode(), Bytecode::kLdar);
|
| + CHECK_EQ(output()->at(3).operand(0), temp1.ToOperand());
|
| + CHECK_EQ(output()->at(4).bytecode(), Bytecode::kReturn);
|
| +}
|
| +
|
| +TEST_F(BytecodeRegisterOptimizerTest, ReleasedRegisterNotFlushed) {
|
| + Initialize(3, 1);
|
| + BytecodeNode node0(Bytecode::kLdaSmi, 3);
|
| + optimizer()->Write(&node0);
|
| + CHECK_EQ(write_count(), 1);
|
| + Register temp0 = NewTemporary();
|
| + Register temp1 = NewTemporary();
|
| + BytecodeNode node1(Bytecode::kStar, temp0.ToOperand());
|
| + optimizer()->Write(&node1);
|
| + CHECK_EQ(write_count(), 1);
|
| + BytecodeNode node2(Bytecode::kStar, temp1.ToOperand());
|
| + optimizer()->Write(&node2);
|
| + CHECK_EQ(write_count(), 1);
|
| + ReleaseTemporaries(temp1);
|
| + BytecodeLabel label;
|
| + BytecodeNode jump(Bytecode::kJump, 0, nullptr);
|
| + optimizer()->WriteJump(&jump, &label);
|
| + BytecodeNode node3(Bytecode::kReturn);
|
| + optimizer()->Write(&node3);
|
| + CHECK_EQ(write_count(), 4);
|
| + CHECK_EQ(output()->at(1).bytecode(), Bytecode::kStar);
|
| + CHECK_EQ(output()->at(1).operand(0), temp0.ToOperand());
|
| + CHECK_EQ(output()->at(2).bytecode(), Bytecode::kJump);
|
| + CHECK_EQ(output()->at(3).bytecode(), Bytecode::kReturn);
|
| +}
|
| +
|
| TEST_F(BytecodeRegisterOptimizerTest, StoresToLocalsImmediate) {
|
| Initialize(3, 1);
|
| Register parameter = Register::FromParameterIndex(1, 3);
|
|
|