[compiler] Split GenerateCode into AssembleCode and FinalizeCode.
AssembleCode will eventually be moved into ExecuteJob, i.e., off the main thread. Bug: v8:6048 Change-Id: If84ee2aaca6c8827cb769c7d69e5094fb4f32e4b Reviewed-on: https://chromium-review.googlesource.com/506669 Commit-Queue: Georg Neis <neis@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#45372}
This commit is contained in:
parent
789b60458b
commit
a28b940e89
@ -60,7 +60,8 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
|
|||||||
osr_pc_offset_(-1),
|
osr_pc_offset_(-1),
|
||||||
optimized_out_literal_id_(-1),
|
optimized_out_literal_id_(-1),
|
||||||
source_position_table_builder_(code->zone(),
|
source_position_table_builder_(code->zone(),
|
||||||
info->SourcePositionRecordingMode()) {
|
info->SourcePositionRecordingMode()),
|
||||||
|
result_(kSuccess) {
|
||||||
for (int i = 0; i < code->InstructionBlockCount(); ++i) {
|
for (int i = 0; i < code->InstructionBlockCount(); ++i) {
|
||||||
new (&labels_[i]) Label;
|
new (&labels_[i]) Label;
|
||||||
}
|
}
|
||||||
@ -74,8 +75,7 @@ void CodeGenerator::CreateFrameAccessState(Frame* frame) {
|
|||||||
frame_access_state_ = new (code()->zone()) FrameAccessState(frame);
|
frame_access_state_ = new (code()->zone()) FrameAccessState(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::AssembleCode() {
|
||||||
Handle<Code> CodeGenerator::GenerateCode() {
|
|
||||||
CompilationInfo* info = this->info();
|
CompilationInfo* info = this->info();
|
||||||
|
|
||||||
// Open a frame scope to indicate that there is a frame on the stack. The
|
// Open a frame scope to indicate that there is a frame on the stack. The
|
||||||
@ -175,14 +175,13 @@ Handle<Code> CodeGenerator::GenerateCode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeGenResult result;
|
|
||||||
if (FLAG_enable_embedded_constant_pool && !block->needs_frame()) {
|
if (FLAG_enable_embedded_constant_pool && !block->needs_frame()) {
|
||||||
ConstantPoolUnavailableScope constant_pool_unavailable(masm());
|
ConstantPoolUnavailableScope constant_pool_unavailable(masm());
|
||||||
result = AssembleBlock(block);
|
result_ = AssembleBlock(block);
|
||||||
} else {
|
} else {
|
||||||
result = AssembleBlock(block);
|
result_ = AssembleBlock(block);
|
||||||
}
|
}
|
||||||
if (result != kSuccess) return Handle<Code>();
|
if (result_ != kSuccess) return;
|
||||||
unwinding_info_writer_.EndInstructionBlock(block);
|
unwinding_info_writer_.EndInstructionBlock(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,9 +227,15 @@ Handle<Code> CodeGenerator::GenerateCode() {
|
|||||||
unwinding_info_writer_.Finish(masm()->pc_offset());
|
unwinding_info_writer_.Finish(masm()->pc_offset());
|
||||||
|
|
||||||
safepoints()->Emit(masm(), frame()->GetTotalFrameSlotCount());
|
safepoints()->Emit(masm(), frame()->GetTotalFrameSlotCount());
|
||||||
|
result_ = kSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<Code> CodeGenerator::FinalizeCode() {
|
||||||
|
if (result_ != kSuccess) return Handle<Code>();
|
||||||
|
|
||||||
Handle<Code> result = v8::internal::CodeGenerator::MakeCodeEpilogue(
|
Handle<Code> result = v8::internal::CodeGenerator::MakeCodeEpilogue(
|
||||||
masm(), unwinding_info_writer_.eh_frame_writer(), info, Handle<Object>());
|
masm(), unwinding_info_writer_.eh_frame_writer(), info(),
|
||||||
|
Handle<Object>());
|
||||||
result->set_is_turbofanned(true);
|
result->set_is_turbofanned(true);
|
||||||
result->set_stack_slots(frame()->GetTotalFrameSlotCount());
|
result->set_stack_slots(frame()->GetTotalFrameSlotCount());
|
||||||
result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
|
result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
|
||||||
@ -255,7 +260,7 @@ Handle<Code> CodeGenerator::GenerateCode() {
|
|||||||
PopulateDeoptimizationData(result);
|
PopulateDeoptimizationData(result);
|
||||||
|
|
||||||
// Ensure there is space for lazy deoptimization in the relocation info.
|
// Ensure there is space for lazy deoptimization in the relocation info.
|
||||||
if (info->ShouldEnsureSpaceForLazyDeopt()) {
|
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
|
||||||
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result);
|
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,8 +80,11 @@ class CodeGenerator final : public GapResolver::Assembler {
|
|||||||
explicit CodeGenerator(Frame* frame, Linkage* linkage,
|
explicit CodeGenerator(Frame* frame, Linkage* linkage,
|
||||||
InstructionSequence* code, CompilationInfo* info);
|
InstructionSequence* code, CompilationInfo* info);
|
||||||
|
|
||||||
// Generate native code.
|
// Generate native code. After calling AssembleCode, call FinalizeCode to
|
||||||
Handle<Code> GenerateCode();
|
// produce the actual code object. If an error occurs during either phase,
|
||||||
|
// FinalizeCode returns a null handle.
|
||||||
|
void AssembleCode();
|
||||||
|
Handle<Code> FinalizeCode();
|
||||||
|
|
||||||
InstructionSequence* code() const { return code_; }
|
InstructionSequence* code() const { return code_; }
|
||||||
FrameAccessState* frame_access_state() const { return frame_access_state_; }
|
FrameAccessState* frame_access_state() const { return frame_access_state_; }
|
||||||
@ -317,6 +320,7 @@ class CodeGenerator final : public GapResolver::Assembler {
|
|||||||
int osr_pc_offset_;
|
int osr_pc_offset_;
|
||||||
int optimized_out_literal_id_;
|
int optimized_out_literal_id_;
|
||||||
SourcePositionTableBuilder source_position_table_builder_;
|
SourcePositionTableBuilder source_position_table_builder_;
|
||||||
|
CodeGenResult result_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
|
@ -174,6 +174,8 @@ class PipelineData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~PipelineData() {
|
~PipelineData() {
|
||||||
|
delete code_generator_; // Must happen before zones are destroyed.
|
||||||
|
code_generator_ = nullptr;
|
||||||
DeleteRegisterAllocationZone();
|
DeleteRegisterAllocationZone();
|
||||||
DeleteInstructionZone();
|
DeleteInstructionZone();
|
||||||
DeleteGraphZone();
|
DeleteGraphZone();
|
||||||
@ -196,6 +198,8 @@ class PipelineData {
|
|||||||
code_ = code;
|
code_ = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodeGenerator* code_generator() const { return code_generator_; }
|
||||||
|
|
||||||
// RawMachineAssembler generally produces graphs which cannot be verified.
|
// RawMachineAssembler generally produces graphs which cannot be verified.
|
||||||
bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
|
bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
|
||||||
|
|
||||||
@ -314,6 +318,11 @@ class PipelineData {
|
|||||||
sequence(), debug_name());
|
sequence(), debug_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitializeCodeGenerator(Linkage* linkage) {
|
||||||
|
DCHECK_NULL(code_generator_);
|
||||||
|
code_generator_ = new CodeGenerator(frame(), linkage, sequence(), info());
|
||||||
|
}
|
||||||
|
|
||||||
void BeginPhaseKind(const char* phase_kind_name) {
|
void BeginPhaseKind(const char* phase_kind_name) {
|
||||||
if (pipeline_statistics() != nullptr) {
|
if (pipeline_statistics() != nullptr) {
|
||||||
pipeline_statistics()->BeginPhaseKind(phase_kind_name);
|
pipeline_statistics()->BeginPhaseKind(phase_kind_name);
|
||||||
@ -339,6 +348,7 @@ class PipelineData {
|
|||||||
bool verify_graph_ = false;
|
bool verify_graph_ = false;
|
||||||
bool is_asm_ = false;
|
bool is_asm_ = false;
|
||||||
Handle<Code> code_ = Handle<Code>::null();
|
Handle<Code> code_ = Handle<Code>::null();
|
||||||
|
CodeGenerator* code_generator_ = nullptr;
|
||||||
|
|
||||||
// All objects in the following group of fields are allocated in graph_zone_.
|
// All objects in the following group of fields are allocated in graph_zone_.
|
||||||
// They are all set to nullptr when the graph_zone_ is destroyed.
|
// They are all set to nullptr when the graph_zone_ is destroyed.
|
||||||
@ -356,8 +366,7 @@ class PipelineData {
|
|||||||
|
|
||||||
// All objects in the following group of fields are allocated in
|
// All objects in the following group of fields are allocated in
|
||||||
// instruction_zone_. They are all set to nullptr when the instruction_zone_
|
// instruction_zone_. They are all set to nullptr when the instruction_zone_
|
||||||
// is
|
// is destroyed.
|
||||||
// destroyed.
|
|
||||||
ZoneStats::Scope instruction_zone_scope_;
|
ZoneStats::Scope instruction_zone_scope_;
|
||||||
Zone* instruction_zone_;
|
Zone* instruction_zone_;
|
||||||
InstructionSequence* sequence_ = nullptr;
|
InstructionSequence* sequence_ = nullptr;
|
||||||
@ -400,8 +409,11 @@ class PipelineImpl final {
|
|||||||
// Run the concurrent optimization passes.
|
// Run the concurrent optimization passes.
|
||||||
bool OptimizeGraph(Linkage* linkage);
|
bool OptimizeGraph(Linkage* linkage);
|
||||||
|
|
||||||
// Perform the actual code generation and return handle to a code object.
|
// Run the code assembly pass.
|
||||||
Handle<Code> GenerateCode(Linkage* linkage);
|
void AssembleCode(Linkage* linkage);
|
||||||
|
|
||||||
|
// Run the code finalization pass.
|
||||||
|
Handle<Code> FinalizeCode();
|
||||||
|
|
||||||
bool ScheduleAndSelectInstructions(Linkage* linkage, bool trim_graph);
|
bool ScheduleAndSelectInstructions(Linkage* linkage, bool trim_graph);
|
||||||
void RunPrintAndVerify(const char* phase, bool untyped = false);
|
void RunPrintAndVerify(const char* phase, bool untyped = false);
|
||||||
@ -624,7 +636,8 @@ PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl() {
|
PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl() {
|
||||||
Handle<Code> code = pipeline_.GenerateCode(linkage_);
|
pipeline_.AssembleCode(linkage_);
|
||||||
|
Handle<Code> code = pipeline_.FinalizeCode();
|
||||||
if (code.is_null()) {
|
if (code.is_null()) {
|
||||||
if (info()->bailout_reason() == kNoReason) {
|
if (info()->bailout_reason() == kNoReason) {
|
||||||
return AbortOptimization(kCodeGenerationFailed);
|
return AbortOptimization(kCodeGenerationFailed);
|
||||||
@ -711,7 +724,8 @@ PipelineWasmCompilationJob::ExecuteJobImpl() {
|
|||||||
|
|
||||||
PipelineWasmCompilationJob::Status
|
PipelineWasmCompilationJob::Status
|
||||||
PipelineWasmCompilationJob::FinalizeJobImpl() {
|
PipelineWasmCompilationJob::FinalizeJobImpl() {
|
||||||
pipeline_.GenerateCode(&linkage_);
|
pipeline_.AssembleCode(&linkage_);
|
||||||
|
pipeline_.FinalizeCode();
|
||||||
return SUCCEEDED;
|
return SUCCEEDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1448,14 +1462,19 @@ struct JumpThreadingPhase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AssembleCodePhase {
|
||||||
|
static const char* phase_name() { return "assemble code"; }
|
||||||
|
|
||||||
struct GenerateCodePhase {
|
void Run(PipelineData* data, Zone* temp_zone) {
|
||||||
static const char* phase_name() { return "generate code"; }
|
data->code_generator()->AssembleCode();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
|
struct FinalizeCodePhase {
|
||||||
CodeGenerator generator(data->frame(), linkage, data->sequence(),
|
static const char* phase_name() { return "finalize code"; }
|
||||||
data->info());
|
|
||||||
data->set_code(generator.GenerateCode());
|
void Run(PipelineData* data, Zone* temp_zone) {
|
||||||
|
data->set_code(data->code_generator()->FinalizeCode());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1724,7 +1743,8 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info) {
|
|||||||
|
|
||||||
if (!pipeline.CreateGraph()) return Handle<Code>::null();
|
if (!pipeline.CreateGraph()) return Handle<Code>::null();
|
||||||
if (!pipeline.OptimizeGraph(&linkage)) return Handle<Code>::null();
|
if (!pipeline.OptimizeGraph(&linkage)) return Handle<Code>::null();
|
||||||
return pipeline.GenerateCode(&linkage);
|
pipeline.AssembleCode(&linkage);
|
||||||
|
return pipeline.FinalizeCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@ -1900,13 +1920,16 @@ bool PipelineImpl::ScheduleAndSelectInstructions(Linkage* linkage,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Code> PipelineImpl::GenerateCode(Linkage* linkage) {
|
void PipelineImpl::AssembleCode(Linkage* linkage) {
|
||||||
PipelineData* data = this->data_;
|
PipelineData* data = this->data_;
|
||||||
|
|
||||||
data->BeginPhaseKind("code generation");
|
data->BeginPhaseKind("code generation");
|
||||||
|
data->InitializeCodeGenerator(linkage);
|
||||||
|
Run<AssembleCodePhase>();
|
||||||
|
}
|
||||||
|
|
||||||
// Generate final machine code.
|
Handle<Code> PipelineImpl::FinalizeCode() {
|
||||||
Run<GenerateCodePhase>(linkage);
|
PipelineData* data = this->data_;
|
||||||
|
Run<FinalizeCodePhase>();
|
||||||
|
|
||||||
Handle<Code> code = data->code();
|
Handle<Code> code = data->code();
|
||||||
if (data->profiler_data()) {
|
if (data->profiler_data()) {
|
||||||
@ -1954,7 +1977,8 @@ Handle<Code> PipelineImpl::ScheduleAndGenerateCode(
|
|||||||
if (!ScheduleAndSelectInstructions(&linkage, false)) return Handle<Code>();
|
if (!ScheduleAndSelectInstructions(&linkage, false)) return Handle<Code>();
|
||||||
|
|
||||||
// Generate the final machine code.
|
// Generate the final machine code.
|
||||||
return GenerateCode(&linkage);
|
AssembleCode(&linkage);
|
||||||
|
return FinalizeCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config,
|
void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config,
|
||||||
|
Loading…
Reference in New Issue
Block a user