OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/pipeline.h" | 5 #include "src/compiler/pipeline.h" |
6 | 6 |
7 #include <fstream> // NOLINT(readability/streams) | 7 #include <fstream> // NOLINT(readability/streams) |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "src/base/adapters.h" | 10 #include "src/base/adapters.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 #include "src/compiler/verifier.h" | 51 #include "src/compiler/verifier.h" |
52 #include "src/compiler/zone-pool.h" | 52 #include "src/compiler/zone-pool.h" |
53 #include "src/ostreams.h" | 53 #include "src/ostreams.h" |
54 #include "src/type-info.h" | 54 #include "src/type-info.h" |
55 #include "src/utils.h" | 55 #include "src/utils.h" |
56 | 56 |
57 namespace v8 { | 57 namespace v8 { |
58 namespace internal { | 58 namespace internal { |
59 namespace compiler { | 59 namespace compiler { |
60 | 60 |
61 class PipelineData { | 61 namespace { |
| 62 |
| 63 PipelineStatistics* NewPipelineStatistics(CompilationInfo* const info, |
| 64 ZonePool* const zone_pool) { |
| 65 if (FLAG_turbo_stats) { |
| 66 PipelineStatistics* pipeline_statistics = |
| 67 new PipelineStatistics(info, zone_pool); |
| 68 pipeline_statistics->BeginPhaseKind("initializing"); |
| 69 return pipeline_statistics; |
| 70 } |
| 71 return nullptr; |
| 72 } |
| 73 |
| 74 } // namespace |
| 75 |
| 76 |
| 77 class PipelineData final { |
62 public: | 78 public: |
63 // For main entry point. | 79 // For main entry point. |
64 PipelineData(ZonePool* zone_pool, CompilationInfo* info, | 80 explicit PipelineData(CompilationInfo* info) |
65 PipelineStatistics* pipeline_statistics) | |
66 : isolate_(info->isolate()), | 81 : isolate_(info->isolate()), |
67 info_(info), | 82 info_(info), |
68 outer_zone_(info_->zone()), | 83 outer_zone_(info_->zone()), |
69 zone_pool_(zone_pool), | 84 pipeline_statistics_(NewPipelineStatistics(info, zone_pool())), |
70 pipeline_statistics_(pipeline_statistics), | |
71 compilation_failed_(false), | 85 compilation_failed_(false), |
72 code_(Handle<Code>::null()), | 86 code_(Handle<Code>::null()), |
73 graph_zone_scope_(zone_pool_), | 87 graph_zone_scope_(&zone_pool_), |
74 graph_zone_(graph_zone_scope_.zone()), | 88 graph_zone_(graph_zone_scope_.zone()), |
75 graph_(nullptr), | 89 graph_(nullptr), |
76 loop_assignment_(nullptr), | 90 loop_assignment_(nullptr), |
77 machine_(nullptr), | 91 machine_(nullptr), |
78 common_(nullptr), | 92 common_(nullptr), |
79 javascript_(nullptr), | 93 javascript_(nullptr), |
80 jsgraph_(nullptr), | 94 jsgraph_(nullptr), |
81 js_type_feedback_(nullptr), | 95 js_type_feedback_(nullptr), |
82 schedule_(nullptr), | 96 schedule_(nullptr), |
83 instruction_zone_scope_(zone_pool_), | 97 linkage_(nullptr), |
| 98 profiler_data_(nullptr), |
| 99 instruction_zone_scope_(&zone_pool_), |
84 instruction_zone_(instruction_zone_scope_.zone()), | 100 instruction_zone_(instruction_zone_scope_.zone()), |
85 sequence_(nullptr), | 101 sequence_(nullptr), |
86 frame_(nullptr), | 102 frame_(nullptr), |
87 register_allocation_zone_scope_(zone_pool_), | 103 register_allocation_zone_scope_(&zone_pool_), |
88 register_allocation_zone_(register_allocation_zone_scope_.zone()), | 104 register_allocation_zone_(register_allocation_zone_scope_.zone()), |
89 register_allocation_data_(nullptr) { | 105 register_allocation_data_(nullptr) { |
90 PhaseScope scope(pipeline_statistics, "init pipeline data"); | 106 PhaseScope scope(pipeline_statistics(), "init pipeline data"); |
91 graph_ = new (graph_zone_) Graph(graph_zone_); | 107 graph_ = new (graph_zone_) Graph(graph_zone_); |
92 source_positions_.Reset(new SourcePositionTable(graph_)); | 108 source_positions_.Reset(new SourcePositionTable(graph_)); |
93 machine_ = new (graph_zone_) MachineOperatorBuilder( | 109 machine_ = new (graph_zone_) MachineOperatorBuilder( |
94 graph_zone_, kMachPtr, | 110 graph_zone_, kMachPtr, |
95 InstructionSelector::SupportedMachineOperatorFlags()); | 111 InstructionSelector::SupportedMachineOperatorFlags()); |
96 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); | 112 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_); |
97 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); | 113 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); |
98 jsgraph_ = new (graph_zone_) | 114 jsgraph_ = new (graph_zone_) |
99 JSGraph(isolate_, graph_, common_, javascript_, machine_); | 115 JSGraph(isolate_, graph_, common_, javascript_, machine_); |
100 } | 116 } |
101 | 117 |
102 // For machine graph testing entry point. | 118 // For machine graph testing entry point. |
103 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, | 119 PipelineData(CompilationInfo* info, Graph* graph, Schedule* schedule) |
104 Schedule* schedule) | |
105 : isolate_(info->isolate()), | 120 : isolate_(info->isolate()), |
106 info_(info), | 121 info_(info), |
107 outer_zone_(nullptr), | 122 outer_zone_(nullptr), |
108 zone_pool_(zone_pool), | |
109 pipeline_statistics_(nullptr), | 123 pipeline_statistics_(nullptr), |
110 compilation_failed_(false), | 124 compilation_failed_(false), |
111 code_(Handle<Code>::null()), | 125 code_(Handle<Code>::null()), |
112 graph_zone_scope_(zone_pool_), | 126 graph_zone_scope_(&zone_pool_), |
113 graph_zone_(nullptr), | 127 graph_zone_(nullptr), |
114 graph_(graph), | 128 graph_(graph), |
115 source_positions_(new SourcePositionTable(graph_)), | 129 source_positions_(new SourcePositionTable(graph_)), |
116 loop_assignment_(nullptr), | 130 loop_assignment_(nullptr), |
117 machine_(nullptr), | 131 machine_(nullptr), |
118 common_(nullptr), | 132 common_(nullptr), |
119 javascript_(nullptr), | 133 javascript_(nullptr), |
120 jsgraph_(nullptr), | 134 jsgraph_(nullptr), |
121 js_type_feedback_(nullptr), | 135 js_type_feedback_(nullptr), |
122 schedule_(schedule), | 136 schedule_(schedule), |
123 instruction_zone_scope_(zone_pool_), | 137 linkage_(nullptr), |
| 138 profiler_data_(nullptr), |
| 139 instruction_zone_scope_(&zone_pool_), |
124 instruction_zone_(instruction_zone_scope_.zone()), | 140 instruction_zone_(instruction_zone_scope_.zone()), |
125 sequence_(nullptr), | 141 sequence_(nullptr), |
126 frame_(nullptr), | 142 frame_(nullptr), |
127 register_allocation_zone_scope_(zone_pool_), | 143 register_allocation_zone_scope_(&zone_pool_), |
128 register_allocation_zone_(register_allocation_zone_scope_.zone()), | 144 register_allocation_zone_(register_allocation_zone_scope_.zone()), |
129 register_allocation_data_(nullptr) {} | 145 register_allocation_data_(nullptr) {} |
130 | 146 |
131 // For register allocation testing entry point. | 147 // For register allocation testing entry point. |
132 PipelineData(ZonePool* zone_pool, CompilationInfo* info, | 148 PipelineData(CompilationInfo* info, InstructionSequence* sequence) |
133 InstructionSequence* sequence) | |
134 : isolate_(info->isolate()), | 149 : isolate_(info->isolate()), |
135 info_(info), | 150 info_(info), |
136 outer_zone_(nullptr), | 151 outer_zone_(nullptr), |
137 zone_pool_(zone_pool), | |
138 pipeline_statistics_(nullptr), | 152 pipeline_statistics_(nullptr), |
139 compilation_failed_(false), | 153 compilation_failed_(false), |
140 code_(Handle<Code>::null()), | 154 code_(Handle<Code>::null()), |
141 graph_zone_scope_(zone_pool_), | 155 graph_zone_scope_(&zone_pool_), |
142 graph_zone_(nullptr), | 156 graph_zone_(nullptr), |
143 graph_(nullptr), | 157 graph_(nullptr), |
144 loop_assignment_(nullptr), | 158 loop_assignment_(nullptr), |
145 machine_(nullptr), | 159 machine_(nullptr), |
146 common_(nullptr), | 160 common_(nullptr), |
147 javascript_(nullptr), | 161 javascript_(nullptr), |
148 jsgraph_(nullptr), | 162 jsgraph_(nullptr), |
149 js_type_feedback_(nullptr), | 163 js_type_feedback_(nullptr), |
150 schedule_(nullptr), | 164 schedule_(nullptr), |
151 instruction_zone_scope_(zone_pool_), | 165 linkage_(nullptr), |
| 166 profiler_data_(nullptr), |
| 167 instruction_zone_scope_(&zone_pool_), |
152 instruction_zone_(sequence->zone()), | 168 instruction_zone_(sequence->zone()), |
153 sequence_(sequence), | 169 sequence_(sequence), |
154 frame_(nullptr), | 170 frame_(nullptr), |
155 register_allocation_zone_scope_(zone_pool_), | 171 register_allocation_zone_scope_(&zone_pool_), |
156 register_allocation_zone_(register_allocation_zone_scope_.zone()), | 172 register_allocation_zone_(register_allocation_zone_scope_.zone()), |
157 register_allocation_data_(nullptr) {} | 173 register_allocation_data_(nullptr) {} |
158 | 174 |
159 ~PipelineData() { | 175 ~PipelineData() { |
160 DeleteRegisterAllocationZone(); | 176 DeleteRegisterAllocationZone(); |
161 DeleteInstructionZone(); | 177 DeleteInstructionZone(); |
162 DeleteGraphZone(); | 178 DeleteGraphZone(); |
163 } | 179 } |
164 | 180 |
165 Isolate* isolate() const { return isolate_; } | 181 Isolate* isolate() const { return isolate_; } |
166 CompilationInfo* info() const { return info_; } | 182 CompilationInfo* info() const { return info_; } |
167 ZonePool* zone_pool() const { return zone_pool_; } | 183 ZonePool* zone_pool() { return &zone_pool_; } |
168 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } | 184 PipelineStatistics* pipeline_statistics() const { |
| 185 return pipeline_statistics_.get(); |
| 186 } |
169 bool compilation_failed() const { return compilation_failed_; } | 187 bool compilation_failed() const { return compilation_failed_; } |
170 void set_compilation_failed() { compilation_failed_ = true; } | 188 void set_compilation_failed() { compilation_failed_ = true; } |
171 Handle<Code> code() { return code_; } | 189 Handle<Code> code() { return code_; } |
172 void set_code(Handle<Code> code) { | 190 void set_code(Handle<Code> code) { |
173 DCHECK(code_.is_null()); | 191 DCHECK(code_.is_null()); |
174 code_ = code; | 192 code_ = code; |
175 } | 193 } |
176 | 194 |
177 // RawMachineAssembler generally produces graphs which cannot be verified. | 195 // RawMachineAssembler generally produces graphs which cannot be verified. |
178 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } | 196 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } |
(...skipping 21 matching lines...) Expand all Loading... |
200 Schedule* schedule() const { return schedule_; } | 218 Schedule* schedule() const { return schedule_; } |
201 void set_schedule(Schedule* schedule) { | 219 void set_schedule(Schedule* schedule) { |
202 DCHECK(!schedule_); | 220 DCHECK(!schedule_); |
203 schedule_ = schedule; | 221 schedule_ = schedule; |
204 } | 222 } |
205 | 223 |
206 Zone* instruction_zone() const { return instruction_zone_; } | 224 Zone* instruction_zone() const { return instruction_zone_; } |
207 InstructionSequence* sequence() const { return sequence_; } | 225 InstructionSequence* sequence() const { return sequence_; } |
208 Frame* frame() const { return frame_; } | 226 Frame* frame() const { return frame_; } |
209 | 227 |
| 228 Linkage* linkage() const { return linkage_; } |
| 229 void set_linkage(Linkage* linkage) { linkage_ = linkage; } |
| 230 |
| 231 BasicBlockProfiler::Data* profiler_data() const { return profiler_data_; } |
| 232 |
210 Zone* register_allocation_zone() const { return register_allocation_zone_; } | 233 Zone* register_allocation_zone() const { return register_allocation_zone_; } |
211 RegisterAllocationData* register_allocation_data() const { | 234 RegisterAllocationData* register_allocation_data() const { |
212 return register_allocation_data_; | 235 return register_allocation_data_; |
213 } | 236 } |
214 | 237 |
215 void DeleteGraphZone() { | 238 void DeleteGraphZone() { |
216 // Destroy objects with destructors first. | 239 // Destroy objects with destructors first. |
217 source_positions_.Reset(nullptr); | 240 source_positions_.Reset(nullptr); |
218 if (graph_zone_ == nullptr) return; | 241 if (graph_zone_ == nullptr) return; |
219 // Destroy zone and clear pointers. | 242 // Destroy zone and clear pointers. |
(...skipping 19 matching lines...) Expand all Loading... |
239 | 262 |
240 void DeleteRegisterAllocationZone() { | 263 void DeleteRegisterAllocationZone() { |
241 if (register_allocation_zone_ == nullptr) return; | 264 if (register_allocation_zone_ == nullptr) return; |
242 register_allocation_zone_scope_.Destroy(); | 265 register_allocation_zone_scope_.Destroy(); |
243 register_allocation_zone_ = nullptr; | 266 register_allocation_zone_ = nullptr; |
244 register_allocation_data_ = nullptr; | 267 register_allocation_data_ = nullptr; |
245 } | 268 } |
246 | 269 |
247 void InitializeInstructionSequence() { | 270 void InitializeInstructionSequence() { |
248 DCHECK(sequence_ == nullptr); | 271 DCHECK(sequence_ == nullptr); |
| 272 if (FLAG_turbo_profiling) { |
| 273 profiler_data_ = |
| 274 BasicBlockInstrumentor::Instrument(info(), graph(), schedule()); |
| 275 } |
249 InstructionBlocks* instruction_blocks = | 276 InstructionBlocks* instruction_blocks = |
250 InstructionSequence::InstructionBlocksFor(instruction_zone(), | 277 InstructionSequence::InstructionBlocksFor(instruction_zone(), |
251 schedule()); | 278 schedule()); |
252 sequence_ = new (instruction_zone()) InstructionSequence( | 279 sequence_ = new (instruction_zone()) InstructionSequence( |
253 info()->isolate(), instruction_zone(), instruction_blocks); | 280 info()->isolate(), instruction_zone(), instruction_blocks); |
254 } | 281 } |
255 | 282 |
256 void InitializeRegisterAllocationData(const RegisterConfiguration* config, | 283 void InitializeRegisterAllocationData(const RegisterConfiguration* config, |
257 const char* debug_name) { | 284 const char* debug_name) { |
258 DCHECK(frame_ == nullptr); | 285 DCHECK(frame_ == nullptr); |
259 DCHECK(register_allocation_data_ == nullptr); | 286 DCHECK(register_allocation_data_ == nullptr); |
260 frame_ = new (instruction_zone()) Frame(); | 287 frame_ = new (instruction_zone()) Frame(); |
261 register_allocation_data_ = new (register_allocation_zone()) | 288 register_allocation_data_ = new (register_allocation_zone()) |
262 RegisterAllocationData(config, register_allocation_zone(), frame(), | 289 RegisterAllocationData(config, register_allocation_zone(), frame(), |
263 sequence(), debug_name); | 290 sequence(), debug_name); |
264 } | 291 } |
265 | 292 |
| 293 std::ostringstream& source_position_output() { |
| 294 return source_position_output_; |
| 295 } |
| 296 |
266 private: | 297 private: |
267 Isolate* isolate_; | 298 Isolate* isolate_; |
268 CompilationInfo* info_; | 299 CompilationInfo* info_; |
269 Zone* outer_zone_; | 300 Zone* outer_zone_; |
270 ZonePool* const zone_pool_; | 301 ZonePool zone_pool_; |
271 PipelineStatistics* pipeline_statistics_; | 302 SmartPointer<PipelineStatistics> pipeline_statistics_; |
272 bool compilation_failed_; | 303 bool compilation_failed_; |
273 Handle<Code> code_; | 304 Handle<Code> code_; |
274 | 305 |
275 // All objects in the following group of fields are allocated in graph_zone_. | 306 // All objects in the following group of fields are allocated in graph_zone_. |
276 // They are all set to NULL when the graph_zone_ is destroyed. | 307 // They are all set to NULL when the graph_zone_ is destroyed. |
277 ZonePool::Scope graph_zone_scope_; | 308 ZonePool::Scope graph_zone_scope_; |
278 Zone* graph_zone_; | 309 Zone* graph_zone_; |
279 Graph* graph_; | 310 Graph* graph_; |
280 // TODO(dcarney): make this into a ZoneObject. | 311 // TODO(dcarney): make this into a ZoneObject. |
281 SmartPointer<SourcePositionTable> source_positions_; | 312 SmartPointer<SourcePositionTable> source_positions_; |
282 LoopAssignmentAnalysis* loop_assignment_; | 313 LoopAssignmentAnalysis* loop_assignment_; |
283 MachineOperatorBuilder* machine_; | 314 MachineOperatorBuilder* machine_; |
284 CommonOperatorBuilder* common_; | 315 CommonOperatorBuilder* common_; |
285 JSOperatorBuilder* javascript_; | 316 JSOperatorBuilder* javascript_; |
286 JSGraph* jsgraph_; | 317 JSGraph* jsgraph_; |
287 JSTypeFeedbackTable* js_type_feedback_; | 318 JSTypeFeedbackTable* js_type_feedback_; |
288 Schedule* schedule_; | 319 Schedule* schedule_; |
| 320 Linkage* linkage_; |
| 321 BasicBlockProfiler::Data* profiler_data_; |
| 322 std::ostringstream source_position_output_; |
289 | 323 |
290 // All objects in the following group of fields are allocated in | 324 // All objects in the following group of fields are allocated in |
291 // instruction_zone_. They are all set to NULL when the instruction_zone_ is | 325 // instruction_zone_. They are all set to NULL when the instruction_zone_ is |
292 // destroyed. | 326 // destroyed. |
293 ZonePool::Scope instruction_zone_scope_; | 327 ZonePool::Scope instruction_zone_scope_; |
294 Zone* instruction_zone_; | 328 Zone* instruction_zone_; |
295 InstructionSequence* sequence_; | 329 InstructionSequence* sequence_; |
296 Frame* frame_; | 330 Frame* frame_; |
297 | 331 |
298 // All objects in the following group of fields are allocated in | 332 // All objects in the following group of fields are allocated in |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 Zone* zone() { return zone_scope_.zone(); } | 471 Zone* zone() { return zone_scope_.zone(); } |
438 | 472 |
439 private: | 473 private: |
440 PhaseScope phase_scope_; | 474 PhaseScope phase_scope_; |
441 ZonePool::Scope zone_scope_; | 475 ZonePool::Scope zone_scope_; |
442 }; | 476 }; |
443 | 477 |
444 } // namespace | 478 } // namespace |
445 | 479 |
446 | 480 |
| 481 Pipeline::Pipeline(CompilationInfo* info) : Pipeline(new PipelineData(info)) {} |
| 482 |
| 483 |
| 484 Pipeline::~Pipeline() { delete data_; } |
| 485 |
| 486 |
| 487 CompilationInfo* Pipeline::info() const { return data()->info(); } |
| 488 |
| 489 |
447 template <typename Phase> | 490 template <typename Phase> |
448 void Pipeline::Run() { | 491 void Pipeline::Run() { |
449 PipelineRunScope scope(this->data_, Phase::phase_name()); | 492 PipelineRunScope scope(data(), Phase::phase_name()); |
450 Phase phase; | 493 Phase phase; |
451 phase.Run(this->data_, scope.zone()); | 494 phase.Run(data(), scope.zone()); |
452 } | 495 } |
453 | 496 |
454 | 497 |
455 template <typename Phase, typename Arg0> | 498 template <typename Phase, typename Arg0> |
456 void Pipeline::Run(Arg0 arg_0) { | 499 void Pipeline::Run(Arg0 arg_0) { |
457 PipelineRunScope scope(this->data_, Phase::phase_name()); | 500 PipelineRunScope scope(data(), Phase::phase_name()); |
458 Phase phase; | 501 Phase phase; |
459 phase.Run(this->data_, scope.zone(), arg_0); | 502 phase.Run(data(), scope.zone(), arg_0); |
460 } | 503 } |
461 | 504 |
462 | 505 |
463 struct LoopAssignmentAnalysisPhase { | 506 struct LoopAssignmentAnalysisPhase { |
464 static const char* phase_name() { return "loop assignment analysis"; } | 507 static const char* phase_name() { return "loop assignment analysis"; } |
465 | 508 |
466 void Run(PipelineData* data, Zone* temp_zone) { | 509 void Run(PipelineData* data, Zone* temp_zone) { |
467 AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info()); | 510 AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info()); |
468 LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze(); | 511 LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze(); |
469 data->set_loop_assignment(loop_assignment); | 512 data->set_loop_assignment(loop_assignment); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 : Scheduler::kNoFlags); | 773 : Scheduler::kNoFlags); |
731 if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule); | 774 if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule); |
732 data->set_schedule(schedule); | 775 data->set_schedule(schedule); |
733 } | 776 } |
734 }; | 777 }; |
735 | 778 |
736 | 779 |
737 struct InstructionSelectionPhase { | 780 struct InstructionSelectionPhase { |
738 static const char* phase_name() { return "select instructions"; } | 781 static const char* phase_name() { return "select instructions"; } |
739 | 782 |
740 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { | 783 void Run(PipelineData* data, Zone* temp_zone) { |
741 InstructionSelector selector( | 784 InstructionSelector selector( |
742 temp_zone, data->graph()->NodeCount(), linkage, data->sequence(), | 785 temp_zone, data->graph()->NodeCount(), data->linkage(), |
743 data->schedule(), data->source_positions(), | 786 data->sequence(), data->schedule(), data->source_positions(), |
744 data->info()->is_source_positions_enabled() | 787 data->info()->is_source_positions_enabled() |
745 ? InstructionSelector::kAllSourcePositions | 788 ? InstructionSelector::kAllSourcePositions |
746 : InstructionSelector::kCallSourcePositions); | 789 : InstructionSelector::kCallSourcePositions); |
747 selector.SelectInstructions(); | 790 selector.SelectInstructions(); |
748 } | 791 } |
749 }; | 792 }; |
750 | 793 |
751 | 794 |
752 struct MeetRegisterConstraintsPhase { | 795 struct MeetRegisterConstraintsPhase { |
753 static const char* phase_name() { return "meet register constraints"; } | 796 static const char* phase_name() { return "meet register constraints"; } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence())) { | 933 if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence())) { |
891 JumpThreading::ApplyForwarding(result, data->sequence()); | 934 JumpThreading::ApplyForwarding(result, data->sequence()); |
892 } | 935 } |
893 } | 936 } |
894 }; | 937 }; |
895 | 938 |
896 | 939 |
897 struct GenerateCodePhase { | 940 struct GenerateCodePhase { |
898 static const char* phase_name() { return "generate code"; } | 941 static const char* phase_name() { return "generate code"; } |
899 | 942 |
900 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { | 943 void Run(PipelineData* data, Zone* temp_zone) { |
901 CodeGenerator generator(data->frame(), linkage, data->sequence(), | 944 CodeGenerator generator(data->frame(), data->linkage(), data->sequence(), |
902 data->info()); | 945 data->info()); |
903 data->set_code(generator.GenerateCode()); | 946 data->set_code(generator.GenerateCode()); |
904 } | 947 } |
905 }; | 948 }; |
906 | 949 |
907 | 950 |
908 struct PrintGraphPhase { | 951 struct PrintGraphPhase { |
909 static const char* phase_name() { return nullptr; } | 952 static const char* phase_name() { return nullptr; } |
910 | 953 |
911 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { | 954 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 }; | 992 }; |
950 | 993 |
951 | 994 |
952 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { | 995 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { |
953 if (data_->pipeline_statistics() != NULL) { | 996 if (data_->pipeline_statistics() != NULL) { |
954 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); | 997 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); |
955 } | 998 } |
956 } | 999 } |
957 | 1000 |
958 | 1001 |
| 1002 void Pipeline::EndPhaseKind() { |
| 1003 if (data_->pipeline_statistics() != NULL) { |
| 1004 data_->pipeline_statistics()->EndPhaseKind(); |
| 1005 } |
| 1006 } |
| 1007 |
| 1008 |
959 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { | 1009 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { |
960 if (FLAG_trace_turbo) { | 1010 if (FLAG_trace_turbo) { |
961 Run<PrintGraphPhase>(phase); | 1011 Run<PrintGraphPhase>(phase); |
962 } | 1012 } |
963 if (FLAG_turbo_verify) { | 1013 if (FLAG_turbo_verify) { |
964 Run<VerifyGraphPhase>(untyped); | 1014 Run<VerifyGraphPhase>(untyped); |
965 } | 1015 } |
966 } | 1016 } |
967 | 1017 |
968 | 1018 |
969 Handle<Code> Pipeline::GenerateCode() { | 1019 bool Pipeline::CreateGraph() { |
970 // TODO(mstarzinger): This is just a temporary hack to make TurboFan work, | 1020 // TODO(mstarzinger): This is just a temporary hack to make TurboFan work, |
971 // the correct solution is to restore the context register after invoking | 1021 // the correct solution is to restore the context register after invoking |
972 // builtins from full-codegen. | 1022 // builtins from full-codegen. |
973 Handle<SharedFunctionInfo> shared = info()->shared_info(); | 1023 Handle<SharedFunctionInfo> shared = info()->shared_info(); |
974 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { | 1024 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { |
975 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); | 1025 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); |
976 Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id); | 1026 Object* builtin = isolate()->js_builtins_object()->javascript_builtin(id); |
977 if (*info()->closure() == builtin) return Handle<Code>::null(); | 1027 if (*info()->closure() == builtin) return false; |
978 } | 1028 } |
979 | 1029 |
980 // TODO(dslomov): support turbo optimization of subclass constructors. | 1030 // TODO(dslomov): support turbo optimization of subclass constructors. |
981 if (IsSubclassConstructor(shared->kind())) { | 1031 if (IsSubclassConstructor(shared->kind())) { |
982 shared->DisableOptimization(kSuperReference); | 1032 shared->DisableOptimization(kSuperReference); |
983 return Handle<Code>::null(); | 1033 return false; |
984 } | |
985 | |
986 ZonePool zone_pool; | |
987 SmartPointer<PipelineStatistics> pipeline_statistics; | |
988 | |
989 if (FLAG_turbo_stats) { | |
990 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); | |
991 pipeline_statistics->BeginPhaseKind("initializing"); | |
992 } | 1034 } |
993 | 1035 |
994 if (FLAG_trace_turbo) { | 1036 if (FLAG_trace_turbo) { |
995 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "w+"); | 1037 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "w+"); |
996 if (json_file != nullptr) { | 1038 if (json_file != nullptr) { |
997 OFStream json_of(json_file); | 1039 OFStream json_of(json_file); |
998 Handle<Script> script = info()->script(); | 1040 Handle<Script> script = info()->script(); |
999 FunctionLiteral* function = info()->function(); | 1041 FunctionLiteral* function = info()->function(); |
1000 SmartArrayPointer<char> function_name = | 1042 SmartArrayPointer<char> function_name = |
1001 info()->shared_info()->DebugName()->ToCString(); | 1043 info()->shared_info()->DebugName()->ToCString(); |
1002 int pos = info()->shared_info()->start_position(); | 1044 int pos = info()->shared_info()->start_position(); |
1003 json_of << "{\"function\":\"" << function_name.get() | 1045 json_of << "{\"function\":\"" << function_name.get() |
1004 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; | 1046 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; |
1005 if (!script->IsUndefined() && !script->source()->IsUndefined()) { | 1047 if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
1006 DisallowHeapAllocation no_allocation; | 1048 DisallowHeapAllocation no_allocation; |
1007 int start = function->start_position(); | 1049 int start = function->start_position(); |
1008 int len = function->end_position() - start; | 1050 int len = function->end_position() - start; |
1009 String::SubStringRange source(String::cast(script->source()), start, | 1051 String::SubStringRange source(String::cast(script->source()), start, |
1010 len); | 1052 len); |
1011 for (const auto& c : source) { | 1053 for (const auto& c : source) { |
1012 json_of << AsEscapedUC16ForJSON(c); | 1054 json_of << AsEscapedUC16ForJSON(c); |
1013 } | 1055 } |
1014 } | 1056 } |
1015 json_of << "\",\n\"phases\":["; | 1057 json_of << "\",\n\"phases\":["; |
1016 fclose(json_file); | 1058 fclose(json_file); |
1017 } | 1059 } |
1018 } | 1060 } |
1019 | 1061 |
1020 PipelineData data(&zone_pool, info(), pipeline_statistics.get()); | |
1021 this->data_ = &data; | |
1022 | |
1023 if (info()->is_type_feedback_enabled()) { | 1062 if (info()->is_type_feedback_enabled()) { |
1024 data.set_js_type_feedback(new (data.graph_zone()) | 1063 data()->set_js_type_feedback(new (data()->graph_zone()) |
1025 JSTypeFeedbackTable(data.graph_zone())); | 1064 JSTypeFeedbackTable(data()->graph_zone())); |
1026 } | 1065 } |
1027 | 1066 |
1028 BeginPhaseKind("graph creation"); | 1067 BeginPhaseKind("graph creation"); |
1029 | 1068 |
1030 if (FLAG_trace_turbo) { | 1069 if (FLAG_trace_turbo) { |
1031 OFStream os(stdout); | 1070 OFStream os(stdout); |
1032 os << "---------------------------------------------------\n" | 1071 os << "---------------------------------------------------\n" |
1033 << "Begin compiling method " << GetDebugName(info()).get() | 1072 << "Begin compiling method " << GetDebugName(info()).get() |
1034 << " using Turbofan" << std::endl; | 1073 << " using Turbofan" << std::endl; |
1035 TurboCfgFile tcf(isolate()); | 1074 TurboCfgFile tcf(isolate()); |
1036 tcf << AsC1VCompilation(info()); | 1075 tcf << AsC1VCompilation(info()); |
1037 } | 1076 } |
1038 | 1077 |
1039 data.source_positions()->AddDecorator(); | 1078 data()->source_positions()->AddDecorator(); |
1040 | 1079 |
1041 if (FLAG_loop_assignment_analysis) { | 1080 if (FLAG_loop_assignment_analysis) { |
1042 Run<LoopAssignmentAnalysisPhase>(); | 1081 Run<LoopAssignmentAnalysisPhase>(); |
1043 } | 1082 } |
1044 | 1083 |
1045 Run<GraphBuilderPhase>(info()->is_context_specializing()); | 1084 Run<GraphBuilderPhase>(info()->is_context_specializing()); |
1046 if (data.compilation_failed()) return Handle<Code>::null(); | 1085 if (data()->compilation_failed()) return false; |
1047 RunPrintAndVerify("Initial untyped", true); | 1086 RunPrintAndVerify("Initial untyped", true); |
1048 | 1087 |
1049 Run<EarlyControlReductionPhase>(); | 1088 Run<EarlyControlReductionPhase>(); |
1050 RunPrintAndVerify("Early Control reduced", true); | 1089 RunPrintAndVerify("Early Control reduced", true); |
1051 | 1090 |
1052 if (info()->is_context_specializing()) { | 1091 if (info()->is_context_specializing()) { |
1053 // Specialize the code to the context as aggressively as possible. | 1092 // Specialize the code to the context as aggressively as possible. |
1054 Run<ContextSpecializerPhase>(); | 1093 Run<ContextSpecializerPhase>(); |
1055 RunPrintAndVerify("Context specialized", true); | 1094 RunPrintAndVerify("Context specialized", true); |
1056 } | 1095 } |
1057 | 1096 |
1058 Run<InliningPhase>(); | 1097 Run<InliningPhase>(); |
1059 RunPrintAndVerify("Inlined", true); | 1098 RunPrintAndVerify("Inlined", true); |
1060 | 1099 |
1061 Run<EarlyGraphTrimmingPhase>(); | 1100 Run<EarlyGraphTrimmingPhase>(); |
1062 RunPrintAndVerify("Early trimmed", true); | 1101 RunPrintAndVerify("Early trimmed", true); |
1063 | 1102 |
1064 if (FLAG_print_turbo_replay) { | 1103 if (FLAG_print_turbo_replay) { |
1065 // Print a replay of the initial graph. | 1104 // Print a replay of the initial graph. |
1066 GraphReplayPrinter::PrintReplay(data.graph()); | 1105 GraphReplayPrinter::PrintReplay(data()->graph()); |
1067 } | 1106 } |
1068 | 1107 |
1069 // Bailout here in case target architecture is not supported. | 1108 // Bailout here in case target architecture is not supported. |
1070 if (!SupportedTarget()) return Handle<Code>::null(); | 1109 if (!SupportedTarget()) return false; |
1071 | 1110 |
1072 SmartPointer<Typer> typer; | 1111 SmartPointer<Typer> typer; |
1073 if (info()->is_typing_enabled()) { | 1112 if (info()->is_typing_enabled()) { |
1074 // Type the graph. | 1113 // Type the graph. |
1075 typer.Reset(new Typer(isolate(), data.graph(), info()->context())); | 1114 typer.Reset(new Typer(isolate(), data()->graph(), info()->context())); |
1076 Run<TyperPhase>(typer.get()); | 1115 Run<TyperPhase>(typer.get()); |
1077 RunPrintAndVerify("Typed"); | 1116 RunPrintAndVerify("Typed"); |
1078 } | 1117 } |
1079 | 1118 |
1080 BeginPhaseKind("lowering"); | 1119 BeginPhaseKind("lowering"); |
1081 | 1120 |
1082 if (info()->is_typing_enabled()) { | 1121 if (info()->is_typing_enabled()) { |
1083 // Lower JSOperators where we can determine types. | 1122 // Lower JSOperators where we can determine types. |
1084 Run<TypedLoweringPhase>(); | 1123 Run<TypedLoweringPhase>(); |
1085 RunPrintAndVerify("Lowered typed"); | 1124 RunPrintAndVerify("Lowered typed"); |
(...skipping 26 matching lines...) Expand all Loading... |
1112 // Lower changes that have been inserted before. | 1151 // Lower changes that have been inserted before. |
1113 Run<ChangeLoweringPhase>(); | 1152 Run<ChangeLoweringPhase>(); |
1114 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1153 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1115 RunPrintAndVerify("Lowered changes", true); | 1154 RunPrintAndVerify("Lowered changes", true); |
1116 | 1155 |
1117 Run<LateControlReductionPhase>(); | 1156 Run<LateControlReductionPhase>(); |
1118 RunPrintAndVerify("Late Control reduced"); | 1157 RunPrintAndVerify("Late Control reduced"); |
1119 } else { | 1158 } else { |
1120 if (info()->is_osr()) { | 1159 if (info()->is_osr()) { |
1121 Run<OsrDeconstructionPhase>(); | 1160 Run<OsrDeconstructionPhase>(); |
1122 if (info()->bailout_reason() != kNoReason) return Handle<Code>::null(); | 1161 if (info()->bailout_reason() != kNoReason) return false; |
1123 RunPrintAndVerify("OSR deconstruction", true); | 1162 RunPrintAndVerify("OSR deconstruction", true); |
1124 } | 1163 } |
1125 } | 1164 } |
1126 | 1165 |
1127 // Lower any remaining generic JSOperators. | 1166 // Lower any remaining generic JSOperators. |
1128 Run<GenericLoweringPhase>(); | 1167 Run<GenericLoweringPhase>(); |
1129 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1168 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1130 RunPrintAndVerify("Lowered generic", true); | 1169 RunPrintAndVerify("Lowered generic", true); |
1131 | 1170 |
| 1171 EndPhaseKind(); |
| 1172 |
| 1173 data()->source_positions()->RemoveDecorator(); |
| 1174 return true; |
| 1175 } |
| 1176 |
| 1177 |
| 1178 bool Pipeline::OptimizeGraph() { |
| 1179 BeginPhaseKind("block building"); |
| 1180 |
1132 Run<LateGraphTrimmingPhase>(); | 1181 Run<LateGraphTrimmingPhase>(); |
1133 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1182 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
1134 RunPrintAndVerify("Late trimmed", true); | 1183 RunPrintAndVerify("Late trimmed", true); |
1135 | 1184 |
1136 BeginPhaseKind("block building"); | 1185 return ScheduleAndAllocateRegisters( |
1137 | 1186 Linkage::ComputeIncoming(data()->instruction_zone(), info())); |
1138 data.source_positions()->RemoveDecorator(); | |
1139 | |
1140 // Kill the Typer and thereby uninstall the decorator (if any). | |
1141 typer.Reset(nullptr); | |
1142 | |
1143 return ScheduleAndGenerateCode( | |
1144 Linkage::ComputeIncoming(data.instruction_zone(), info())); | |
1145 } | 1187 } |
1146 | 1188 |
1147 | 1189 |
| 1190 Handle<Code> Pipeline::GenerateCode() { |
| 1191 if (!CreateGraph() || !OptimizeGraph()) return Handle<Code>::null(); |
| 1192 return DoGenerateCode(); |
| 1193 } |
| 1194 |
| 1195 |
1148 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1196 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
1149 Graph* graph, | 1197 Graph* graph, |
1150 Schedule* schedule) { | 1198 Schedule* schedule) { |
1151 CallDescriptor* call_descriptor = | 1199 CallDescriptor* call_descriptor = |
1152 Linkage::ComputeIncoming(info->zone(), info); | 1200 Linkage::ComputeIncoming(info->zone(), info); |
1153 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); | 1201 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); |
1154 } | 1202 } |
1155 | 1203 |
1156 | 1204 |
1157 Handle<Code> Pipeline::GenerateCodeForTesting(Isolate* isolate, | 1205 Handle<Code> Pipeline::GenerateCodeForTesting(Isolate* isolate, |
1158 CallDescriptor* call_descriptor, | 1206 CallDescriptor* call_descriptor, |
1159 Graph* graph, | 1207 Graph* graph, |
1160 Schedule* schedule) { | 1208 Schedule* schedule) { |
1161 FakeStubForTesting stub(isolate); | 1209 FakeStubForTesting stub(isolate); |
1162 CompilationInfo info(&stub, isolate, graph->zone()); | 1210 CompilationInfo info(&stub, isolate, graph->zone()); |
1163 return GenerateCodeForTesting(&info, call_descriptor, graph, schedule); | 1211 return GenerateCodeForTesting(&info, call_descriptor, graph, schedule); |
1164 } | 1212 } |
1165 | 1213 |
1166 | 1214 |
1167 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1215 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
1168 CallDescriptor* call_descriptor, | 1216 CallDescriptor* call_descriptor, |
1169 Graph* graph, | 1217 Graph* graph, |
1170 Schedule* schedule) { | 1218 Schedule* schedule) { |
1171 // Construct a pipeline for scheduling and code generation. | 1219 // Construct a pipeline for scheduling and code generation. |
1172 ZonePool zone_pool; | 1220 PipelineData* data = new PipelineData(info, graph, schedule); |
1173 PipelineData data(&zone_pool, info, graph, schedule); | |
1174 SmartPointer<PipelineStatistics> pipeline_statistics; | 1221 SmartPointer<PipelineStatistics> pipeline_statistics; |
1175 if (FLAG_turbo_stats) { | 1222 if (FLAG_turbo_stats) { |
1176 pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool)); | 1223 pipeline_statistics.Reset(new PipelineStatistics(info, data->zone_pool())); |
1177 pipeline_statistics->BeginPhaseKind("test codegen"); | 1224 pipeline_statistics->BeginPhaseKind("test codegen"); |
1178 } | 1225 } |
1179 | 1226 |
1180 Pipeline pipeline(info); | 1227 Pipeline pipeline(data); |
1181 pipeline.data_ = &data; | 1228 if (data->schedule() == nullptr) { |
1182 if (data.schedule() == nullptr) { | |
1183 // TODO(rossberg): Should this really be untyped? | 1229 // TODO(rossberg): Should this really be untyped? |
1184 pipeline.RunPrintAndVerify("Machine", true); | 1230 pipeline.RunPrintAndVerify("Machine", true); |
1185 } | 1231 } |
1186 | 1232 |
1187 return pipeline.ScheduleAndGenerateCode(call_descriptor); | 1233 return pipeline.ScheduleAndGenerateCode(call_descriptor); |
1188 } | 1234 } |
1189 | 1235 |
1190 | 1236 |
1191 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, | 1237 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config, |
1192 InstructionSequence* sequence, | 1238 InstructionSequence* sequence, |
1193 bool run_verifier) { | 1239 bool run_verifier) { |
1194 FakeStubForTesting stub(sequence->isolate()); | 1240 FakeStubForTesting stub(sequence->isolate()); |
1195 CompilationInfo info(&stub, sequence->isolate(), sequence->zone()); | 1241 CompilationInfo info(&stub, sequence->isolate(), sequence->zone()); |
1196 ZonePool zone_pool; | 1242 PipelineData* data = new PipelineData(&info, sequence); |
1197 PipelineData data(&zone_pool, &info, sequence); | 1243 Pipeline pipeline(data); |
1198 Pipeline pipeline(&info); | |
1199 pipeline.data_ = &data; | |
1200 pipeline.AllocateRegisters(config, run_verifier); | 1244 pipeline.AllocateRegisters(config, run_verifier); |
1201 return !data.compilation_failed(); | 1245 return !data->compilation_failed(); |
1202 } | 1246 } |
1203 | 1247 |
1204 | 1248 |
1205 Handle<Code> Pipeline::ScheduleAndGenerateCode( | 1249 bool Pipeline::ScheduleAndAllocateRegisters(CallDescriptor* call_descriptor) { |
1206 CallDescriptor* call_descriptor) { | 1250 PipelineData* data = this->data(); |
1207 PipelineData* data = this->data_; | |
1208 | 1251 |
1209 DCHECK_NOT_NULL(data->graph()); | 1252 DCHECK_NOT_NULL(data->graph()); |
1210 CHECK(SupportedBackend()); | 1253 CHECK(SupportedBackend()); |
1211 | 1254 |
1212 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); | 1255 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); |
1213 TraceSchedule(data->info(), data->schedule()); | 1256 TraceSchedule(data->info(), data->schedule()); |
1214 | 1257 |
1215 BasicBlockProfiler::Data* profiler_data = NULL; | |
1216 if (FLAG_turbo_profiling) { | |
1217 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), | |
1218 data->schedule()); | |
1219 } | |
1220 | |
1221 data->InitializeInstructionSequence(); | 1258 data->InitializeInstructionSequence(); |
1222 | 1259 |
1223 // Select and schedule instructions covering the scheduled graph. | 1260 // Select and schedule instructions covering the scheduled graph. |
1224 Linkage linkage(call_descriptor); | 1261 data->set_linkage(new (data->info()->zone()) Linkage(call_descriptor)); |
1225 Run<InstructionSelectionPhase>(&linkage); | 1262 Run<InstructionSelectionPhase>(); |
1226 | 1263 |
1227 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { | 1264 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { |
1228 TurboCfgFile tcf(isolate()); | 1265 TurboCfgFile tcf(isolate()); |
1229 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), | 1266 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), |
1230 data->sequence()); | 1267 data->sequence()); |
1231 } | 1268 } |
1232 | 1269 |
1233 std::ostringstream source_position_output; | |
1234 if (FLAG_trace_turbo) { | 1270 if (FLAG_trace_turbo) { |
1235 // Output source position information before the graph is deleted. | 1271 // Output source position information before the graph is deleted. |
1236 data_->source_positions()->Print(source_position_output); | 1272 data->source_positions()->Print(data->source_position_output()); |
1237 } | 1273 } |
1238 | 1274 |
1239 data->DeleteGraphZone(); | 1275 data->DeleteGraphZone(); |
1240 | 1276 |
1241 BeginPhaseKind("register allocation"); | 1277 BeginPhaseKind("register allocation"); |
1242 | 1278 |
1243 bool run_verifier = FLAG_turbo_verify_allocation; | 1279 bool run_verifier = FLAG_turbo_verify_allocation; |
1244 // Allocate registers. | 1280 // Allocate registers. |
1245 AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier); | 1281 AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier); |
1246 if (data->compilation_failed()) { | 1282 if (data->compilation_failed()) { |
1247 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 1283 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
1248 return Handle<Code>(); | 1284 return false; |
1249 } | 1285 } |
1250 | 1286 |
1251 BeginPhaseKind("code generation"); | |
1252 | |
1253 // Optimimize jumps. | 1287 // Optimimize jumps. |
1254 if (FLAG_turbo_jt) { | 1288 if (FLAG_turbo_jt) { |
1255 Run<JumpThreadingPhase>(); | 1289 Run<JumpThreadingPhase>(); |
1256 } | 1290 } |
1257 | 1291 |
| 1292 EndPhaseKind(); |
| 1293 |
| 1294 return true; |
| 1295 } |
| 1296 |
| 1297 |
| 1298 Handle<Code> Pipeline::DoGenerateCode() { |
| 1299 PipelineData* data = this->data_; |
| 1300 |
| 1301 BeginPhaseKind("code generation"); |
| 1302 |
1258 // Generate final machine code. | 1303 // Generate final machine code. |
1259 Run<GenerateCodePhase>(&linkage); | 1304 Run<GenerateCodePhase>(); |
1260 | 1305 |
1261 Handle<Code> code = data->code(); | 1306 Handle<Code> code = data->code(); |
1262 if (profiler_data != NULL) { | 1307 if (data->profiler_data()) { |
1263 #if ENABLE_DISASSEMBLER | 1308 #if ENABLE_DISASSEMBLER |
1264 std::ostringstream os; | 1309 std::ostringstream os; |
1265 code->Disassemble(NULL, os); | 1310 code->Disassemble(NULL, os); |
1266 profiler_data->SetCode(&os); | 1311 data->profiler_data()->SetCode(&os); |
1267 #endif | 1312 #endif |
1268 } | 1313 } |
1269 | 1314 |
1270 info()->SetCode(code); | 1315 info()->SetCode(code); |
1271 v8::internal::CodeGenerator::PrintCode(code, info()); | 1316 v8::internal::CodeGenerator::PrintCode(code, info()); |
1272 | 1317 |
1273 if (FLAG_trace_turbo) { | 1318 if (FLAG_trace_turbo) { |
1274 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "a+"); | 1319 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "a+"); |
1275 if (json_file != nullptr) { | 1320 if (json_file != nullptr) { |
1276 OFStream json_of(json_file); | 1321 OFStream json_of(json_file); |
1277 json_of | 1322 json_of |
1278 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; | 1323 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; |
1279 #if ENABLE_DISASSEMBLER | 1324 #if ENABLE_DISASSEMBLER |
1280 std::stringstream disassembly_stream; | 1325 std::stringstream disassembly_stream; |
1281 code->Disassemble(NULL, disassembly_stream); | 1326 code->Disassemble(NULL, disassembly_stream); |
1282 std::string disassembly_string(disassembly_stream.str()); | 1327 std::string disassembly_string(disassembly_stream.str()); |
1283 for (const auto& c : disassembly_string) { | 1328 for (const auto& c : disassembly_string) { |
1284 json_of << AsEscapedUC16ForJSON(c); | 1329 json_of << AsEscapedUC16ForJSON(c); |
1285 } | 1330 } |
1286 #endif // ENABLE_DISASSEMBLER | 1331 #endif // ENABLE_DISASSEMBLER |
1287 json_of << "\"}\n],\n"; | 1332 json_of << "\"}\n],\n"; |
1288 json_of << "\"nodePositions\":"; | 1333 json_of << "\"nodePositions\":"; |
1289 json_of << source_position_output.str(); | 1334 json_of << data->source_position_output().str(); |
1290 json_of << "}"; | 1335 json_of << "}"; |
1291 fclose(json_file); | 1336 fclose(json_file); |
1292 } | 1337 } |
1293 OFStream os(stdout); | 1338 OFStream os(stdout); |
1294 os << "---------------------------------------------------\n" | 1339 os << "---------------------------------------------------\n" |
1295 << "Finished compiling method " << GetDebugName(info()).get() | 1340 << "Finished compiling method " << GetDebugName(info()).get() |
1296 << " using Turbofan" << std::endl; | 1341 << " using Turbofan" << std::endl; |
1297 } | 1342 } |
1298 | 1343 |
1299 return code; | 1344 return code; |
1300 } | 1345 } |
1301 | 1346 |
1302 | 1347 |
| 1348 Handle<Code> Pipeline::ScheduleAndGenerateCode( |
| 1349 CallDescriptor* call_descriptor) { |
| 1350 if (!ScheduleAndAllocateRegisters(call_descriptor)) { |
| 1351 return Handle<Code>::null(); |
| 1352 } |
| 1353 return DoGenerateCode(); |
| 1354 } |
| 1355 |
| 1356 |
1303 void Pipeline::AllocateRegisters(const RegisterConfiguration* config, | 1357 void Pipeline::AllocateRegisters(const RegisterConfiguration* config, |
1304 bool run_verifier) { | 1358 bool run_verifier) { |
1305 PipelineData* data = this->data_; | 1359 PipelineData* data = this->data(); |
1306 | 1360 |
1307 // Don't track usage for this zone in compiler stats. | 1361 // Don't track usage for this zone in compiler stats. |
1308 SmartPointer<Zone> verifier_zone; | 1362 SmartPointer<Zone> verifier_zone; |
1309 RegisterAllocatorVerifier* verifier = nullptr; | 1363 RegisterAllocatorVerifier* verifier = nullptr; |
1310 if (run_verifier) { | 1364 if (run_verifier) { |
1311 verifier_zone.Reset(new Zone()); | 1365 verifier_zone.Reset(new Zone()); |
1312 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( | 1366 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( |
1313 verifier_zone.get(), config, data->sequence()); | 1367 verifier_zone.get(), config, data->sequence()); |
1314 } | 1368 } |
1315 | 1369 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 tcf << AsC1VRegisterAllocationData("CodeGen", | 1430 tcf << AsC1VRegisterAllocationData("CodeGen", |
1377 data->register_allocation_data()); | 1431 data->register_allocation_data()); |
1378 } | 1432 } |
1379 | 1433 |
1380 data->DeleteRegisterAllocationZone(); | 1434 data->DeleteRegisterAllocationZone(); |
1381 } | 1435 } |
1382 | 1436 |
1383 } // namespace compiler | 1437 } // namespace compiler |
1384 } // namespace internal | 1438 } // namespace internal |
1385 } // namespace v8 | 1439 } // namespace v8 |
OLD | NEW |