| 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 |