Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: src/compiler/pipeline.cc

Issue 1179393008: [turbofan] Enable concurrent (re)compilation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Redo the PipelineData cleanup. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698