[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:
Georg Neis 2017-05-17 13:53:37 +02:00 committed by Commit Bot
parent 789b60458b
commit a28b940e89
3 changed files with 62 additions and 29 deletions

View File

@ -60,7 +60,8 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
osr_pc_offset_(-1),
optimized_out_literal_id_(-1),
source_position_table_builder_(code->zone(),
info->SourcePositionRecordingMode()) {
info->SourcePositionRecordingMode()),
result_(kSuccess) {
for (int i = 0; i < code->InstructionBlockCount(); ++i) {
new (&labels_[i]) Label;
}
@ -74,8 +75,7 @@ void CodeGenerator::CreateFrameAccessState(Frame* frame) {
frame_access_state_ = new (code()->zone()) FrameAccessState(frame);
}
Handle<Code> CodeGenerator::GenerateCode() {
void CodeGenerator::AssembleCode() {
CompilationInfo* info = this->info();
// 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()) {
ConstantPoolUnavailableScope constant_pool_unavailable(masm());
result = AssembleBlock(block);
result_ = AssembleBlock(block);
} else {
result = AssembleBlock(block);
result_ = AssembleBlock(block);
}
if (result != kSuccess) return Handle<Code>();
if (result_ != kSuccess) return;
unwinding_info_writer_.EndInstructionBlock(block);
}
}
@ -228,9 +227,15 @@ Handle<Code> CodeGenerator::GenerateCode() {
unwinding_info_writer_.Finish(masm()->pc_offset());
safepoints()->Emit(masm(), frame()->GetTotalFrameSlotCount());
result_ = kSuccess;
}
Handle<Code> CodeGenerator::FinalizeCode() {
if (result_ != kSuccess) return Handle<Code>();
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_stack_slots(frame()->GetTotalFrameSlotCount());
result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
@ -255,7 +260,7 @@ Handle<Code> CodeGenerator::GenerateCode() {
PopulateDeoptimizationData(result);
// Ensure there is space for lazy deoptimization in the relocation info.
if (info->ShouldEnsureSpaceForLazyDeopt()) {
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result);
}

View File

@ -80,8 +80,11 @@ class CodeGenerator final : public GapResolver::Assembler {
explicit CodeGenerator(Frame* frame, Linkage* linkage,
InstructionSequence* code, CompilationInfo* info);
// Generate native code.
Handle<Code> GenerateCode();
// Generate native code. After calling AssembleCode, call FinalizeCode to
// 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_; }
FrameAccessState* frame_access_state() const { return frame_access_state_; }
@ -317,6 +320,7 @@ class CodeGenerator final : public GapResolver::Assembler {
int osr_pc_offset_;
int optimized_out_literal_id_;
SourcePositionTableBuilder source_position_table_builder_;
CodeGenResult result_;
};
} // namespace compiler

View File

@ -174,6 +174,8 @@ class PipelineData {
}
~PipelineData() {
delete code_generator_; // Must happen before zones are destroyed.
code_generator_ = nullptr;
DeleteRegisterAllocationZone();
DeleteInstructionZone();
DeleteGraphZone();
@ -196,6 +198,8 @@ class PipelineData {
code_ = code;
}
CodeGenerator* code_generator() const { return code_generator_; }
// RawMachineAssembler generally produces graphs which cannot be verified.
bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
@ -314,6 +318,11 @@ class PipelineData {
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) {
if (pipeline_statistics() != nullptr) {
pipeline_statistics()->BeginPhaseKind(phase_kind_name);
@ -339,6 +348,7 @@ class PipelineData {
bool verify_graph_ = false;
bool is_asm_ = false;
Handle<Code> code_ = Handle<Code>::null();
CodeGenerator* code_generator_ = nullptr;
// 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.
@ -356,8 +366,7 @@ class PipelineData {
// All objects in the following group of fields are allocated in
// instruction_zone_. They are all set to nullptr when the instruction_zone_
// is
// destroyed.
// is destroyed.
ZoneStats::Scope instruction_zone_scope_;
Zone* instruction_zone_;
InstructionSequence* sequence_ = nullptr;
@ -400,8 +409,11 @@ class PipelineImpl final {
// Run the concurrent optimization passes.
bool OptimizeGraph(Linkage* linkage);
// Perform the actual code generation and return handle to a code object.
Handle<Code> GenerateCode(Linkage* linkage);
// Run the code assembly pass.
void AssembleCode(Linkage* linkage);
// Run the code finalization pass.
Handle<Code> FinalizeCode();
bool ScheduleAndSelectInstructions(Linkage* linkage, bool trim_graph);
void RunPrintAndVerify(const char* phase, bool untyped = false);
@ -624,7 +636,8 @@ PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl() {
}
PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl() {
Handle<Code> code = pipeline_.GenerateCode(linkage_);
pipeline_.AssembleCode(linkage_);
Handle<Code> code = pipeline_.FinalizeCode();
if (code.is_null()) {
if (info()->bailout_reason() == kNoReason) {
return AbortOptimization(kCodeGenerationFailed);
@ -711,7 +724,8 @@ PipelineWasmCompilationJob::ExecuteJobImpl() {
PipelineWasmCompilationJob::Status
PipelineWasmCompilationJob::FinalizeJobImpl() {
pipeline_.GenerateCode(&linkage_);
pipeline_.AssembleCode(&linkage_);
pipeline_.FinalizeCode();
return SUCCEEDED;
}
@ -1448,14 +1462,19 @@ struct JumpThreadingPhase {
}
};
struct AssembleCodePhase {
static const char* phase_name() { return "assemble code"; }
struct GenerateCodePhase {
static const char* phase_name() { return "generate code"; }
void Run(PipelineData* data, Zone* temp_zone) {
data->code_generator()->AssembleCode();
}
};
void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
CodeGenerator generator(data->frame(), linkage, data->sequence(),
data->info());
data->set_code(generator.GenerateCode());
struct FinalizeCodePhase {
static const char* phase_name() { return "finalize code"; }
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.OptimizeGraph(&linkage)) return Handle<Code>::null();
return pipeline.GenerateCode(&linkage);
pipeline.AssembleCode(&linkage);
return pipeline.FinalizeCode();
}
// static
@ -1900,13 +1920,16 @@ bool PipelineImpl::ScheduleAndSelectInstructions(Linkage* linkage,
return true;
}
Handle<Code> PipelineImpl::GenerateCode(Linkage* linkage) {
void PipelineImpl::AssembleCode(Linkage* linkage) {
PipelineData* data = this->data_;
data->BeginPhaseKind("code generation");
data->InitializeCodeGenerator(linkage);
Run<AssembleCodePhase>();
}
// Generate final machine code.
Run<GenerateCodePhase>(linkage);
Handle<Code> PipelineImpl::FinalizeCode() {
PipelineData* data = this->data_;
Run<FinalizeCodePhase>();
Handle<Code> code = data->code();
if (data->profiler_data()) {
@ -1954,7 +1977,8 @@ Handle<Code> PipelineImpl::ScheduleAndGenerateCode(
if (!ScheduleAndSelectInstructions(&linkage, false)) return Handle<Code>();
// Generate the final machine code.
return GenerateCode(&linkage);
AssembleCode(&linkage);
return FinalizeCode();
}
void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config,