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

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

Powered by Google App Engine
This is Rietveld 408576698