Index: src/compiler/pipeline.cc |
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc |
index b158d8b37ac32c37914556c0c36417c031e57d62..03a0c7953c473007cdc1a934a753d20daf55696b 100644 |
--- a/src/compiler/pipeline.cc |
+++ b/src/compiler/pipeline.cc |
@@ -85,6 +85,7 @@ class PipelineData : public ZoneObject { |
pipeline_statistics_(pipeline_statistics), |
compilation_failed_(false), |
code_(Handle<Code>::null()), |
+ profiler_data_(nullptr), |
graph_zone_scope_(zone_pool_), |
graph_zone_(graph_zone_scope_.zone()), |
graph_(nullptr), |
@@ -125,6 +126,7 @@ class PipelineData : public ZoneObject { |
pipeline_statistics_(nullptr), |
compilation_failed_(false), |
code_(Handle<Code>::null()), |
+ profiler_data_(nullptr), |
graph_zone_scope_(zone_pool_), |
graph_zone_(nullptr), |
graph_(graph), |
@@ -154,6 +156,7 @@ class PipelineData : public ZoneObject { |
pipeline_statistics_(nullptr), |
compilation_failed_(false), |
code_(Handle<Code>::null()), |
+ profiler_data_(nullptr), |
graph_zone_scope_(zone_pool_), |
graph_zone_(nullptr), |
graph_(nullptr), |
@@ -191,7 +194,13 @@ class PipelineData : public ZoneObject { |
DCHECK(code_.is_null()); |
code_ = code; |
} |
- |
+ BasicBlockProfiler::Data* profiler_data() { return profiler_data_; } |
+ void set_profiler_data(BasicBlockProfiler::Data* data) { |
+ profiler_data_ = data; |
+ } |
+ std::ostringstream* source_position_output() { |
+ return &source_position_output_; |
+ } |
// RawMachineAssembler generally produces graphs which cannot be verified. |
bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } |
@@ -313,6 +322,8 @@ class PipelineData : public ZoneObject { |
PipelineStatistics* pipeline_statistics_; |
bool compilation_failed_; |
Handle<Code> code_; |
+ BasicBlockProfiler::Data* profiler_data_; |
+ std::ostringstream source_position_output_; |
// 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. |
@@ -1404,7 +1415,110 @@ void Pipeline::InitializeWasmCompilation(Zone* pipeline_zone, |
RunPrintAndVerify("Machine", true); |
} |
-void Pipeline::FinalizeWasmCompilation() { data_->Destroy(); } |
+bool Pipeline::ExecuteWasmCompilation(CallDescriptor* descriptor) { |
Michael Starzinger
2016/04/20 16:59:08
This duplicates quite a lot of complex logic. We c
ahaas
2016/04/21 07:59:43
I use the same code for the new functions and Sche
|
+ PipelineData* data = this->data_; |
+ DCHECK_NOT_NULL(data); |
+ DCHECK_NOT_NULL(data->graph()); |
+ |
+ if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); |
+ TraceSchedule(data->info(), data->schedule()); |
+ |
+ if (FLAG_turbo_profiling) { |
+ data->set_profiler_data(BasicBlockInstrumentor::Instrument( |
+ info(), data->graph(), data->schedule())); |
+ } |
+ |
+ data->InitializeInstructionSequence(descriptor); |
+ |
+ data->InitializeFrameData(descriptor); |
+ // Select and schedule instructions covering the scheduled graph. |
+ Linkage linkage(descriptor); |
+ Run<InstructionSelectionPhase>(&linkage); |
+ |
+ if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { |
+ TurboCfgFile tcf(isolate()); |
+ tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), |
+ data->sequence()); |
+ } |
+ |
+ if (FLAG_trace_turbo) { |
+ // Output source position information before the graph is deleted. |
+ data_->source_positions()->Print(*(data->source_position_output())); |
+ } |
+ |
+ data->DeleteGraphZone(); |
+ |
+ BeginPhaseKind("register allocation"); |
+ |
+ bool run_verifier = FLAG_turbo_verify_allocation; |
+ |
+ // Allocate registers. |
+ AllocateRegisters( |
+ RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), |
+ descriptor, run_verifier); |
+ Run<FrameElisionPhase>(); |
+ if (data->compilation_failed()) { |
+ info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
+ return false; |
+ } |
+ |
+ BeginPhaseKind("code generation"); |
+ // TODO(mtrofin): move this off to the register allocator. |
+ bool generate_frame_at_start = |
+ data_->sequence()->instruction_blocks().front()->must_construct_frame(); |
+ // Optimimize jumps. |
+ if (FLAG_turbo_jt) { |
+ Run<JumpThreadingPhase>(generate_frame_at_start); |
+ } |
+ return true; |
+} |
+ |
+Handle<Code> Pipeline::FinalizeWasmCompilation(CallDescriptor* descriptor) { |
+ PipelineData* data = this->data_; |
+ Linkage linkage(descriptor); |
+ // Generate final machine code. |
+ Run<GenerateCodePhase>(&linkage); |
+ |
+ Handle<Code> code = data->code(); |
+ if (data->profiler_data() != nullptr) { |
+#if ENABLE_DISASSEMBLER |
+ std::ostringstream os; |
+ code->Disassemble(nullptr, os); |
+ data->profiler_data()->SetCode(&os); |
+#endif |
+ } |
+ |
+ info()->SetCode(code); |
+ v8::internal::CodeGenerator::PrintCode(code, info()); |
+ |
+ if (FLAG_trace_turbo) { |
+ FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+"); |
+ if (json_file != nullptr) { |
+ OFStream json_of(json_file); |
+ json_of |
+ << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; |
+#if ENABLE_DISASSEMBLER |
+ std::stringstream disassembly_stream; |
+ code->Disassemble(nullptr, disassembly_stream); |
+ std::string disassembly_string(disassembly_stream.str()); |
+ for (const auto& c : disassembly_string) { |
+ json_of << AsEscapedUC16ForJSON(c); |
+ } |
+#endif // ENABLE_DISASSEMBLER |
+ json_of << "\"}\n],\n"; |
+ json_of << "\"nodePositions\":"; |
+ json_of << data->source_position_output()->str(); |
+ json_of << "}"; |
+ fclose(json_file); |
+ } |
+ OFStream os(stdout); |
+ os << "---------------------------------------------------\n" |
+ << "Finished compiling method " << info()->GetDebugName().get() |
+ << " using Turbofan" << std::endl; |
+ } |
+ data->Destroy(); |
+ return code; |
+} |
OptimizedCompileJob* Pipeline::NewCompilationJob(CompilationInfo* info) { |
return new (info->zone()) PipelineCompilationJob(info); |
@@ -1423,21 +1537,18 @@ bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, |
return !data.compilation_failed(); |
} |
- |
Handle<Code> Pipeline::ScheduleAndGenerateCode( |
CallDescriptor* call_descriptor) { |
PipelineData* data = this->data_; |
- |
DCHECK_NOT_NULL(data); |
DCHECK_NOT_NULL(data->graph()); |
if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); |
TraceSchedule(data->info(), data->schedule()); |
- BasicBlockProfiler::Data* profiler_data = nullptr; |
if (FLAG_turbo_profiling) { |
- profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), |
- data->schedule()); |
+ data->set_profiler_data(BasicBlockInstrumentor::Instrument( |
+ info(), data->graph(), data->schedule())); |
} |
data->InitializeInstructionSequence(call_descriptor); |
@@ -1453,10 +1564,9 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode( |
data->sequence()); |
} |
- std::ostringstream source_position_output; |
if (FLAG_trace_turbo) { |
// Output source position information before the graph is deleted. |
- data_->source_positions()->Print(source_position_output); |
+ data_->source_positions()->Print(*(data->source_position_output())); |
} |
data->DeleteGraphZone(); |
@@ -1483,16 +1593,15 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode( |
if (FLAG_turbo_jt) { |
Run<JumpThreadingPhase>(generate_frame_at_start); |
} |
- |
// Generate final machine code. |
Run<GenerateCodePhase>(&linkage); |
Handle<Code> code = data->code(); |
- if (profiler_data != nullptr) { |
+ if (data->profiler_data() != nullptr) { |
#if ENABLE_DISASSEMBLER |
std::ostringstream os; |
code->Disassemble(nullptr, os); |
- profiler_data->SetCode(&os); |
+ data->profiler_data()->SetCode(&os); |
#endif |
} |
@@ -1515,7 +1624,7 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode( |
#endif // ENABLE_DISASSEMBLER |
json_of << "\"}\n],\n"; |
json_of << "\"nodePositions\":"; |
- json_of << source_position_output.str(); |
+ json_of << data->source_position_output()->str(); |
json_of << "}"; |
fclose(json_file); |
} |
@@ -1524,11 +1633,9 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode( |
<< "Finished compiling method " << info()->GetDebugName().get() |
<< " using Turbofan" << std::endl; |
} |
- |
return code; |
} |
- |
void Pipeline::AllocateRegisters(const RegisterConfiguration* config, |
CallDescriptor* descriptor, |
bool run_verifier) { |