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