Index: src/compiler/pipeline.cc |
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc |
index e77a0ed0b24c30d2dc9857909b83ca62eafd7629..f4d898f8a5457af7357f2e56a7c15429de5f9a38 100644 |
--- a/src/compiler/pipeline.cc |
+++ b/src/compiler/pipeline.cc |
@@ -73,13 +73,14 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
-class PipelineData : public ZoneObject { |
+class PipelineData { |
public: |
// For main entry point. |
PipelineData(ZonePool* zone_pool, CompilationInfo* info, |
PipelineStatistics* pipeline_statistics) |
: isolate_(info->isolate()), |
info_(info), |
+ debug_name_(info_->GetDebugName()), |
outer_zone_(info_->zone()), |
zone_pool_(zone_pool), |
pipeline_statistics_(pipeline_statistics), |
@@ -107,6 +108,7 @@ class PipelineData : public ZoneObject { |
SourcePositionTable* source_positions) |
: isolate_(info->isolate()), |
info_(info), |
+ debug_name_(info_->GetDebugName()), |
zone_pool_(zone_pool), |
graph_zone_scope_(zone_pool_), |
graph_(graph), |
@@ -121,6 +123,7 @@ class PipelineData : public ZoneObject { |
Schedule* schedule) |
: isolate_(info->isolate()), |
info_(info), |
+ debug_name_(info_->GetDebugName()), |
zone_pool_(zone_pool), |
graph_zone_scope_(zone_pool_), |
graph_(graph), |
@@ -136,6 +139,7 @@ class PipelineData : public ZoneObject { |
InstructionSequence* sequence) |
: isolate_(info->isolate()), |
info_(info), |
+ debug_name_(info_->GetDebugName()), |
zone_pool_(zone_pool), |
graph_zone_scope_(zone_pool_), |
instruction_zone_scope_(zone_pool_), |
@@ -144,14 +148,12 @@ class PipelineData : public ZoneObject { |
register_allocation_zone_scope_(zone_pool_), |
register_allocation_zone_(register_allocation_zone_scope_.zone()) {} |
- void Destroy() { |
+ ~PipelineData() { |
DeleteRegisterAllocationZone(); |
DeleteInstructionZone(); |
DeleteGraphZone(); |
} |
- ~PipelineData() { Destroy(); } |
- |
Isolate* isolate() const { return isolate_; } |
CompilationInfo* info() const { return info_; } |
ZonePool* zone_pool() const { return zone_pool_; } |
@@ -163,22 +165,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; } |
Zone* graph_zone() const { return graph_zone_; } |
Graph* graph() const { return graph_; } |
- SourcePositionTable* source_positions() const { |
- DCHECK_NOT_NULL(source_positions_); |
- return source_positions_; |
- } |
+ SourcePositionTable* source_positions() const { return source_positions_; } |
MachineOperatorBuilder* machine() const { return machine_; } |
CommonOperatorBuilder* common() const { return common_; } |
JSOperatorBuilder* javascript() const { return javascript_; } |
@@ -218,6 +211,18 @@ class PipelineData : public ZoneObject { |
return register_allocation_data_; |
} |
+ BasicBlockProfiler::Data* profiler_data() const { return profiler_data_; } |
+ void set_profiler_data(BasicBlockProfiler::Data* profiler_data) { |
+ profiler_data_ = profiler_data; |
+ } |
+ |
+ std::string const& source_position_output() const { |
+ return source_position_output_; |
+ } |
+ void set_source_position_output(std::string const& source_position_output) { |
+ source_position_output_ = source_position_output; |
+ } |
+ |
void DeleteGraphZone() { |
if (graph_zone_ == nullptr) return; |
graph_zone_scope_.Destroy(); |
@@ -274,24 +279,22 @@ class PipelineData : public ZoneObject { |
} |
void InitializeRegisterAllocationData(const RegisterConfiguration* config, |
- CallDescriptor* descriptor, |
- const char* debug_name) { |
+ CallDescriptor* descriptor) { |
DCHECK(register_allocation_data_ == nullptr); |
register_allocation_data_ = new (register_allocation_zone()) |
RegisterAllocationData(config, register_allocation_zone(), frame(), |
- sequence(), debug_name); |
+ sequence(), debug_name_.get()); |
} |
private: |
- Isolate* isolate_; |
- CompilationInfo* info_; |
+ Isolate* const isolate_; |
+ CompilationInfo* const info_; |
+ base::SmartArrayPointer<char> debug_name_; |
Zone* outer_zone_ = nullptr; |
ZonePool* const zone_pool_; |
PipelineStatistics* pipeline_statistics_ = nullptr; |
bool compilation_failed_ = false; |
- Handle<Code> code_; |
- BasicBlockProfiler::Data* profiler_data_ = nullptr; |
- std::ostringstream source_position_output_; |
+ Handle<Code> code_ = Handle<Code>::null(); |
// 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. |
@@ -324,6 +327,12 @@ class PipelineData : public ZoneObject { |
Zone* register_allocation_zone_; |
RegisterAllocationData* register_allocation_data_ = nullptr; |
+ // Basic block profiling support. |
+ BasicBlockProfiler::Data* profiler_data_ = nullptr; |
+ |
+ // Source position output for --trace-turbo. |
+ std::string source_position_output_; |
+ |
int CalculateFixedFrameSize(CallDescriptor* descriptor) { |
if (descriptor->IsJSFunctionCall()) { |
return StandardFrameConstants::kFixedSlotCount; |
@@ -459,15 +468,59 @@ class PipelineRunScope { |
ZonePool::Scope zone_scope_; |
}; |
-class PipelineCompilationJob : public OptimizedCompileJob { |
+PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info, |
+ ZonePool* zone_pool) { |
+ if (!FLAG_turbo_stats) return nullptr; |
+ |
+ PipelineStatistics* pipeline_statistics = |
+ new PipelineStatistics(info, zone_pool); |
+ pipeline_statistics->BeginPhaseKind("initializing"); |
+ |
+ FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "w+"); |
+ if (json_file != nullptr) { |
+ OFStream json_of(json_file); |
+ Handle<Script> script = info->script(); |
+ base::SmartArrayPointer<char> function_name = info->GetDebugName(); |
+ int pos = info->shared_info()->start_position(); |
+ json_of << "{\"function\":\"" << function_name.get() |
+ << "\", \"sourcePosition\":" << pos << ", \"source\":\""; |
+ if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
+ DisallowHeapAllocation no_allocation; |
+ int start = info->shared_info()->start_position(); |
+ int len = info->shared_info()->end_position() - start; |
+ String::SubStringRange source(String::cast(script->source()), start, len); |
+ for (const auto& c : source) { |
+ json_of << AsEscapedUC16ForJSON(c); |
+ } |
+ } |
+ json_of << "\",\n\"phases\":["; |
+ fclose(json_file); |
+ } |
+ |
+ return pipeline_statistics; |
+} |
+ |
+class PipelineCompilationJob final : public OptimizedCompileJob { |
public: |
explicit PipelineCompilationJob(CompilationInfo* info) |
- : OptimizedCompileJob(info, "TurboFan") {} |
+ : OptimizedCompileJob(info, "TurboFan"), |
+ zone_pool_(info->isolate()->allocator()), |
+ pipeline_statistics_(CreatePipelineStatistics(info, &zone_pool_)), |
+ data_(&zone_pool_, info, pipeline_statistics_.get()), |
+ pipeline_(&data_), |
+ linkage_(Linkage::ComputeIncoming(info->zone(), info)) {} |
protected: |
- virtual Status CreateGraphImpl(); |
- virtual Status OptimizeGraphImpl(); |
- virtual Status GenerateCodeImpl(); |
+ Status CreateGraphImpl() final; |
+ Status OptimizeGraphImpl() final; |
+ Status GenerateCodeImpl() final; |
+ |
+ private: |
+ ZonePool zone_pool_; |
+ base::SmartPointer<PipelineStatistics> pipeline_statistics_; |
+ PipelineData data_; |
+ Pipeline pipeline_; |
+ Linkage linkage_; |
}; |
PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { |
@@ -489,31 +542,76 @@ PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { |
if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED; |
} |
- Pipeline pipeline(info()); |
- pipeline.GenerateCode(); |
- if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. |
- if (info()->code().is_null()) return AbortOptimization(kGraphBuildingFailed); |
+ if (!pipeline_.CreateGraph()) { |
+ if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. |
+ return AbortOptimization(kGraphBuildingFailed); |
+ } |
return SUCCEEDED; |
} |
PipelineCompilationJob::Status PipelineCompilationJob::OptimizeGraphImpl() { |
- // TODO(turbofan): Currently everything is done in the first phase. |
- DCHECK(!info()->code().is_null()); |
+ if (!pipeline_.OptimizeGraph(&linkage_)) return FAILED; |
return SUCCEEDED; |
} |
PipelineCompilationJob::Status PipelineCompilationJob::GenerateCodeImpl() { |
- // TODO(turbofan): Currently everything is done in the first phase. |
- DCHECK(!info()->code().is_null()); |
- info()->dependencies()->Commit(info()->code()); |
+ Handle<Code> code = pipeline_.GenerateCode(&linkage_); |
+ if (code.is_null()) { |
+ if (info()->bailout_reason() == kNoReason) { |
+ return AbortOptimization(kCodeGenerationFailed); |
+ } |
+ return BAILED_OUT; |
+ } |
+ info()->dependencies()->Commit(code); |
+ info()->SetCode(code); |
if (info()->is_deoptimization_enabled()) { |
- info()->context()->native_context()->AddOptimizedCode(*info()->code()); |
- RegisterWeakObjectsInOptimizedCode(info()->code()); |
+ info()->context()->native_context()->AddOptimizedCode(*code); |
+ RegisterWeakObjectsInOptimizedCode(code); |
} |
return SUCCEEDED; |
} |
+class PipelineWasmCompilationJob final : public OptimizedCompileJob { |
+ public: |
+ explicit PipelineWasmCompilationJob(CompilationInfo* info, Graph* graph, |
+ CallDescriptor* descriptor, |
+ SourcePositionTable* source_positions) |
+ : OptimizedCompileJob(info, "TurboFan"), |
+ zone_pool_(info->isolate()->allocator()), |
+ data_(&zone_pool_, info, graph, source_positions), |
+ pipeline_(&data_), |
+ linkage_(descriptor) {} |
+ |
+ protected: |
+ Status CreateGraphImpl() final; |
+ Status OptimizeGraphImpl() final; |
+ Status GenerateCodeImpl() final; |
+ |
+ private: |
+ ZonePool zone_pool_; |
+ PipelineData data_; |
+ Pipeline pipeline_; |
+ Linkage linkage_; |
+}; |
+ |
+PipelineWasmCompilationJob::Status |
+PipelineWasmCompilationJob::CreateGraphImpl() { |
+ return SUCCEEDED; |
+} |
+ |
+PipelineWasmCompilationJob::Status |
+PipelineWasmCompilationJob::OptimizeGraphImpl() { |
+ if (!pipeline_.ScheduleAndSelectInstructions(&linkage_)) return FAILED; |
+ return SUCCEEDED; |
+} |
+ |
+PipelineWasmCompilationJob::Status |
+PipelineWasmCompilationJob::GenerateCodeImpl() { |
+ pipeline_.GenerateCode(&linkage_); |
+ return SUCCEEDED; |
+} |
+ |
} // namespace |
@@ -1140,6 +1238,11 @@ void Pipeline::BeginPhaseKind(const char* phase_kind_name) { |
} |
} |
+void Pipeline::EndPhaseKind() { |
+ if (data_->pipeline_statistics() != nullptr) { |
+ data_->pipeline_statistics()->EndPhaseKind(); |
+ } |
+} |
void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { |
if (FLAG_trace_turbo) { |
@@ -1150,42 +1253,8 @@ void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { |
} |
} |
- |
-Handle<Code> Pipeline::GenerateCode() { |
- ZonePool zone_pool(isolate()->allocator()); |
- base::SmartPointer<PipelineStatistics> pipeline_statistics; |
- |
- if (FLAG_turbo_stats) { |
- pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); |
- pipeline_statistics->BeginPhaseKind("initializing"); |
- } |
- |
- if (FLAG_trace_turbo) { |
- FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "w+"); |
- if (json_file != nullptr) { |
- OFStream json_of(json_file); |
- Handle<Script> script = info()->script(); |
- base::SmartArrayPointer<char> function_name = info()->GetDebugName(); |
- int pos = info()->shared_info()->start_position(); |
- json_of << "{\"function\":\"" << function_name.get() |
- << "\", \"sourcePosition\":" << pos << ", \"source\":\""; |
- if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
- DisallowHeapAllocation no_allocation; |
- int start = info()->shared_info()->start_position(); |
- int len = info()->shared_info()->end_position() - start; |
- String::SubStringRange source(String::cast(script->source()), start, |
- len); |
- for (const auto& c : source) { |
- json_of << AsEscapedUC16ForJSON(c); |
- } |
- } |
- json_of << "\",\n\"phases\":["; |
- fclose(json_file); |
- } |
- } |
- |
- PipelineData data(&zone_pool, info(), pipeline_statistics.get()); |
- this->data_ = &data; |
+bool Pipeline::CreateGraph() { |
+ PipelineData* data = this->data_; |
BeginPhaseKind("graph creation"); |
@@ -1198,7 +1267,7 @@ Handle<Code> Pipeline::GenerateCode() { |
tcf << AsC1VCompilation(info()); |
} |
- data.source_positions()->AddDecorator(); |
+ data->source_positions()->AddDecorator(); |
if (FLAG_loop_assignment_analysis) { |
Run<LoopAssignmentAnalysisPhase>(); |
@@ -1207,7 +1276,10 @@ Handle<Code> Pipeline::GenerateCode() { |
Run<TypeHintAnalysisPhase>(); |
Run<GraphBuilderPhase>(); |
- if (data.compilation_failed()) return Handle<Code>::null(); |
+ if (data->compilation_failed()) { |
+ EndPhaseKind(); |
+ return false; |
+ } |
RunPrintAndVerify("Initial untyped", true); |
// Perform OSR deconstruction. |
@@ -1226,12 +1298,12 @@ Handle<Code> Pipeline::GenerateCode() { |
if (FLAG_print_turbo_replay) { |
// Print a replay of the initial graph. |
- GraphReplayPrinter::PrintReplay(data.graph()); |
+ GraphReplayPrinter::PrintReplay(data->graph()); |
} |
// Type the graph. |
base::SmartPointer<Typer> typer; |
- typer.Reset(new Typer(isolate(), data.graph(), |
+ typer.Reset(new Typer(isolate(), data->graph(), |
info()->is_deoptimization_enabled() |
? Typer::kDeoptimizationEnabled |
: Typer::kNoFlags, |
@@ -1280,19 +1352,36 @@ Handle<Code> Pipeline::GenerateCode() { |
// TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
RunPrintAndVerify("Late optimized", true); |
+ // Kill the Typer and thereby uninstall the decorator (if any). |
+ typer.Reset(nullptr); |
+ |
+ EndPhaseKind(); |
+ |
+ return true; |
+} |
+ |
+bool Pipeline::OptimizeGraph(Linkage* linkage) { |
+ PipelineData* data = this->data_; |
+ |
+ BeginPhaseKind("block building"); |
+ |
Run<LateGraphTrimmingPhase>(); |
// TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
RunPrintAndVerify("Late trimmed", true); |
- BeginPhaseKind("block building"); |
+ data->source_positions()->RemoveDecorator(); |
- data.source_positions()->RemoveDecorator(); |
+ return ScheduleAndSelectInstructions(linkage); |
+} |
- // Kill the Typer and thereby uninstall the decorator (if any). |
- typer.Reset(nullptr); |
+Handle<Code> Pipeline::GenerateCode() { |
+ PipelineData* data = this->data_; |
- return ScheduleAndGenerateCode( |
- Linkage::ComputeIncoming(data.instruction_zone(), info())); |
+ Linkage linkage(Linkage::ComputeIncoming(data->instruction_zone(), info())); |
+ |
+ if (!CreateGraph()) return Handle<Code>::null(); |
+ if (!OptimizeGraph(&linkage)) return Handle<Code>::null(); |
+ return GenerateCode(&linkage); |
} |
Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, |
@@ -1311,8 +1400,7 @@ Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, |
pipeline_statistics->BeginPhaseKind("stub codegen"); |
} |
- Pipeline pipeline(&info); |
- pipeline.data_ = &data; |
+ Pipeline pipeline(&data); |
DCHECK_NOT_NULL(data.schedule()); |
if (FLAG_trace_turbo) { |
@@ -1330,7 +1418,17 @@ Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, |
return pipeline.ScheduleAndGenerateCode(call_descriptor); |
} |
+// static |
+Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info) { |
+ ZonePool zone_pool(info->isolate()->allocator()); |
+ base::SmartPointer<PipelineStatistics> pipeline_statistics( |
+ CreatePipelineStatistics(info, &zone_pool)); |
+ PipelineData data(&zone_pool, info, pipeline_statistics.get()); |
+ Pipeline pipeline(&data); |
+ return pipeline.GenerateCode(); |
+} |
+// static |
Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
Graph* graph, |
Schedule* schedule) { |
@@ -1339,7 +1437,7 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
return GenerateCodeForTesting(info, call_descriptor, graph, schedule); |
} |
- |
+// static |
Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
CallDescriptor* call_descriptor, |
Graph* graph, |
@@ -1353,8 +1451,7 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
pipeline_statistics->BeginPhaseKind("test codegen"); |
} |
- Pipeline pipeline(info); |
- pipeline.data_ = &data; |
+ Pipeline pipeline(&data); |
if (data.schedule() == nullptr) { |
// TODO(rossberg): Should this really be untyped? |
pipeline.RunPrintAndVerify("Machine", true); |
@@ -1363,26 +1460,17 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
return pipeline.ScheduleAndGenerateCode(call_descriptor); |
} |
-void Pipeline::InitializeWasmCompilation( |
- Zone* pipeline_zone, ZonePool* zone_pool, Graph* graph, |
- SourcePositionTable* source_positions) { |
- data_ = new (pipeline_zone) |
- PipelineData(zone_pool, info(), graph, source_positions); |
- RunPrintAndVerify("Machine", true); |
-} |
- |
-bool Pipeline::ExecuteWasmCompilation(CallDescriptor* descriptor) { |
- return ScheduleGraph(descriptor); |
-} |
- |
-Handle<Code> Pipeline::FinalizeWasmCompilation(CallDescriptor* descriptor) { |
- Handle<Code> result = GenerateCode(descriptor); |
- data_->Destroy(); |
- return result; |
+// static |
+OptimizedCompileJob* Pipeline::NewCompilationJob(CompilationInfo* info) { |
+ return new PipelineCompilationJob(info); |
} |
-OptimizedCompileJob* Pipeline::NewCompilationJob(CompilationInfo* info) { |
- return new (info->zone()) PipelineCompilationJob(info); |
+// static |
+OptimizedCompileJob* Pipeline::NewWasmCompilationJob( |
+ CompilationInfo* info, Graph* graph, CallDescriptor* descriptor, |
+ SourcePositionTable* source_positions) { |
+ return new PipelineWasmCompilationJob(info, graph, descriptor, |
+ source_positions); |
} |
bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, |
@@ -1392,25 +1480,16 @@ bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, |
sequence->zone()); |
ZonePool zone_pool(sequence->isolate()->allocator()); |
PipelineData data(&zone_pool, &info, sequence); |
- Pipeline pipeline(&info); |
- pipeline.data_ = &data; |
+ Pipeline pipeline(&data); |
pipeline.data_->InitializeFrameData(nullptr); |
pipeline.AllocateRegisters(config, nullptr, run_verifier); |
return !data.compilation_failed(); |
} |
-Handle<Code> Pipeline::ScheduleAndGenerateCode( |
- CallDescriptor* call_descriptor) { |
- if (ScheduleGraph(call_descriptor)) { |
- return GenerateCode(call_descriptor); |
- } else { |
- return Handle<Code>::null(); |
- } |
-} |
- |
-bool Pipeline::ScheduleGraph(CallDescriptor* call_descriptor) { |
+bool Pipeline::ScheduleAndSelectInstructions(Linkage* linkage) { |
+ CallDescriptor* call_descriptor = linkage->GetIncomingDescriptor(); |
PipelineData* data = this->data_; |
- DCHECK_NOT_NULL(data); |
+ |
DCHECK_NOT_NULL(data->graph()); |
if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); |
@@ -1425,8 +1504,7 @@ bool Pipeline::ScheduleGraph(CallDescriptor* call_descriptor) { |
data->InitializeFrameData(call_descriptor); |
// Select and schedule instructions covering the scheduled graph. |
- Linkage linkage(call_descriptor); |
- Run<InstructionSelectionPhase>(&linkage); |
+ Run<InstructionSelectionPhase>(linkage); |
if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { |
TurboCfgFile tcf(isolate()); |
@@ -1435,8 +1513,10 @@ bool Pipeline::ScheduleGraph(CallDescriptor* call_descriptor) { |
} |
if (FLAG_trace_turbo) { |
+ std::ostringstream source_position_output; |
// Output source position information before the graph is deleted. |
- data_->source_positions()->Print(*(data->source_position_output())); |
+ data_->source_positions()->Print(source_position_output); |
+ data_->set_source_position_output(source_position_output.str()); |
} |
data->DeleteGraphZone(); |
@@ -1452,10 +1532,10 @@ bool Pipeline::ScheduleGraph(CallDescriptor* call_descriptor) { |
Run<FrameElisionPhase>(); |
if (data->compilation_failed()) { |
info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
+ EndPhaseKind(); |
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(); |
@@ -1463,17 +1543,22 @@ bool Pipeline::ScheduleGraph(CallDescriptor* call_descriptor) { |
if (FLAG_turbo_jt) { |
Run<JumpThreadingPhase>(generate_frame_at_start); |
} |
+ |
+ EndPhaseKind(); |
+ |
return true; |
} |
-Handle<Code> Pipeline::GenerateCode(CallDescriptor* call_descriptor) { |
+Handle<Code> Pipeline::GenerateCode(Linkage* linkage) { |
PipelineData* data = this->data_; |
- Linkage linkage(call_descriptor); |
+ |
+ BeginPhaseKind("code generation"); |
+ |
// Generate final machine code. |
- Run<GenerateCodePhase>(&linkage); |
+ Run<GenerateCodePhase>(linkage); |
Handle<Code> code = data->code(); |
- if (data->profiler_data() != nullptr) { |
+ if (data->profiler_data()) { |
#if ENABLE_DISASSEMBLER |
std::ostringstream os; |
code->Disassemble(nullptr, os); |
@@ -1500,7 +1585,7 @@ Handle<Code> Pipeline::GenerateCode(CallDescriptor* call_descriptor) { |
#endif // ENABLE_DISASSEMBLER |
json_of << "\"}\n],\n"; |
json_of << "\"nodePositions\":"; |
- json_of << data->source_position_output()->str(); |
+ json_of << data->source_position_output(); |
json_of << "}"; |
fclose(json_file); |
} |
@@ -1509,9 +1594,21 @@ Handle<Code> Pipeline::GenerateCode(CallDescriptor* call_descriptor) { |
<< "Finished compiling method " << info()->GetDebugName().get() |
<< " using Turbofan" << std::endl; |
} |
+ |
return code; |
} |
+Handle<Code> Pipeline::ScheduleAndGenerateCode( |
+ CallDescriptor* call_descriptor) { |
+ Linkage linkage(call_descriptor); |
+ |
+ // Schedule the graph, perform instruction selection and register allocation. |
+ if (!ScheduleAndSelectInstructions(&linkage)) return Handle<Code>(); |
+ |
+ // Generate the final machine code. |
+ return GenerateCode(&linkage); |
+} |
+ |
void Pipeline::AllocateRegisters(const RegisterConfiguration* config, |
CallDescriptor* descriptor, |
bool run_verifier) { |
@@ -1525,15 +1622,13 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config, |
verifier_zone.get(), config, data->sequence()); |
} |
- base::SmartArrayPointer<char> debug_name; |
#ifdef DEBUG |
- debug_name = info()->GetDebugName(); |
data_->sequence()->ValidateEdgeSplitForm(); |
data_->sequence()->ValidateDeferredBlockEntryPaths(); |
data_->sequence()->ValidateDeferredBlockExitPaths(); |
#endif |
- data->InitializeRegisterAllocationData(config, descriptor, debug_name.get()); |
+ data->InitializeRegisterAllocationData(config, descriptor); |
if (info()->is_osr()) { |
OsrHelper osr_helper(info()); |
osr_helper.SetupFrame(data->frame()); |
@@ -1603,6 +1698,8 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config, |
data->DeleteRegisterAllocationZone(); |
} |
+CompilationInfo* Pipeline::info() const { return data_->info(); } |
+ |
Isolate* Pipeline::isolate() const { return info()->isolate(); } |
} // namespace compiler |