OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/pipeline.h" | 5 #include "src/compiler/pipeline.h" |
6 | 6 |
7 #include <fstream> // NOLINT(readability/streams) | 7 #include <fstream> // NOLINT(readability/streams) |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "src/base/adapters.h" | 10 #include "src/base/adapters.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 #include "src/isolate-inl.h" | 66 #include "src/isolate-inl.h" |
67 #include "src/ostreams.h" | 67 #include "src/ostreams.h" |
68 #include "src/register-configuration.h" | 68 #include "src/register-configuration.h" |
69 #include "src/type-info.h" | 69 #include "src/type-info.h" |
70 #include "src/utils.h" | 70 #include "src/utils.h" |
71 | 71 |
72 namespace v8 { | 72 namespace v8 { |
73 namespace internal { | 73 namespace internal { |
74 namespace compiler { | 74 namespace compiler { |
75 | 75 |
76 class PipelineData : public ZoneObject { | 76 class PipelineData { |
77 public: | 77 public: |
78 // For main entry point. | 78 // For main entry point. |
79 PipelineData(ZonePool* zone_pool, CompilationInfo* info, | 79 PipelineData(ZonePool* zone_pool, CompilationInfo* info, |
80 PipelineStatistics* pipeline_statistics) | 80 PipelineStatistics* pipeline_statistics) |
81 : isolate_(info->isolate()), | 81 : isolate_(info->isolate()), |
82 info_(info), | 82 info_(info), |
83 outer_zone_(info_->zone()), | 83 outer_zone_(info_->zone()), |
84 zone_pool_(zone_pool), | 84 zone_pool_(zone_pool), |
85 pipeline_statistics_(pipeline_statistics), | 85 pipeline_statistics_(pipeline_statistics), |
86 graph_zone_scope_(zone_pool_), | 86 graph_zone_scope_(zone_pool_), |
(...skipping 14 matching lines...) Expand all Loading... |
101 jsgraph_ = new (graph_zone_) | 101 jsgraph_ = new (graph_zone_) |
102 JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_); | 102 JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_); |
103 } | 103 } |
104 | 104 |
105 // For WASM compile entry point. | 105 // For WASM compile entry point. |
106 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, | 106 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, |
107 SourcePositionTable* source_positions) | 107 SourcePositionTable* source_positions) |
108 : isolate_(info->isolate()), | 108 : isolate_(info->isolate()), |
109 info_(info), | 109 info_(info), |
110 zone_pool_(zone_pool), | 110 zone_pool_(zone_pool), |
| 111 pipeline_statistics_(nullptr), |
111 graph_zone_scope_(zone_pool_), | 112 graph_zone_scope_(zone_pool_), |
112 graph_(graph), | 113 graph_(graph), |
113 source_positions_(source_positions), | 114 source_positions_(new (info->zone()) SourcePositionTable(graph_)), |
114 instruction_zone_scope_(zone_pool_), | 115 instruction_zone_scope_(zone_pool_), |
115 instruction_zone_(instruction_zone_scope_.zone()), | 116 instruction_zone_(instruction_zone_scope_.zone()), |
116 register_allocation_zone_scope_(zone_pool_), | 117 register_allocation_zone_scope_(zone_pool_), |
117 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} | 118 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} |
118 | 119 |
119 // For machine graph testing entry point. | 120 // For machine graph testing entry point. |
120 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, | 121 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, |
121 Schedule* schedule) | 122 Schedule* schedule) |
122 : isolate_(info->isolate()), | 123 : isolate_(info->isolate()), |
123 info_(info), | 124 info_(info), |
124 zone_pool_(zone_pool), | 125 zone_pool_(zone_pool), |
| 126 pipeline_statistics_(nullptr), |
125 graph_zone_scope_(zone_pool_), | 127 graph_zone_scope_(zone_pool_), |
126 graph_(graph), | 128 graph_(graph), |
127 source_positions_(new (info->zone()) SourcePositionTable(graph_)), | 129 source_positions_(new (info->zone()) SourcePositionTable(graph_)), |
128 schedule_(schedule), | 130 schedule_(schedule), |
129 instruction_zone_scope_(zone_pool_), | 131 instruction_zone_scope_(zone_pool_), |
130 instruction_zone_(instruction_zone_scope_.zone()), | 132 instruction_zone_(instruction_zone_scope_.zone()), |
131 register_allocation_zone_scope_(zone_pool_), | 133 register_allocation_zone_scope_(zone_pool_), |
132 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} | 134 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} |
133 | 135 |
134 // For register allocation testing entry point. | 136 // For register allocation testing entry point. |
135 PipelineData(ZonePool* zone_pool, CompilationInfo* info, | 137 PipelineData(ZonePool* zone_pool, CompilationInfo* info, |
136 InstructionSequence* sequence) | 138 InstructionSequence* sequence) |
137 : isolate_(info->isolate()), | 139 : isolate_(info->isolate()), |
138 info_(info), | 140 info_(info), |
139 zone_pool_(zone_pool), | 141 zone_pool_(zone_pool), |
| 142 pipeline_statistics_(nullptr), |
140 graph_zone_scope_(zone_pool_), | 143 graph_zone_scope_(zone_pool_), |
141 instruction_zone_scope_(zone_pool_), | 144 instruction_zone_scope_(zone_pool_), |
142 instruction_zone_(sequence->zone()), | 145 instruction_zone_(sequence->zone()), |
143 sequence_(sequence), | 146 sequence_(sequence), |
144 register_allocation_zone_scope_(zone_pool_), | 147 register_allocation_zone_scope_(zone_pool_), |
145 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} | 148 register_allocation_zone_(register_allocation_zone_scope_.zone()) {} |
146 | 149 |
147 void Destroy() { | 150 ~PipelineData() { |
148 DeleteRegisterAllocationZone(); | 151 DeleteRegisterAllocationZone(); |
149 DeleteInstructionZone(); | 152 DeleteInstructionZone(); |
150 DeleteGraphZone(); | 153 DeleteGraphZone(); |
151 } | 154 } |
152 | 155 |
153 ~PipelineData() { Destroy(); } | |
154 | |
155 Isolate* isolate() const { return isolate_; } | 156 Isolate* isolate() const { return isolate_; } |
156 CompilationInfo* info() const { return info_; } | 157 CompilationInfo* info() const { return info_; } |
157 ZonePool* zone_pool() const { return zone_pool_; } | 158 ZonePool* zone_pool() const { return zone_pool_; } |
158 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } | 159 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } |
159 bool compilation_failed() const { return compilation_failed_; } | 160 bool compilation_failed() const { return compilation_failed_; } |
160 void set_compilation_failed() { compilation_failed_ = true; } | 161 void set_compilation_failed() { compilation_failed_ = true; } |
161 Handle<Code> code() { return code_; } | 162 Handle<Code> code() { return code_; } |
162 void set_code(Handle<Code> code) { | 163 void set_code(Handle<Code> code) { |
163 DCHECK(code_.is_null()); | 164 DCHECK(code_.is_null()); |
164 code_ = code; | 165 code_ = code; |
165 } | 166 } |
166 BasicBlockProfiler::Data* profiler_data() { return profiler_data_; } | 167 |
167 void set_profiler_data(BasicBlockProfiler::Data* data) { | |
168 profiler_data_ = data; | |
169 } | |
170 std::ostringstream* source_position_output() { | |
171 return &source_position_output_; | |
172 } | |
173 // RawMachineAssembler generally produces graphs which cannot be verified. | 168 // RawMachineAssembler generally produces graphs which cannot be verified. |
174 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } | 169 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } |
175 | 170 |
176 Zone* graph_zone() const { return graph_zone_; } | 171 Zone* graph_zone() const { return graph_zone_; } |
177 Graph* graph() const { return graph_; } | 172 Graph* graph() const { return graph_; } |
178 SourcePositionTable* source_positions() const { | 173 SourcePositionTable* source_positions() const { return source_positions_; } |
179 DCHECK_NOT_NULL(source_positions_); | |
180 return source_positions_; | |
181 } | |
182 MachineOperatorBuilder* machine() const { return machine_; } | 174 MachineOperatorBuilder* machine() const { return machine_; } |
183 CommonOperatorBuilder* common() const { return common_; } | 175 CommonOperatorBuilder* common() const { return common_; } |
184 JSOperatorBuilder* javascript() const { return javascript_; } | 176 JSOperatorBuilder* javascript() const { return javascript_; } |
185 JSGraph* jsgraph() const { return jsgraph_; } | 177 JSGraph* jsgraph() const { return jsgraph_; } |
186 MaybeHandle<Context> native_context() const { | 178 MaybeHandle<Context> native_context() const { |
187 if (info()->is_native_context_specializing()) { | 179 if (info()->is_native_context_specializing()) { |
188 return handle(info()->native_context(), isolate()); | 180 return handle(info()->native_context(), isolate()); |
189 } | 181 } |
190 return MaybeHandle<Context>(); | 182 return MaybeHandle<Context>(); |
191 } | 183 } |
(...skipping 19 matching lines...) Expand all Loading... |
211 | 203 |
212 Zone* instruction_zone() const { return instruction_zone_; } | 204 Zone* instruction_zone() const { return instruction_zone_; } |
213 InstructionSequence* sequence() const { return sequence_; } | 205 InstructionSequence* sequence() const { return sequence_; } |
214 Frame* frame() const { return frame_; } | 206 Frame* frame() const { return frame_; } |
215 | 207 |
216 Zone* register_allocation_zone() const { return register_allocation_zone_; } | 208 Zone* register_allocation_zone() const { return register_allocation_zone_; } |
217 RegisterAllocationData* register_allocation_data() const { | 209 RegisterAllocationData* register_allocation_data() const { |
218 return register_allocation_data_; | 210 return register_allocation_data_; |
219 } | 211 } |
220 | 212 |
| 213 BasicBlockProfiler::Data* profiler_data() const { return profiler_data_; } |
| 214 void set_profiler_data(BasicBlockProfiler::Data* profiler_data) { |
| 215 profiler_data_ = profiler_data; |
| 216 } |
| 217 |
| 218 std::string const& source_position_output() const { |
| 219 return source_position_output_; |
| 220 } |
| 221 void set_source_position_output(std::string const& source_position_output) { |
| 222 source_position_output_ = source_position_output; |
| 223 } |
| 224 |
221 void DeleteGraphZone() { | 225 void DeleteGraphZone() { |
222 if (graph_zone_ == nullptr) return; | 226 if (graph_zone_ == nullptr) return; |
223 graph_zone_scope_.Destroy(); | 227 graph_zone_scope_.Destroy(); |
224 graph_zone_ = nullptr; | 228 graph_zone_ = nullptr; |
225 graph_ = nullptr; | 229 graph_ = nullptr; |
226 source_positions_ = nullptr; | 230 source_positions_ = nullptr; |
227 loop_assignment_ = nullptr; | 231 loop_assignment_ = nullptr; |
228 type_hint_analysis_ = nullptr; | 232 type_hint_analysis_ = nullptr; |
229 simplified_ = nullptr; | 233 simplified_ = nullptr; |
230 machine_ = nullptr; | 234 machine_ = nullptr; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 void InitializeRegisterAllocationData(const RegisterConfiguration* config, | 280 void InitializeRegisterAllocationData(const RegisterConfiguration* config, |
277 CallDescriptor* descriptor, | 281 CallDescriptor* descriptor, |
278 const char* debug_name) { | 282 const char* debug_name) { |
279 DCHECK(register_allocation_data_ == nullptr); | 283 DCHECK(register_allocation_data_ == nullptr); |
280 register_allocation_data_ = new (register_allocation_zone()) | 284 register_allocation_data_ = new (register_allocation_zone()) |
281 RegisterAllocationData(config, register_allocation_zone(), frame(), | 285 RegisterAllocationData(config, register_allocation_zone(), frame(), |
282 sequence(), debug_name); | 286 sequence(), debug_name); |
283 } | 287 } |
284 | 288 |
285 private: | 289 private: |
286 Isolate* isolate_; | 290 Isolate* const isolate_; |
287 CompilationInfo* info_; | 291 CompilationInfo* const info_; |
288 Zone* outer_zone_ = nullptr; | 292 Zone* outer_zone_ = nullptr; |
289 ZonePool* const zone_pool_; | 293 ZonePool* const zone_pool_; |
290 PipelineStatistics* pipeline_statistics_ = nullptr; | 294 PipelineStatistics* pipeline_statistics_; |
291 bool compilation_failed_ = false; | 295 bool compilation_failed_ = false; |
292 Handle<Code> code_; | 296 Handle<Code> code_ = Handle<Code>::null(); |
293 BasicBlockProfiler::Data* profiler_data_ = nullptr; | |
294 std::ostringstream source_position_output_; | |
295 | 297 |
296 // All objects in the following group of fields are allocated in graph_zone_. | 298 // All objects in the following group of fields are allocated in graph_zone_. |
297 // They are all set to nullptr when the graph_zone_ is destroyed. | 299 // They are all set to nullptr when the graph_zone_ is destroyed. |
298 ZonePool::Scope graph_zone_scope_; | 300 ZonePool::Scope graph_zone_scope_; |
299 Zone* graph_zone_ = nullptr; | 301 Zone* graph_zone_ = nullptr; |
300 Graph* graph_ = nullptr; | 302 Graph* graph_ = nullptr; |
301 SourcePositionTable* source_positions_ = nullptr; | 303 SourcePositionTable* source_positions_ = nullptr; |
302 LoopAssignmentAnalysis* loop_assignment_ = nullptr; | 304 LoopAssignmentAnalysis* loop_assignment_ = nullptr; |
303 TypeHintAnalysis* type_hint_analysis_ = nullptr; | 305 TypeHintAnalysis* type_hint_analysis_ = nullptr; |
304 SimplifiedOperatorBuilder* simplified_ = nullptr; | 306 SimplifiedOperatorBuilder* simplified_ = nullptr; |
(...skipping 12 matching lines...) Expand all Loading... |
317 InstructionSequence* sequence_ = nullptr; | 319 InstructionSequence* sequence_ = nullptr; |
318 Frame* frame_ = nullptr; | 320 Frame* frame_ = nullptr; |
319 | 321 |
320 // All objects in the following group of fields are allocated in | 322 // All objects in the following group of fields are allocated in |
321 // register_allocation_zone_. They are all set to nullptr when the zone is | 323 // register_allocation_zone_. They are all set to nullptr when the zone is |
322 // destroyed. | 324 // destroyed. |
323 ZonePool::Scope register_allocation_zone_scope_; | 325 ZonePool::Scope register_allocation_zone_scope_; |
324 Zone* register_allocation_zone_; | 326 Zone* register_allocation_zone_; |
325 RegisterAllocationData* register_allocation_data_ = nullptr; | 327 RegisterAllocationData* register_allocation_data_ = nullptr; |
326 | 328 |
| 329 // Basic block profiling support. |
| 330 BasicBlockProfiler::Data* profiler_data_ = nullptr; |
| 331 |
| 332 // Source position output for --trace-turbo. |
| 333 std::string source_position_output_; |
| 334 |
327 int CalculateFixedFrameSize(CallDescriptor* descriptor) { | 335 int CalculateFixedFrameSize(CallDescriptor* descriptor) { |
328 if (descriptor->IsJSFunctionCall()) { | 336 if (descriptor->IsJSFunctionCall()) { |
329 return StandardFrameConstants::kFixedSlotCount; | 337 return StandardFrameConstants::kFixedSlotCount; |
330 } | 338 } |
331 return descriptor->IsCFunctionCall() | 339 return descriptor->IsCFunctionCall() |
332 ? (CommonFrameConstants::kFixedSlotCountAboveFp + | 340 ? (CommonFrameConstants::kFixedSlotCountAboveFp + |
333 CommonFrameConstants::kCPSlotCount) | 341 CommonFrameConstants::kCPSlotCount) |
334 : TypedFrameConstants::kFixedSlotCount; | 342 : TypedFrameConstants::kFixedSlotCount; |
335 } | 343 } |
336 | 344 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 phase_name), | 460 phase_name), |
453 zone_scope_(data->zone_pool()) {} | 461 zone_scope_(data->zone_pool()) {} |
454 | 462 |
455 Zone* zone() { return zone_scope_.zone(); } | 463 Zone* zone() { return zone_scope_.zone(); } |
456 | 464 |
457 private: | 465 private: |
458 PhaseScope phase_scope_; | 466 PhaseScope phase_scope_; |
459 ZonePool::Scope zone_scope_; | 467 ZonePool::Scope zone_scope_; |
460 }; | 468 }; |
461 | 469 |
462 class PipelineCompilationJob : public OptimizedCompileJob { | 470 PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info, |
| 471 ZonePool* zone_pool) { |
| 472 if (!FLAG_turbo_stats) return nullptr; |
| 473 |
| 474 PipelineStatistics* pipeline_statistics = |
| 475 new PipelineStatistics(info, zone_pool); |
| 476 pipeline_statistics->BeginPhaseKind("initializing"); |
| 477 |
| 478 FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "w+"); |
| 479 if (json_file != nullptr) { |
| 480 OFStream json_of(json_file); |
| 481 Handle<Script> script = info->script(); |
| 482 base::SmartArrayPointer<char> function_name = info->GetDebugName(); |
| 483 int pos = info->shared_info()->start_position(); |
| 484 json_of << "{\"function\":\"" << function_name.get() |
| 485 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; |
| 486 if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
| 487 DisallowHeapAllocation no_allocation; |
| 488 int start = info->shared_info()->start_position(); |
| 489 int len = info->shared_info()->end_position() - start; |
| 490 String::SubStringRange source(String::cast(script->source()), start, len); |
| 491 for (const auto& c : source) { |
| 492 json_of << AsEscapedUC16ForJSON(c); |
| 493 } |
| 494 } |
| 495 json_of << "\",\n\"phases\":["; |
| 496 fclose(json_file); |
| 497 } |
| 498 |
| 499 return pipeline_statistics; |
| 500 } |
| 501 |
| 502 class PipelineCompilationJob final : public OptimizedCompileJob { |
463 public: | 503 public: |
464 explicit PipelineCompilationJob(CompilationInfo* info) | 504 explicit PipelineCompilationJob(CompilationInfo* info) |
465 : OptimizedCompileJob(info, "TurboFan") {} | 505 : OptimizedCompileJob(info, "TurboFan"), |
| 506 zone_pool_(info->isolate()->allocator()), |
| 507 pipeline_statistics_(CreatePipelineStatistics(info, &zone_pool_)), |
| 508 data_(&zone_pool_, info, pipeline_statistics_.get()), |
| 509 pipeline_(&data_), |
| 510 linkage_(Linkage::ComputeIncoming(info->zone(), info)) {} |
466 | 511 |
467 protected: | 512 protected: |
468 virtual Status CreateGraphImpl(); | 513 Status CreateGraphImpl() final; |
469 virtual Status OptimizeGraphImpl(); | 514 Status OptimizeGraphImpl() final; |
470 virtual Status GenerateCodeImpl(); | 515 Status GenerateCodeImpl() final; |
| 516 |
| 517 private: |
| 518 ZonePool zone_pool_; |
| 519 base::SmartPointer<PipelineStatistics> pipeline_statistics_; |
| 520 PipelineData data_; |
| 521 Pipeline pipeline_; |
| 522 Linkage linkage_; |
471 }; | 523 }; |
472 | 524 |
473 PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { | 525 PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { |
474 if (info()->shared_info()->asm_function()) { | 526 if (info()->shared_info()->asm_function()) { |
475 if (info()->osr_frame()) info()->MarkAsFrameSpecializing(); | 527 if (info()->osr_frame()) info()->MarkAsFrameSpecializing(); |
476 info()->MarkAsFunctionContextSpecializing(); | 528 info()->MarkAsFunctionContextSpecializing(); |
477 } else { | 529 } else { |
478 if (!FLAG_always_opt) { | 530 if (!FLAG_always_opt) { |
479 info()->MarkAsBailoutOnUninitialized(); | 531 info()->MarkAsBailoutOnUninitialized(); |
480 } | 532 } |
481 if (FLAG_native_context_specialization) { | 533 if (FLAG_native_context_specialization) { |
482 info()->MarkAsNativeContextSpecializing(); | 534 info()->MarkAsNativeContextSpecializing(); |
483 } | 535 } |
484 } | 536 } |
485 if (!info()->shared_info()->asm_function() || FLAG_turbo_asm_deoptimization) { | 537 if (!info()->shared_info()->asm_function() || FLAG_turbo_asm_deoptimization) { |
486 info()->MarkAsDeoptimizationEnabled(); | 538 info()->MarkAsDeoptimizationEnabled(); |
487 } | 539 } |
488 if (!info()->shared_info()->HasBytecodeArray()) { | 540 if (!info()->shared_info()->HasBytecodeArray()) { |
489 if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED; | 541 if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED; |
490 } | 542 } |
491 | 543 |
492 Pipeline pipeline(info()); | 544 if (!pipeline_.CreateGraph()) { |
493 pipeline.GenerateCode(); | 545 if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. |
494 if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. | 546 return AbortOptimization(kGraphBuildingFailed); |
495 if (info()->code().is_null()) return AbortOptimization(kGraphBuildingFailed); | 547 } |
496 | 548 |
497 return SUCCEEDED; | 549 return SUCCEEDED; |
498 } | 550 } |
499 | 551 |
500 PipelineCompilationJob::Status PipelineCompilationJob::OptimizeGraphImpl() { | 552 PipelineCompilationJob::Status PipelineCompilationJob::OptimizeGraphImpl() { |
501 // TODO(turbofan): Currently everything is done in the first phase. | 553 if (!pipeline_.OptimizeGraph(&linkage_)) return FAILED; |
502 DCHECK(!info()->code().is_null()); | |
503 return SUCCEEDED; | 554 return SUCCEEDED; |
504 } | 555 } |
505 | 556 |
506 PipelineCompilationJob::Status PipelineCompilationJob::GenerateCodeImpl() { | 557 PipelineCompilationJob::Status PipelineCompilationJob::GenerateCodeImpl() { |
507 // TODO(turbofan): Currently everything is done in the first phase. | 558 Handle<Code> code = pipeline_.GenerateCode(&linkage_); |
508 DCHECK(!info()->code().is_null()); | 559 if (code.is_null()) { |
509 info()->dependencies()->Commit(info()->code()); | 560 if (info()->bailout_reason() == kNoReason) { |
| 561 return AbortOptimization(kCodeGenerationFailed); |
| 562 } |
| 563 return BAILED_OUT; |
| 564 } |
| 565 info()->dependencies()->Commit(code); |
| 566 info()->SetCode(code); |
510 if (info()->is_deoptimization_enabled()) { | 567 if (info()->is_deoptimization_enabled()) { |
511 info()->context()->native_context()->AddOptimizedCode(*info()->code()); | 568 info()->context()->native_context()->AddOptimizedCode(*code); |
512 RegisterWeakObjectsInOptimizedCode(info()->code()); | 569 RegisterWeakObjectsInOptimizedCode(code); |
513 } | 570 } |
514 return SUCCEEDED; | 571 return SUCCEEDED; |
515 } | 572 } |
516 | 573 |
| 574 class PipelineWasmCompilationJob final : public OptimizedCompileJob { |
| 575 public: |
| 576 explicit PipelineWasmCompilationJob(CompilationInfo* info, Graph* graph, |
| 577 CallDescriptor* descriptor, |
| 578 SourcePositionTable* source_positions) |
| 579 : OptimizedCompileJob(info, "TurboFan"), |
| 580 zone_pool_(info->isolate()->allocator()), |
| 581 data_(&zone_pool_, info, graph, source_positions), |
| 582 pipeline_(&data_), |
| 583 linkage_(descriptor) {} |
| 584 |
| 585 protected: |
| 586 Status CreateGraphImpl() final; |
| 587 Status OptimizeGraphImpl() final; |
| 588 Status GenerateCodeImpl() final; |
| 589 |
| 590 private: |
| 591 ZonePool zone_pool_; |
| 592 PipelineData data_; |
| 593 Pipeline pipeline_; |
| 594 Linkage linkage_; |
| 595 }; |
| 596 |
| 597 PipelineWasmCompilationJob::Status |
| 598 PipelineWasmCompilationJob::CreateGraphImpl() { |
| 599 return SUCCEEDED; |
| 600 } |
| 601 |
| 602 PipelineWasmCompilationJob::Status |
| 603 PipelineWasmCompilationJob::OptimizeGraphImpl() { |
| 604 if (!pipeline_.ScheduleAndSelectInstructions(&linkage_)) return FAILED; |
| 605 return SUCCEEDED; |
| 606 } |
| 607 |
| 608 PipelineWasmCompilationJob::Status |
| 609 PipelineWasmCompilationJob::GenerateCodeImpl() { |
| 610 pipeline_.GenerateCode(&linkage_); |
| 611 return SUCCEEDED; |
| 612 } |
| 613 |
517 } // namespace | 614 } // namespace |
518 | 615 |
519 | 616 |
520 template <typename Phase> | 617 template <typename Phase> |
521 void Pipeline::Run() { | 618 void Pipeline::Run() { |
522 PipelineRunScope scope(this->data_, Phase::phase_name()); | 619 PipelineRunScope scope(this->data_, Phase::phase_name()); |
523 Phase phase; | 620 Phase phase; |
524 phase.Run(this->data_, scope.zone()); | 621 phase.Run(this->data_, scope.zone()); |
525 } | 622 } |
526 | 623 |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 } | 1230 } |
1134 }; | 1231 }; |
1135 | 1232 |
1136 | 1233 |
1137 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { | 1234 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { |
1138 if (data_->pipeline_statistics() != nullptr) { | 1235 if (data_->pipeline_statistics() != nullptr) { |
1139 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); | 1236 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); |
1140 } | 1237 } |
1141 } | 1238 } |
1142 | 1239 |
| 1240 void Pipeline::EndPhaseKind() { |
| 1241 if (data_->pipeline_statistics() != nullptr) { |
| 1242 data_->pipeline_statistics()->EndPhaseKind(); |
| 1243 } |
| 1244 } |
1143 | 1245 |
1144 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { | 1246 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { |
1145 if (FLAG_trace_turbo) { | 1247 if (FLAG_trace_turbo) { |
1146 Run<PrintGraphPhase>(phase); | 1248 Run<PrintGraphPhase>(phase); |
1147 } | 1249 } |
1148 if (FLAG_turbo_verify) { | 1250 if (FLAG_turbo_verify) { |
1149 Run<VerifyGraphPhase>(untyped); | 1251 Run<VerifyGraphPhase>(untyped); |
1150 } | 1252 } |
1151 } | 1253 } |
1152 | 1254 |
1153 | 1255 bool Pipeline::CreateGraph() { |
1154 Handle<Code> Pipeline::GenerateCode() { | 1256 PipelineData* data = this->data_; |
1155 ZonePool zone_pool(isolate()->allocator()); | |
1156 base::SmartPointer<PipelineStatistics> pipeline_statistics; | |
1157 | |
1158 if (FLAG_turbo_stats) { | |
1159 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); | |
1160 pipeline_statistics->BeginPhaseKind("initializing"); | |
1161 } | |
1162 | |
1163 if (FLAG_trace_turbo) { | |
1164 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "w+"); | |
1165 if (json_file != nullptr) { | |
1166 OFStream json_of(json_file); | |
1167 Handle<Script> script = info()->script(); | |
1168 base::SmartArrayPointer<char> function_name = info()->GetDebugName(); | |
1169 int pos = info()->shared_info()->start_position(); | |
1170 json_of << "{\"function\":\"" << function_name.get() | |
1171 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; | |
1172 if (!script->IsUndefined() && !script->source()->IsUndefined()) { | |
1173 DisallowHeapAllocation no_allocation; | |
1174 int start = info()->shared_info()->start_position(); | |
1175 int len = info()->shared_info()->end_position() - start; | |
1176 String::SubStringRange source(String::cast(script->source()), start, | |
1177 len); | |
1178 for (const auto& c : source) { | |
1179 json_of << AsEscapedUC16ForJSON(c); | |
1180 } | |
1181 } | |
1182 json_of << "\",\n\"phases\":["; | |
1183 fclose(json_file); | |
1184 } | |
1185 } | |
1186 | |
1187 PipelineData data(&zone_pool, info(), pipeline_statistics.get()); | |
1188 this->data_ = &data; | |
1189 | 1257 |
1190 BeginPhaseKind("graph creation"); | 1258 BeginPhaseKind("graph creation"); |
1191 | 1259 |
1192 if (FLAG_trace_turbo) { | 1260 if (FLAG_trace_turbo) { |
1193 OFStream os(stdout); | 1261 OFStream os(stdout); |
1194 os << "---------------------------------------------------\n" | 1262 os << "---------------------------------------------------\n" |
1195 << "Begin compiling method " << info()->GetDebugName().get() | 1263 << "Begin compiling method " << info()->GetDebugName().get() |
1196 << " using Turbofan" << std::endl; | 1264 << " using Turbofan" << std::endl; |
1197 TurboCfgFile tcf(isolate()); | 1265 TurboCfgFile tcf(isolate()); |
1198 tcf << AsC1VCompilation(info()); | 1266 tcf << AsC1VCompilation(info()); |
1199 } | 1267 } |
1200 | 1268 |
1201 data.source_positions()->AddDecorator(); | 1269 data->source_positions()->AddDecorator(); |
1202 | 1270 |
1203 if (FLAG_loop_assignment_analysis) { | 1271 if (FLAG_loop_assignment_analysis) { |
1204 Run<LoopAssignmentAnalysisPhase>(); | 1272 Run<LoopAssignmentAnalysisPhase>(); |
1205 } | 1273 } |
1206 | 1274 |
1207 Run<TypeHintAnalysisPhase>(); | 1275 Run<TypeHintAnalysisPhase>(); |
1208 | 1276 |
1209 Run<GraphBuilderPhase>(); | 1277 Run<GraphBuilderPhase>(); |
1210 if (data.compilation_failed()) return Handle<Code>::null(); | 1278 if (data->compilation_failed()) { |
| 1279 EndPhaseKind(); |
| 1280 return false; |
| 1281 } |
1211 RunPrintAndVerify("Initial untyped", true); | 1282 RunPrintAndVerify("Initial untyped", true); |
1212 | 1283 |
1213 // Perform OSR deconstruction. | 1284 // Perform OSR deconstruction. |
1214 if (info()->is_osr()) { | 1285 if (info()->is_osr()) { |
1215 Run<OsrDeconstructionPhase>(); | 1286 Run<OsrDeconstructionPhase>(); |
1216 RunPrintAndVerify("OSR deconstruction", true); | 1287 RunPrintAndVerify("OSR deconstruction", true); |
1217 } | 1288 } |
1218 | 1289 |
1219 // Perform function context specialization and inlining (if enabled). | 1290 // Perform function context specialization and inlining (if enabled). |
1220 Run<InliningPhase>(); | 1291 Run<InliningPhase>(); |
1221 RunPrintAndVerify("Inlined", true); | 1292 RunPrintAndVerify("Inlined", true); |
1222 | 1293 |
1223 // Remove dead->live edges from the graph. | 1294 // Remove dead->live edges from the graph. |
1224 Run<EarlyGraphTrimmingPhase>(); | 1295 Run<EarlyGraphTrimmingPhase>(); |
1225 RunPrintAndVerify("Early trimmed", true); | 1296 RunPrintAndVerify("Early trimmed", true); |
1226 | 1297 |
1227 if (FLAG_print_turbo_replay) { | 1298 if (FLAG_print_turbo_replay) { |
1228 // Print a replay of the initial graph. | 1299 // Print a replay of the initial graph. |
1229 GraphReplayPrinter::PrintReplay(data.graph()); | 1300 GraphReplayPrinter::PrintReplay(data->graph()); |
1230 } | 1301 } |
1231 | 1302 |
1232 // Type the graph. | 1303 // Type the graph. |
1233 base::SmartPointer<Typer> typer; | 1304 base::SmartPointer<Typer> typer; |
1234 typer.Reset(new Typer(isolate(), data.graph(), | 1305 typer.Reset(new Typer(isolate(), data->graph(), |
1235 info()->is_deoptimization_enabled() | 1306 info()->is_deoptimization_enabled() |
1236 ? Typer::kDeoptimizationEnabled | 1307 ? Typer::kDeoptimizationEnabled |
1237 : Typer::kNoFlags, | 1308 : Typer::kNoFlags, |
1238 info()->dependencies())); | 1309 info()->dependencies())); |
1239 Run<TyperPhase>(typer.get()); | 1310 Run<TyperPhase>(typer.get()); |
1240 RunPrintAndVerify("Typed"); | 1311 RunPrintAndVerify("Typed"); |
1241 | 1312 |
1242 BeginPhaseKind("lowering"); | 1313 BeginPhaseKind("lowering"); |
1243 | 1314 |
1244 // Lower JSOperators where we can determine types. | 1315 // Lower JSOperators where we can determine types. |
(...skipping 28 matching lines...) Expand all Loading... |
1273 if (FLAG_turbo_cf_optimization) { | 1344 if (FLAG_turbo_cf_optimization) { |
1274 Run<ControlFlowOptimizationPhase>(); | 1345 Run<ControlFlowOptimizationPhase>(); |
1275 RunPrintAndVerify("Control flow optimized"); | 1346 RunPrintAndVerify("Control flow optimized"); |
1276 } | 1347 } |
1277 | 1348 |
1278 // Lower changes that have been inserted before. | 1349 // Lower changes that have been inserted before. |
1279 Run<LateOptimizationPhase>(); | 1350 Run<LateOptimizationPhase>(); |
1280 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1351 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1281 RunPrintAndVerify("Late optimized", true); | 1352 RunPrintAndVerify("Late optimized", true); |
1282 | 1353 |
| 1354 // Kill the Typer and thereby uninstall the decorator (if any). |
| 1355 typer.Reset(nullptr); |
| 1356 |
| 1357 EndPhaseKind(); |
| 1358 |
| 1359 return true; |
| 1360 } |
| 1361 |
| 1362 bool Pipeline::OptimizeGraph(Linkage* linkage) { |
| 1363 PipelineData* data = this->data_; |
| 1364 |
| 1365 BeginPhaseKind("block building"); |
| 1366 |
1283 Run<LateGraphTrimmingPhase>(); | 1367 Run<LateGraphTrimmingPhase>(); |
1284 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1368 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1285 RunPrintAndVerify("Late trimmed", true); | 1369 RunPrintAndVerify("Late trimmed", true); |
1286 | 1370 |
1287 BeginPhaseKind("block building"); | 1371 data->source_positions()->RemoveDecorator(); |
1288 | 1372 |
1289 data.source_positions()->RemoveDecorator(); | 1373 return ScheduleAndSelectInstructions(linkage); |
| 1374 } |
1290 | 1375 |
1291 // Kill the Typer and thereby uninstall the decorator (if any). | 1376 Handle<Code> Pipeline::GenerateCode() { |
1292 typer.Reset(nullptr); | 1377 PipelineData* data = this->data_; |
1293 | 1378 |
1294 return ScheduleAndGenerateCode( | 1379 Linkage linkage(Linkage::ComputeIncoming(data->instruction_zone(), info())); |
1295 Linkage::ComputeIncoming(data.instruction_zone(), info())); | 1380 |
| 1381 if (!CreateGraph()) return Handle<Code>::null(); |
| 1382 if (!OptimizeGraph(&linkage)) return Handle<Code>::null(); |
| 1383 return GenerateCode(&linkage); |
1296 } | 1384 } |
1297 | 1385 |
1298 Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, | 1386 Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, |
1299 CallDescriptor* call_descriptor, | 1387 CallDescriptor* call_descriptor, |
1300 Graph* graph, Schedule* schedule, | 1388 Graph* graph, Schedule* schedule, |
1301 Code::Flags flags, | 1389 Code::Flags flags, |
1302 const char* debug_name) { | 1390 const char* debug_name) { |
1303 CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags); | 1391 CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags); |
1304 | 1392 |
1305 // Construct a pipeline for scheduling and code generation. | 1393 // Construct a pipeline for scheduling and code generation. |
1306 ZonePool zone_pool(isolate->allocator()); | 1394 ZonePool zone_pool(isolate->allocator()); |
1307 PipelineData data(&zone_pool, &info, graph, schedule); | 1395 PipelineData data(&zone_pool, &info, graph, schedule); |
1308 base::SmartPointer<PipelineStatistics> pipeline_statistics; | 1396 base::SmartPointer<PipelineStatistics> pipeline_statistics; |
1309 if (FLAG_turbo_stats) { | 1397 if (FLAG_turbo_stats) { |
1310 pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool)); | 1398 pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool)); |
1311 pipeline_statistics->BeginPhaseKind("stub codegen"); | 1399 pipeline_statistics->BeginPhaseKind("stub codegen"); |
1312 } | 1400 } |
1313 | 1401 |
1314 Pipeline pipeline(&info); | 1402 Pipeline pipeline(&data); |
1315 pipeline.data_ = &data; | |
1316 DCHECK_NOT_NULL(data.schedule()); | 1403 DCHECK_NOT_NULL(data.schedule()); |
1317 | 1404 |
1318 if (FLAG_trace_turbo) { | 1405 if (FLAG_trace_turbo) { |
1319 FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+"); | 1406 FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+"); |
1320 if (json_file != nullptr) { | 1407 if (json_file != nullptr) { |
1321 OFStream json_of(json_file); | 1408 OFStream json_of(json_file); |
1322 json_of << "{\"function\":\"" << info.GetDebugName().get() | 1409 json_of << "{\"function\":\"" << info.GetDebugName().get() |
1323 << "\", \"source\":\"\",\n\"phases\":["; | 1410 << "\", \"source\":\"\",\n\"phases\":["; |
1324 fclose(json_file); | 1411 fclose(json_file); |
1325 } | 1412 } |
1326 pipeline.Run<PrintGraphPhase>("Machine"); | 1413 pipeline.Run<PrintGraphPhase>("Machine"); |
1327 } | 1414 } |
1328 | 1415 |
1329 pipeline.Run<VerifyGraphPhase>(false, true); | 1416 pipeline.Run<VerifyGraphPhase>(false, true); |
1330 return pipeline.ScheduleAndGenerateCode(call_descriptor); | 1417 return pipeline.ScheduleAndGenerateCode(call_descriptor); |
1331 } | 1418 } |
1332 | 1419 |
| 1420 // static |
| 1421 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info) { |
| 1422 ZonePool zone_pool(info->isolate()->allocator()); |
| 1423 base::SmartPointer<PipelineStatistics> pipeline_statistics( |
| 1424 CreatePipelineStatistics(info, &zone_pool)); |
| 1425 PipelineData data(&zone_pool, info, pipeline_statistics.get()); |
| 1426 Pipeline pipeline(&data); |
| 1427 return pipeline.GenerateCode(); |
| 1428 } |
1333 | 1429 |
| 1430 // static |
1334 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1431 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
1335 Graph* graph, | 1432 Graph* graph, |
1336 Schedule* schedule) { | 1433 Schedule* schedule) { |
1337 CallDescriptor* call_descriptor = | 1434 CallDescriptor* call_descriptor = |
1338 Linkage::ComputeIncoming(info->zone(), info); | 1435 Linkage::ComputeIncoming(info->zone(), info); |
1339 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); | 1436 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); |
1340 } | 1437 } |
1341 | 1438 |
1342 | 1439 // static |
1343 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1440 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
1344 CallDescriptor* call_descriptor, | 1441 CallDescriptor* call_descriptor, |
1345 Graph* graph, | 1442 Graph* graph, |
1346 Schedule* schedule) { | 1443 Schedule* schedule) { |
1347 // Construct a pipeline for scheduling and code generation. | 1444 // Construct a pipeline for scheduling and code generation. |
1348 ZonePool zone_pool(info->isolate()->allocator()); | 1445 ZonePool zone_pool(info->isolate()->allocator()); |
1349 PipelineData data(&zone_pool, info, graph, schedule); | 1446 PipelineData data(&zone_pool, info, graph, schedule); |
1350 base::SmartPointer<PipelineStatistics> pipeline_statistics; | 1447 base::SmartPointer<PipelineStatistics> pipeline_statistics; |
1351 if (FLAG_turbo_stats) { | 1448 if (FLAG_turbo_stats) { |
1352 pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool)); | 1449 pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool)); |
1353 pipeline_statistics->BeginPhaseKind("test codegen"); | 1450 pipeline_statistics->BeginPhaseKind("test codegen"); |
1354 } | 1451 } |
1355 | 1452 |
1356 Pipeline pipeline(info); | 1453 Pipeline pipeline(&data); |
1357 pipeline.data_ = &data; | |
1358 if (data.schedule() == nullptr) { | 1454 if (data.schedule() == nullptr) { |
1359 // TODO(rossberg): Should this really be untyped? | 1455 // TODO(rossberg): Should this really be untyped? |
1360 pipeline.RunPrintAndVerify("Machine", true); | 1456 pipeline.RunPrintAndVerify("Machine", true); |
1361 } | 1457 } |
1362 | 1458 |
1363 return pipeline.ScheduleAndGenerateCode(call_descriptor); | 1459 return pipeline.ScheduleAndGenerateCode(call_descriptor); |
1364 } | 1460 } |
1365 | 1461 |
1366 void Pipeline::InitializeWasmCompilation( | 1462 // static |
1367 Zone* pipeline_zone, ZonePool* zone_pool, Graph* graph, | 1463 OptimizedCompileJob* Pipeline::NewCompilationJob(CompilationInfo* info) { |
1368 SourcePositionTable* source_positions) { | 1464 return new PipelineCompilationJob(info); |
1369 data_ = new (pipeline_zone) | |
1370 PipelineData(zone_pool, info(), graph, source_positions); | |
1371 RunPrintAndVerify("Machine", true); | |
1372 } | 1465 } |
1373 | 1466 |
1374 bool Pipeline::ExecuteWasmCompilation(CallDescriptor* descriptor) { | 1467 // static |
1375 return ScheduleGraph(descriptor); | 1468 OptimizedCompileJob* Pipeline::NewWasmCompilationJob( |
1376 } | 1469 CompilationInfo* info, Graph* graph, CallDescriptor* descriptor, |
1377 | 1470 SourcePositionTable* source_positions) { |
1378 Handle<Code> Pipeline::FinalizeWasmCompilation(CallDescriptor* descriptor) { | 1471 return new PipelineWasmCompilationJob(info, graph, descriptor, |
1379 Handle<Code> result = GenerateCode(descriptor); | 1472 source_positions); |
1380 data_->Destroy(); | |
1381 return result; | |
1382 } | |
1383 | |
1384 OptimizedCompileJob* Pipeline::NewCompilationJob(CompilationInfo* info) { | |
1385 return new (info->zone()) PipelineCompilationJob(info); | |
1386 } | 1473 } |
1387 | 1474 |
1388 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, | 1475 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, |
1389 InstructionSequence* sequence, | 1476 InstructionSequence* sequence, |
1390 bool run_verifier) { | 1477 bool run_verifier) { |
1391 CompilationInfo info(ArrayVector("testing"), sequence->isolate(), | 1478 CompilationInfo info(ArrayVector("testing"), sequence->isolate(), |
1392 sequence->zone()); | 1479 sequence->zone()); |
1393 ZonePool zone_pool(sequence->isolate()->allocator()); | 1480 ZonePool zone_pool(sequence->isolate()->allocator()); |
1394 PipelineData data(&zone_pool, &info, sequence); | 1481 PipelineData data(&zone_pool, &info, sequence); |
1395 Pipeline pipeline(&info); | 1482 Pipeline pipeline(&data); |
1396 pipeline.data_ = &data; | |
1397 pipeline.data_->InitializeFrameData(nullptr); | 1483 pipeline.data_->InitializeFrameData(nullptr); |
1398 pipeline.AllocateRegisters(config, nullptr, run_verifier); | 1484 pipeline.AllocateRegisters(config, nullptr, run_verifier); |
1399 return !data.compilation_failed(); | 1485 return !data.compilation_failed(); |
1400 } | 1486 } |
1401 | 1487 |
1402 Handle<Code> Pipeline::ScheduleAndGenerateCode( | 1488 bool Pipeline::ScheduleAndSelectInstructions(Linkage* linkage) { |
1403 CallDescriptor* call_descriptor) { | 1489 CallDescriptor* call_descriptor = linkage->GetIncomingDescriptor(); |
1404 if (ScheduleGraph(call_descriptor)) { | 1490 PipelineData* data = this->data_; |
1405 return GenerateCode(call_descriptor); | |
1406 } else { | |
1407 return Handle<Code>::null(); | |
1408 } | |
1409 } | |
1410 | 1491 |
1411 bool Pipeline::ScheduleGraph(CallDescriptor* call_descriptor) { | |
1412 PipelineData* data = this->data_; | |
1413 DCHECK_NOT_NULL(data); | |
1414 DCHECK_NOT_NULL(data->graph()); | 1492 DCHECK_NOT_NULL(data->graph()); |
1415 | 1493 |
1416 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); | 1494 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); |
1417 TraceSchedule(data->info(), data->schedule()); | 1495 TraceSchedule(data->info(), data->schedule()); |
1418 | 1496 |
1419 if (FLAG_turbo_profiling) { | 1497 if (FLAG_turbo_profiling) { |
1420 data->set_profiler_data(BasicBlockInstrumentor::Instrument( | 1498 data->set_profiler_data(BasicBlockInstrumentor::Instrument( |
1421 info(), data->graph(), data->schedule())); | 1499 info(), data->graph(), data->schedule())); |
1422 } | 1500 } |
1423 | 1501 |
1424 data->InitializeInstructionSequence(call_descriptor); | 1502 data->InitializeInstructionSequence(call_descriptor); |
1425 | 1503 |
1426 data->InitializeFrameData(call_descriptor); | 1504 data->InitializeFrameData(call_descriptor); |
1427 // Select and schedule instructions covering the scheduled graph. | 1505 // Select and schedule instructions covering the scheduled graph. |
1428 Linkage linkage(call_descriptor); | 1506 Run<InstructionSelectionPhase>(linkage); |
1429 Run<InstructionSelectionPhase>(&linkage); | |
1430 | 1507 |
1431 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { | 1508 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { |
1432 TurboCfgFile tcf(isolate()); | 1509 TurboCfgFile tcf(isolate()); |
1433 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), | 1510 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), |
1434 data->sequence()); | 1511 data->sequence()); |
1435 } | 1512 } |
1436 | 1513 |
1437 if (FLAG_trace_turbo) { | 1514 if (FLAG_trace_turbo) { |
| 1515 std::ostringstream source_position_output; |
1438 // Output source position information before the graph is deleted. | 1516 // Output source position information before the graph is deleted. |
1439 data_->source_positions()->Print(*(data->source_position_output())); | 1517 data_->source_positions()->Print(source_position_output); |
| 1518 data_->set_source_position_output(source_position_output.str()); |
1440 } | 1519 } |
1441 | 1520 |
1442 data->DeleteGraphZone(); | 1521 data->DeleteGraphZone(); |
1443 | 1522 |
1444 BeginPhaseKind("register allocation"); | 1523 BeginPhaseKind("register allocation"); |
1445 | 1524 |
1446 bool run_verifier = FLAG_turbo_verify_allocation; | 1525 bool run_verifier = FLAG_turbo_verify_allocation; |
1447 | 1526 |
1448 // Allocate registers. | 1527 // Allocate registers. |
1449 AllocateRegisters( | 1528 AllocateRegisters( |
1450 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), | 1529 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), |
1451 call_descriptor, run_verifier); | 1530 call_descriptor, run_verifier); |
1452 Run<FrameElisionPhase>(); | 1531 Run<FrameElisionPhase>(); |
1453 if (data->compilation_failed()) { | 1532 if (data->compilation_failed()) { |
1454 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 1533 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
| 1534 EndPhaseKind(); |
1455 return false; | 1535 return false; |
1456 } | 1536 } |
1457 | 1537 |
1458 BeginPhaseKind("code generation"); | |
1459 // TODO(mtrofin): move this off to the register allocator. | 1538 // TODO(mtrofin): move this off to the register allocator. |
1460 bool generate_frame_at_start = | 1539 bool generate_frame_at_start = |
1461 data_->sequence()->instruction_blocks().front()->must_construct_frame(); | 1540 data_->sequence()->instruction_blocks().front()->must_construct_frame(); |
1462 // Optimimize jumps. | 1541 // Optimimize jumps. |
1463 if (FLAG_turbo_jt) { | 1542 if (FLAG_turbo_jt) { |
1464 Run<JumpThreadingPhase>(generate_frame_at_start); | 1543 Run<JumpThreadingPhase>(generate_frame_at_start); |
1465 } | 1544 } |
| 1545 |
| 1546 EndPhaseKind(); |
| 1547 |
1466 return true; | 1548 return true; |
1467 } | 1549 } |
1468 | 1550 |
1469 Handle<Code> Pipeline::GenerateCode(CallDescriptor* call_descriptor) { | 1551 Handle<Code> Pipeline::GenerateCode(Linkage* linkage) { |
1470 PipelineData* data = this->data_; | 1552 PipelineData* data = this->data_; |
1471 Linkage linkage(call_descriptor); | 1553 |
| 1554 BeginPhaseKind("code generation"); |
| 1555 |
1472 // Generate final machine code. | 1556 // Generate final machine code. |
1473 Run<GenerateCodePhase>(&linkage); | 1557 Run<GenerateCodePhase>(linkage); |
1474 | 1558 |
1475 Handle<Code> code = data->code(); | 1559 Handle<Code> code = data->code(); |
1476 if (data->profiler_data() != nullptr) { | 1560 if (data->profiler_data()) { |
1477 #if ENABLE_DISASSEMBLER | 1561 #if ENABLE_DISASSEMBLER |
1478 std::ostringstream os; | 1562 std::ostringstream os; |
1479 code->Disassemble(nullptr, os); | 1563 code->Disassemble(nullptr, os); |
1480 data->profiler_data()->SetCode(&os); | 1564 data->profiler_data()->SetCode(&os); |
1481 #endif | 1565 #endif |
1482 } | 1566 } |
1483 | 1567 |
1484 info()->SetCode(code); | 1568 info()->SetCode(code); |
1485 v8::internal::CodeGenerator::PrintCode(code, info()); | 1569 v8::internal::CodeGenerator::PrintCode(code, info()); |
1486 | 1570 |
1487 if (FLAG_trace_turbo) { | 1571 if (FLAG_trace_turbo) { |
1488 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+"); | 1572 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+"); |
1489 if (json_file != nullptr) { | 1573 if (json_file != nullptr) { |
1490 OFStream json_of(json_file); | 1574 OFStream json_of(json_file); |
1491 json_of | 1575 json_of |
1492 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; | 1576 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; |
1493 #if ENABLE_DISASSEMBLER | 1577 #if ENABLE_DISASSEMBLER |
1494 std::stringstream disassembly_stream; | 1578 std::stringstream disassembly_stream; |
1495 code->Disassemble(nullptr, disassembly_stream); | 1579 code->Disassemble(nullptr, disassembly_stream); |
1496 std::string disassembly_string(disassembly_stream.str()); | 1580 std::string disassembly_string(disassembly_stream.str()); |
1497 for (const auto& c : disassembly_string) { | 1581 for (const auto& c : disassembly_string) { |
1498 json_of << AsEscapedUC16ForJSON(c); | 1582 json_of << AsEscapedUC16ForJSON(c); |
1499 } | 1583 } |
1500 #endif // ENABLE_DISASSEMBLER | 1584 #endif // ENABLE_DISASSEMBLER |
1501 json_of << "\"}\n],\n"; | 1585 json_of << "\"}\n],\n"; |
1502 json_of << "\"nodePositions\":"; | 1586 json_of << "\"nodePositions\":"; |
1503 json_of << data->source_position_output()->str(); | 1587 json_of << data->source_position_output(); |
1504 json_of << "}"; | 1588 json_of << "}"; |
1505 fclose(json_file); | 1589 fclose(json_file); |
1506 } | 1590 } |
1507 OFStream os(stdout); | 1591 OFStream os(stdout); |
1508 os << "---------------------------------------------------\n" | 1592 os << "---------------------------------------------------\n" |
1509 << "Finished compiling method " << info()->GetDebugName().get() | 1593 << "Finished compiling method " << info()->GetDebugName().get() |
1510 << " using Turbofan" << std::endl; | 1594 << " using Turbofan" << std::endl; |
1511 } | 1595 } |
| 1596 |
1512 return code; | 1597 return code; |
1513 } | 1598 } |
1514 | 1599 |
| 1600 Handle<Code> Pipeline::ScheduleAndGenerateCode( |
| 1601 CallDescriptor* call_descriptor) { |
| 1602 Linkage linkage(call_descriptor); |
| 1603 |
| 1604 // Schedule the graph, perform instruction selection and register allocation. |
| 1605 if (!ScheduleAndSelectInstructions(&linkage)) return Handle<Code>(); |
| 1606 |
| 1607 // Generate the final machine code. |
| 1608 return GenerateCode(&linkage); |
| 1609 } |
| 1610 |
1515 void Pipeline::AllocateRegisters(const RegisterConfiguration* config, | 1611 void Pipeline::AllocateRegisters(const RegisterConfiguration* config, |
1516 CallDescriptor* descriptor, | 1612 CallDescriptor* descriptor, |
1517 bool run_verifier) { | 1613 bool run_verifier) { |
1518 PipelineData* data = this->data_; | 1614 PipelineData* data = this->data_; |
1519 // Don't track usage for this zone in compiler stats. | 1615 // Don't track usage for this zone in compiler stats. |
1520 base::SmartPointer<Zone> verifier_zone; | 1616 base::SmartPointer<Zone> verifier_zone; |
1521 RegisterAllocatorVerifier* verifier = nullptr; | 1617 RegisterAllocatorVerifier* verifier = nullptr; |
1522 if (run_verifier) { | 1618 if (run_verifier) { |
1523 verifier_zone.Reset(new Zone(isolate()->allocator())); | 1619 verifier_zone.Reset(new Zone(isolate()->allocator())); |
1524 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( | 1620 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 | 1692 |
1597 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { | 1693 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { |
1598 TurboCfgFile tcf(data->isolate()); | 1694 TurboCfgFile tcf(data->isolate()); |
1599 tcf << AsC1VRegisterAllocationData("CodeGen", | 1695 tcf << AsC1VRegisterAllocationData("CodeGen", |
1600 data->register_allocation_data()); | 1696 data->register_allocation_data()); |
1601 } | 1697 } |
1602 | 1698 |
1603 data->DeleteRegisterAllocationZone(); | 1699 data->DeleteRegisterAllocationZone(); |
1604 } | 1700 } |
1605 | 1701 |
| 1702 CompilationInfo* Pipeline::info() const { return data_->info(); } |
| 1703 |
1606 Isolate* Pipeline::isolate() const { return info()->isolate(); } | 1704 Isolate* Pipeline::isolate() const { return info()->isolate(); } |
1607 | 1705 |
1608 } // namespace compiler | 1706 } // namespace compiler |
1609 } // namespace internal | 1707 } // namespace internal |
1610 } // namespace v8 | 1708 } // namespace v8 |
OLD | NEW |