| Index: src/compiler/instruction-selector.cc
|
| diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
|
| index d8409a3f89c8250155d645b73b189ece198083d4..e8a3153f7ff90350d83b7ae446af39d7c958bb79 100644
|
| --- a/src/compiler/instruction-selector.cc
|
| +++ b/src/compiler/instruction-selector.cc
|
| @@ -41,11 +41,12 @@ InstructionSelector::InstructionSelector(
|
| virtual_register_rename_(zone),
|
| scheduler_(nullptr),
|
| enable_scheduling_(enable_scheduling),
|
| - frame_(frame) {
|
| + frame_(frame),
|
| + instruction_selection_failed_(false) {
|
| instructions_.reserve(node_count);
|
| }
|
|
|
| -void InstructionSelector::SelectInstructions() {
|
| +bool InstructionSelector::SelectInstructions() {
|
| // Mark the inputs of all phis in loop headers as used.
|
| BasicBlockVector* blocks = schedule()->rpo_order();
|
| for (auto const block : *blocks) {
|
| @@ -64,6 +65,7 @@ void InstructionSelector::SelectInstructions() {
|
| // Visit each basic block in post order.
|
| for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) {
|
| VisitBlock(*i);
|
| + if (instruction_selection_failed()) return false;
|
| }
|
|
|
| // Schedule the selected instructions.
|
| @@ -90,6 +92,7 @@ void InstructionSelector::SelectInstructions() {
|
| #if DEBUG
|
| sequence()->ValidateSSA();
|
| #endif
|
| + return true;
|
| }
|
|
|
| void InstructionSelector::StartBlock(RpoNumber rpo) {
|
| @@ -208,6 +211,13 @@ Instruction* InstructionSelector::Emit(
|
| InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
|
| size_t input_count, InstructionOperand* inputs, size_t temp_count,
|
| InstructionOperand* temps) {
|
| + if (output_count >= Instruction::kMaxOutputCount ||
|
| + input_count >= Instruction::kMaxInputCount ||
|
| + temp_count >= Instruction::kMaxTempCount) {
|
| + set_instruction_selection_failed();
|
| + return nullptr;
|
| + }
|
| +
|
| Instruction* instr =
|
| Instruction::New(instruction_zone(), opcode, output_count, outputs,
|
| input_count, inputs, temp_count, temps);
|
| @@ -767,7 +777,6 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
|
| }
|
| }
|
|
|
| -
|
| void InstructionSelector::VisitBlock(BasicBlock* block) {
|
| DCHECK(!current_block_);
|
| current_block_ = block;
|
| @@ -804,6 +813,7 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
|
| // up".
|
| size_t current_node_end = instructions_.size();
|
| VisitNode(node);
|
| + if (instruction_selection_failed()) return;
|
| std::reverse(instructions_.begin() + current_node_end, instructions_.end());
|
| if (instructions_.size() == current_node_end) continue;
|
| // Mark source position on first instruction emitted.
|
| @@ -1843,9 +1853,11 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
|
| // Emit the call instruction.
|
| size_t const output_count = buffer.outputs.size();
|
| auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
|
| - Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
|
| - &buffer.instruction_args.front())
|
| - ->MarkAsCall();
|
| + Instruction* call_instr =
|
| + Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
|
| + &buffer.instruction_args.front());
|
| + if (instruction_selection_failed()) return;
|
| + call_instr->MarkAsCall();
|
| }
|
|
|
|
|
| @@ -1951,9 +1963,11 @@ void InstructionSelector::VisitTailCall(Node* node) {
|
| // Emit the call instruction.
|
| size_t output_count = buffer.outputs.size();
|
| auto* outputs = &buffer.outputs.front();
|
| - Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
|
| - &buffer.instruction_args.front())
|
| - ->MarkAsCall();
|
| + Instruction* call_instr =
|
| + Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
|
| + &buffer.instruction_args.front());
|
| + if (instruction_selection_failed()) return;
|
| + call_instr->MarkAsCall();
|
| Emit(kArchRet, 0, nullptr, output_count, outputs);
|
| }
|
| }
|
|
|