Commit 5247b267 authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Abort compilation when the max deoptimization table size is exceeded.

BUG=chromium:607115
LOG=n

Review-Url: https://codereview.chromium.org/1928903002
Cr-Commit-Position: refs/heads/master@{#35855}
parent 53457279
......@@ -450,7 +450,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
ArmOperandConverter i(this, instr);
__ MaybeCheckConstPool();
......@@ -584,7 +585,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1272,6 +1275,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
ASSEMBLE_ATOMIC_LOAD_INTEGER(ldr);
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
......@@ -1332,16 +1336,17 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
}
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
// TODO(turbofan): We should be able to generate better code by sharing the
// actual final call site and just bl'ing to it here, similar to what we do
// in the lithium backend.
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
__ CheckConstPool(false, false);
return kSuccess;
}
void CodeGenerator::FinishFrame(Frame* frame) {
......
......@@ -537,7 +537,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
Arm64OperandConverter i(this, instr);
InstructionCode opcode = instr->opcode();
ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
......@@ -689,7 +690,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1429,6 +1432,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ Dmb(InnerShareable, BarrierAll);
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
......@@ -1531,12 +1535,13 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
__ EndBlockPools();
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
return kSuccess;
}
void CodeGenerator::FinishFrame(Frame* frame) {
......
......@@ -156,12 +156,14 @@ Handle<Code> CodeGenerator::GenerateCode() {
}
}
CodeGenResult result;
if (FLAG_enable_embedded_constant_pool && !block->needs_frame()) {
ConstantPoolUnavailableScope constant_pool_unavailable(masm());
AssembleBlock(block);
result = AssembleBlock(block);
} else {
AssembleBlock(block);
result = AssembleBlock(block);
}
if (result != kSuccess) return Handle<Code>();
}
}
......@@ -304,15 +306,18 @@ bool CodeGenerator::IsMaterializableFromRoot(
return false;
}
void CodeGenerator::AssembleBlock(const InstructionBlock* block) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleBlock(
const InstructionBlock* block) {
for (int i = block->code_start(); i < block->code_end(); ++i) {
Instruction* instr = code()->InstructionAt(i);
AssembleInstruction(instr, block);
CodeGenResult result = AssembleInstruction(instr, block);
if (result != kSuccess) return result;
}
return kSuccess;
}
void CodeGenerator::AssembleInstruction(Instruction* instr,
const InstructionBlock* block) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleInstruction(
Instruction* instr, const InstructionBlock* block) {
AssembleGaps(instr);
DCHECK_IMPLIES(
block->must_deconstruct_frame(),
......@@ -323,7 +328,8 @@ void CodeGenerator::AssembleInstruction(Instruction* instr,
}
AssembleSourcePosition(instr);
// Assemble architecture-specific code for the instruction.
AssembleArchInstruction(instr);
CodeGenResult result = AssembleArchInstruction(instr);
if (result != kSuccess) return result;
FlagsMode mode = FlagsModeField::decode(instr->opcode());
FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
......@@ -339,7 +345,7 @@ void CodeGenerator::AssembleInstruction(Instruction* instr,
if (!IsNextInAssemblyOrder(true_rpo)) {
AssembleArchJump(true_rpo);
}
return;
return kSuccess;
}
if (IsNextInAssemblyOrder(true_rpo)) {
// true block is next, can fall through if condition negated.
......@@ -381,6 +387,7 @@ void CodeGenerator::AssembleInstruction(Instruction* instr,
break;
}
}
return kSuccess;
}
......
......@@ -90,11 +90,14 @@ class CodeGenerator final : public GapResolver::Assembler {
bool IsMaterializableFromRoot(Handle<HeapObject> object,
Heap::RootListIndex* index_return);
enum CodeGenResult { kSuccess, kTooManyDeoptimizationBailouts };
// Assemble instructions for the specified block.
void AssembleBlock(const InstructionBlock* block);
CodeGenResult AssembleBlock(const InstructionBlock* block);
// Assemble code for the specified instruction.
void AssembleInstruction(Instruction* instr, const InstructionBlock* block);
CodeGenResult AssembleInstruction(Instruction* instr,
const InstructionBlock* block);
void AssembleSourcePosition(Instruction* instr);
void AssembleGaps(Instruction* instr);
......@@ -102,15 +105,15 @@ class CodeGenerator final : public GapResolver::Assembler {
// ============= Architecture-specific code generation methods. ==============
// ===========================================================================
void AssembleArchInstruction(Instruction* instr);
CodeGenResult AssembleArchInstruction(Instruction* instr);
void AssembleArchJump(RpoNumber target);
void AssembleArchBranch(Instruction* instr, BranchInfo* branch);
void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
void AssembleArchLookupSwitch(Instruction* instr);
void AssembleArchTableSwitch(Instruction* instr);
void AssembleDeoptimizerCall(int deoptimization_id,
Deoptimizer::BailoutType bailout_type);
CodeGenResult AssembleDeoptimizerCall(int deoptimization_id,
Deoptimizer::BailoutType bailout_type);
// Generates an architecture-specific, descriptor-specific prologue
// to set up a stack frame.
......
......@@ -427,7 +427,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
IA32OperandConverter i(this, instr);
InstructionCode opcode = instr->opcode();
ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
......@@ -546,7 +547,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1331,6 +1334,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
UNREACHABLE(); // Won't be generated by instruction selector.
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
......@@ -1504,12 +1508,13 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
__ jmp(Operand::JumpTable(input, times_4, table));
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
return kSuccess;
}
......
......@@ -531,7 +531,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
MipsOperandConverter i(this, instr);
InstructionCode opcode = instr->opcode();
ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
......@@ -653,7 +654,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1344,6 +1347,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
ASSEMBLE_ATOMIC_LOAD_INTEGER(lw);
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
......@@ -1638,12 +1642,13 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
});
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
return kSuccess;
}
void CodeGenerator::FinishFrame(Frame* frame) {
......
......@@ -543,7 +543,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
MipsOperandConverter i(this, instr);
InstructionCode opcode = instr->opcode();
ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
......@@ -663,7 +664,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1594,6 +1597,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
ASSEMBLE_ATOMIC_LOAD_INTEGER(lw);
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
......@@ -1905,12 +1909,13 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
});
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
return kSuccess;
}
void CodeGenerator::FinishFrame(Frame* frame) {
......
......@@ -727,7 +727,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
PPCOperandConverter i(this, instr);
ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode());
......@@ -868,7 +869,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1611,6 +1614,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
UNREACHABLE();
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
......@@ -1730,15 +1734,16 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
__ Jump(kScratchReg);
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
// TODO(turbofan): We should be able to generate better code by sharing the
// actual final call site and just bl'ing to it here, similar to what we do
// in the lithium backend.
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
return kSuccess;
}
void CodeGenerator::FinishFrame(Frame* frame) {
......
......@@ -593,7 +593,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
S390OperandConverter i(this, instr);
ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode());
......@@ -722,7 +723,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1661,6 +1664,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
UNREACHABLE();
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
// Assembles branches after an instruction.
......@@ -1780,14 +1784,16 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
__ Jump(kScratchReg);
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
// TODO(turbofan): We should be able to generate better code by sharing the
// actual final call site and just bl'ing to it here, similar to what we do
// in the lithium backend.
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
return kSuccess;
}
void CodeGenerator::FinishFrame(Frame* frame) {
......
......@@ -649,7 +649,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
X64OperandConverter i(this, instr);
InstructionCode opcode = instr->opcode();
ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
......@@ -770,7 +771,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1768,6 +1771,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
UNREACHABLE(); // Won't be generated by instruction selector.
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
......@@ -1930,12 +1934,13 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
__ jmp(Operand(kScratchRegister, input, times_8, 0));
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
return kSuccess;
}
......
......@@ -434,7 +434,8 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
}
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
X87OperandConverter i(this, instr);
InstructionCode opcode = instr->opcode();
ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
......@@ -632,7 +633,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
Deoptimizer::BailoutType bailout_type =
Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
CodeGenResult result =
AssembleDeoptimizerCall(deopt_state_id, bailout_type);
if (result != kSuccess) return result;
break;
}
case kArchRet:
......@@ -1771,6 +1774,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
UNREACHABLE(); // Won't be generated by instruction selector.
break;
}
return kSuccess;
} // NOLINT(readability/fn_size)
......@@ -1980,12 +1984,13 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
__ jmp(Operand::JumpTable(input, times_4, table));
}
void CodeGenerator::AssembleDeoptimizerCall(
CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
__ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
return kSuccess;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment