| Index: src/interpreter/bytecode-register-optimizer.cc
|
| diff --git a/src/interpreter/bytecode-register-optimizer.cc b/src/interpreter/bytecode-register-optimizer.cc
|
| index 12be57b48c2964d53bf8b9127d5c4ea562e2361f..d28f215de856634a36816853af68d925e4b25d67 100644
|
| --- a/src/interpreter/bytecode-register-optimizer.cc
|
| +++ b/src/interpreter/bytecode-register-optimizer.cc
|
| @@ -174,7 +174,6 @@
|
| int parameter_count, BytecodePipelineStage* next_stage)
|
| : accumulator_(Register::virtual_accumulator()),
|
| temporary_base_(register_allocator->allocation_base()),
|
| - max_register_index_(register_allocator->allocation_base() - 1),
|
| register_info_table_(zone),
|
| equivalence_id_(0),
|
| next_stage_(next_stage),
|
| @@ -209,17 +208,15 @@
|
|
|
| // override
|
| Handle<BytecodeArray> BytecodeRegisterOptimizer::ToBytecodeArray(
|
| - Isolate* isolate, int register_count, int parameter_count,
|
| + Isolate* isolate, int fixed_register_count, int parameter_count,
|
| Handle<FixedArray> handler_table) {
|
| FlushState();
|
| - return next_stage_->ToBytecodeArray(isolate, max_register_index_ + 1,
|
| + return next_stage_->ToBytecodeArray(isolate, fixed_register_count,
|
| parameter_count, handler_table);
|
| }
|
|
|
| // override
|
| void BytecodeRegisterOptimizer::Write(BytecodeNode* node) {
|
| - // Jumps are handled by WriteJump.
|
| - DCHECK(!Bytecodes::IsJump(node->bytecode()));
|
| //
|
| // Transfers with observable registers as the destination will be
|
| // immediately materialized so the source position information will
|
| @@ -248,16 +245,18 @@
|
| break;
|
| }
|
|
|
| - if (node->bytecode() == Bytecode::kDebugger ||
|
| + if (Bytecodes::IsJump(node->bytecode()) ||
|
| + node->bytecode() == Bytecode::kDebugger ||
|
| node->bytecode() == Bytecode::kSuspendGenerator) {
|
| // All state must be flushed before emitting
|
| + // - a jump (due to how bytecode offsets for jumps are evaluated),
|
| // - a call to the debugger (as it can manipulate locals and parameters),
|
| // - a generator suspend (as this involves saving all registers).
|
| FlushState();
|
| }
|
|
|
| PrepareOperands(node);
|
| - next_stage_->Write(node);
|
| + WriteToNextStage(node);
|
| }
|
|
|
| // override
|
| @@ -307,29 +306,38 @@
|
| flush_required_ = false;
|
| }
|
|
|
| +void BytecodeRegisterOptimizer::WriteToNextStage(BytecodeNode* node) const {
|
| + next_stage_->Write(node);
|
| +}
|
| +
|
| +void BytecodeRegisterOptimizer::WriteToNextStage(
|
| + BytecodeNode* node, const BytecodeSourceInfo& source_info) const {
|
| + if (source_info.is_valid()) {
|
| + node->source_info().Clone(source_info);
|
| + }
|
| + next_stage_->Write(node);
|
| +}
|
| +
|
| void BytecodeRegisterOptimizer::OutputRegisterTransfer(
|
| RegisterInfo* input_info, RegisterInfo* output_info,
|
| - BytecodeSourceInfo* source_info) {
|
| + const BytecodeSourceInfo& source_info) {
|
| Register input = input_info->register_value();
|
| Register output = output_info->register_value();
|
| DCHECK_NE(input.index(), output.index());
|
|
|
| if (input == accumulator_) {
|
| uint32_t operand = static_cast<uint32_t>(output.ToOperand());
|
| - BytecodeNode node(Bytecode::kStar, operand, source_info);
|
| - next_stage_->Write(&node);
|
| + BytecodeNode node(Bytecode::kStar, operand);
|
| + WriteToNextStage(&node, source_info);
|
| } else if (output == accumulator_) {
|
| uint32_t operand = static_cast<uint32_t>(input.ToOperand());
|
| - BytecodeNode node(Bytecode::kLdar, operand, source_info);
|
| - next_stage_->Write(&node);
|
| + BytecodeNode node(Bytecode::kLdar, operand);
|
| + WriteToNextStage(&node, source_info);
|
| } else {
|
| uint32_t operand0 = static_cast<uint32_t>(input.ToOperand());
|
| uint32_t operand1 = static_cast<uint32_t>(output.ToOperand());
|
| - BytecodeNode node(Bytecode::kMov, operand0, operand1, source_info);
|
| - next_stage_->Write(&node);
|
| - }
|
| - if (output != accumulator_) {
|
| - max_register_index_ = std::max(max_register_index_, output.index());
|
| + BytecodeNode node(Bytecode::kMov, operand0, operand1);
|
| + WriteToNextStage(&node, source_info);
|
| }
|
| output_info->set_materialized(true);
|
| }
|
| @@ -381,7 +389,7 @@
|
|
|
| void BytecodeRegisterOptimizer::RegisterTransfer(
|
| RegisterInfo* input_info, RegisterInfo* output_info,
|
| - BytecodeSourceInfo* source_info) {
|
| + const BytecodeSourceInfo& source_info) {
|
| // Materialize an alternate in the equivalence set that
|
| // |output_info| is leaving.
|
| if (output_info->materialized()) {
|
| @@ -400,41 +408,42 @@
|
| output_info->set_materialized(false);
|
| RegisterInfo* materialized_info = input_info->GetMaterializedEquivalent();
|
| OutputRegisterTransfer(materialized_info, output_info, source_info);
|
| - } else if (source_info->is_valid()) {
|
| + } else if (source_info.is_valid()) {
|
| // Emit a placeholder nop to maintain source position info.
|
| EmitNopForSourceInfo(source_info);
|
| }
|
| }
|
|
|
| void BytecodeRegisterOptimizer::EmitNopForSourceInfo(
|
| - BytecodeSourceInfo* source_info) const {
|
| - DCHECK(source_info->is_valid());
|
| - BytecodeNode nop(Bytecode::kNop, source_info);
|
| - next_stage_->Write(&nop);
|
| -}
|
| -
|
| -void BytecodeRegisterOptimizer::DoLdar(BytecodeNode* node) {
|
| + const BytecodeSourceInfo& source_info) const {
|
| + DCHECK(source_info.is_valid());
|
| + BytecodeNode nop(Bytecode::kNop);
|
| + nop.source_info().Clone(source_info);
|
| + WriteToNextStage(&nop);
|
| +}
|
| +
|
| +void BytecodeRegisterOptimizer::DoLdar(const BytecodeNode* const node) {
|
| Register input = GetRegisterInputOperand(
|
| 0, node->bytecode(), node->operands(), node->operand_count());
|
| RegisterInfo* input_info = GetRegisterInfo(input);
|
| - RegisterTransfer(input_info, accumulator_info_, node->source_info_ptr());
|
| -}
|
| -
|
| -void BytecodeRegisterOptimizer::DoMov(BytecodeNode* node) {
|
| + RegisterTransfer(input_info, accumulator_info_, node->source_info());
|
| +}
|
| +
|
| +void BytecodeRegisterOptimizer::DoMov(const BytecodeNode* const node) {
|
| Register input = GetRegisterInputOperand(
|
| 0, node->bytecode(), node->operands(), node->operand_count());
|
| RegisterInfo* input_info = GetRegisterInfo(input);
|
| Register output = GetRegisterOutputOperand(
|
| 1, node->bytecode(), node->operands(), node->operand_count());
|
| RegisterInfo* output_info = GetOrCreateRegisterInfo(output);
|
| - RegisterTransfer(input_info, output_info, node->source_info_ptr());
|
| -}
|
| -
|
| -void BytecodeRegisterOptimizer::DoStar(BytecodeNode* node) {
|
| + RegisterTransfer(input_info, output_info, node->source_info());
|
| +}
|
| +
|
| +void BytecodeRegisterOptimizer::DoStar(const BytecodeNode* const node) {
|
| Register output = GetRegisterOutputOperand(
|
| 0, node->bytecode(), node->operands(), node->operand_count());
|
| RegisterInfo* output_info = GetOrCreateRegisterInfo(output);
|
| - RegisterTransfer(accumulator_info_, output_info, node->source_info_ptr());
|
| + RegisterTransfer(accumulator_info_, output_info, node->source_info());
|
| }
|
|
|
| void BytecodeRegisterOptimizer::PrepareRegisterOutputOperand(
|
| @@ -442,8 +451,6 @@
|
| if (reg_info->materialized()) {
|
| CreateMaterializedEquivalent(reg_info);
|
| }
|
| - max_register_index_ =
|
| - std::max(max_register_index_, reg_info->register_value().index());
|
| reg_info->MoveToNewEquivalenceSet(NextEquivalenceId(), true);
|
| }
|
|
|
| @@ -474,8 +481,8 @@
|
| void BytecodeRegisterOptimizer::PrepareRegisterInputOperand(
|
| BytecodeNode* const node, Register reg, int operand_index) {
|
| Register equivalent = GetEquivalentRegisterForInputOperand(reg);
|
| - node->UpdateOperand(operand_index,
|
| - static_cast<uint32_t>(equivalent.ToOperand()));
|
| + node->operands()[operand_index] =
|
| + static_cast<uint32_t>(equivalent.ToOperand());
|
| }
|
|
|
| void BytecodeRegisterOptimizer::PrepareRegisterRangeInputOperand(Register start,
|
|
|