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