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 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 private: | 297 private: |
298 Isolate* isolate_; | 298 Isolate* isolate_; |
299 CompilationInfo* info_; | 299 CompilationInfo* info_; |
300 Zone* outer_zone_; | 300 Zone* outer_zone_; |
301 ZonePool* const zone_pool_; | 301 ZonePool* const zone_pool_; |
302 PipelineStatistics* pipeline_statistics_; | 302 PipelineStatistics* pipeline_statistics_; |
303 bool compilation_failed_; | 303 bool compilation_failed_; |
304 Handle<Code> code_; | 304 Handle<Code> code_; |
305 | 305 |
306 // 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_. |
307 // They are all set to NULL when the graph_zone_ is destroyed. | 307 // They are all set to nullptr when the graph_zone_ is destroyed. |
308 ZonePool::Scope graph_zone_scope_; | 308 ZonePool::Scope graph_zone_scope_; |
309 Zone* graph_zone_; | 309 Zone* graph_zone_; |
310 Graph* graph_; | 310 Graph* graph_; |
311 // TODO(dcarney): make this into a ZoneObject. | 311 // TODO(dcarney): make this into a ZoneObject. |
312 base::SmartPointer<SourcePositionTable> source_positions_; | 312 base::SmartPointer<SourcePositionTable> source_positions_; |
313 LoopAssignmentAnalysis* loop_assignment_; | 313 LoopAssignmentAnalysis* loop_assignment_; |
314 TypeHintAnalysis* type_hint_analysis_ = nullptr; | 314 TypeHintAnalysis* type_hint_analysis_ = nullptr; |
315 SimplifiedOperatorBuilder* simplified_; | 315 SimplifiedOperatorBuilder* simplified_; |
316 MachineOperatorBuilder* machine_; | 316 MachineOperatorBuilder* machine_; |
317 CommonOperatorBuilder* common_; | 317 CommonOperatorBuilder* common_; |
318 JSOperatorBuilder* javascript_; | 318 JSOperatorBuilder* javascript_; |
319 JSGraph* jsgraph_; | 319 JSGraph* jsgraph_; |
320 Schedule* schedule_; | 320 Schedule* schedule_; |
321 | 321 |
322 // All objects in the following group of fields are allocated in | 322 // All objects in the following group of fields are allocated in |
323 // instruction_zone_. They are all set to NULL when the instruction_zone_ is | 323 // instruction_zone_. They are all set to nullptr when the instruction_zone_ |
| 324 // is |
324 // destroyed. | 325 // destroyed. |
325 ZonePool::Scope instruction_zone_scope_; | 326 ZonePool::Scope instruction_zone_scope_; |
326 Zone* instruction_zone_; | 327 Zone* instruction_zone_; |
327 InstructionSequence* sequence_; | 328 InstructionSequence* sequence_; |
328 Frame* frame_; | 329 Frame* frame_; |
329 | 330 |
330 // All objects in the following group of fields are allocated in | 331 // All objects in the following group of fields are allocated in |
331 // register_allocation_zone_. They are all set to NULL when the zone is | 332 // register_allocation_zone_. They are all set to nullptr when the zone is |
332 // destroyed. | 333 // destroyed. |
333 ZonePool::Scope register_allocation_zone_scope_; | 334 ZonePool::Scope register_allocation_zone_scope_; |
334 Zone* register_allocation_zone_; | 335 Zone* register_allocation_zone_; |
335 RegisterAllocationData* register_allocation_data_; | 336 RegisterAllocationData* register_allocation_data_; |
336 | 337 |
337 DISALLOW_COPY_AND_ASSIGN(PipelineData); | 338 DISALLOW_COPY_AND_ASSIGN(PipelineData); |
338 }; | 339 }; |
339 | 340 |
340 | 341 |
341 namespace { | 342 namespace { |
342 | 343 |
343 struct TurboCfgFile : public std::ofstream { | 344 struct TurboCfgFile : public std::ofstream { |
344 explicit TurboCfgFile(Isolate* isolate) | 345 explicit TurboCfgFile(Isolate* isolate) |
345 : std::ofstream(isolate->GetTurboCfgFileName().c_str(), | 346 : std::ofstream(isolate->GetTurboCfgFileName().c_str(), |
346 std::ios_base::app) {} | 347 std::ios_base::app) {} |
347 }; | 348 }; |
348 | 349 |
349 | 350 |
350 void TraceSchedule(CompilationInfo* info, Schedule* schedule) { | 351 void TraceSchedule(CompilationInfo* info, Schedule* schedule) { |
351 if (FLAG_trace_turbo) { | 352 if (FLAG_trace_turbo) { |
352 FILE* json_file = OpenVisualizerLogFile(info, NULL, "json", "a+"); | 353 FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+"); |
353 if (json_file != nullptr) { | 354 if (json_file != nullptr) { |
354 OFStream json_of(json_file); | 355 OFStream json_of(json_file); |
355 json_of << "{\"name\":\"Schedule\",\"type\":\"schedule\",\"data\":\""; | 356 json_of << "{\"name\":\"Schedule\",\"type\":\"schedule\",\"data\":\""; |
356 std::stringstream schedule_stream; | 357 std::stringstream schedule_stream; |
357 schedule_stream << *schedule; | 358 schedule_stream << *schedule; |
358 std::string schedule_string(schedule_stream.str()); | 359 std::string schedule_string(schedule_stream.str()); |
359 for (const auto& c : schedule_string) { | 360 for (const auto& c : schedule_string) { |
360 json_of << AsEscapedUC16ForJSON(c); | 361 json_of << AsEscapedUC16ForJSON(c); |
361 } | 362 } |
362 json_of << "\"},\n"; | 363 json_of << "\"},\n"; |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 }; | 752 }; |
752 | 753 |
753 | 754 |
754 struct StressLoopPeelingPhase { | 755 struct StressLoopPeelingPhase { |
755 static const char* phase_name() { return "stress loop peeling"; } | 756 static const char* phase_name() { return "stress loop peeling"; } |
756 | 757 |
757 void Run(PipelineData* data, Zone* temp_zone) { | 758 void Run(PipelineData* data, Zone* temp_zone) { |
758 // Peel the first outer loop for testing. | 759 // Peel the first outer loop for testing. |
759 // TODO(titzer): peel all loops? the N'th loop? Innermost loops? | 760 // TODO(titzer): peel all loops? the N'th loop? Innermost loops? |
760 LoopTree* loop_tree = LoopFinder::BuildLoopTree(data->graph(), temp_zone); | 761 LoopTree* loop_tree = LoopFinder::BuildLoopTree(data->graph(), temp_zone); |
761 if (loop_tree != NULL && loop_tree->outer_loops().size() > 0) { | 762 if (loop_tree != nullptr && loop_tree->outer_loops().size() > 0) { |
762 LoopPeeler::Peel(data->graph(), data->common(), loop_tree, | 763 LoopPeeler::Peel(data->graph(), data->common(), loop_tree, |
763 loop_tree->outer_loops()[0], temp_zone); | 764 loop_tree->outer_loops()[0], temp_zone); |
764 } | 765 } |
765 } | 766 } |
766 }; | 767 }; |
767 | 768 |
768 | 769 |
769 struct GenericLoweringPhase { | 770 struct GenericLoweringPhase { |
770 static const char* phase_name() { return "generic lowering"; } | 771 static const char* phase_name() { return "generic lowering"; } |
771 | 772 |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 | 1000 |
1000 | 1001 |
1001 struct PrintGraphPhase { | 1002 struct PrintGraphPhase { |
1002 static const char* phase_name() { return nullptr; } | 1003 static const char* phase_name() { return nullptr; } |
1003 | 1004 |
1004 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { | 1005 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { |
1005 CompilationInfo* info = data->info(); | 1006 CompilationInfo* info = data->info(); |
1006 Graph* graph = data->graph(); | 1007 Graph* graph = data->graph(); |
1007 | 1008 |
1008 { // Print JSON. | 1009 { // Print JSON. |
1009 FILE* json_file = OpenVisualizerLogFile(info, NULL, "json", "a+"); | 1010 FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+"); |
1010 if (json_file == nullptr) return; | 1011 if (json_file == nullptr) return; |
1011 OFStream json_of(json_file); | 1012 OFStream json_of(json_file); |
1012 json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":" | 1013 json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":" |
1013 << AsJSON(*graph, data->source_positions()) << "},\n"; | 1014 << AsJSON(*graph, data->source_positions()) << "},\n"; |
1014 fclose(json_file); | 1015 fclose(json_file); |
1015 } | 1016 } |
1016 | 1017 |
1017 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 1018 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
1018 OFStream os(stdout); | 1019 OFStream os(stdout); |
1019 os << "-- Graph after " << phase << " -- " << std::endl; | 1020 os << "-- Graph after " << phase << " -- " << std::endl; |
1020 os << AsRPO(*graph); | 1021 os << AsRPO(*graph); |
1021 } | 1022 } |
1022 } | 1023 } |
1023 }; | 1024 }; |
1024 | 1025 |
1025 | 1026 |
1026 struct VerifyGraphPhase { | 1027 struct VerifyGraphPhase { |
1027 static const char* phase_name() { return nullptr; } | 1028 static const char* phase_name() { return nullptr; } |
1028 | 1029 |
1029 void Run(PipelineData* data, Zone* temp_zone, const bool untyped) { | 1030 void Run(PipelineData* data, Zone* temp_zone, const bool untyped) { |
1030 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped | 1031 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped |
1031 ? Verifier::TYPED | 1032 ? Verifier::TYPED |
1032 : Verifier::UNTYPED); | 1033 : Verifier::UNTYPED); |
1033 } | 1034 } |
1034 }; | 1035 }; |
1035 | 1036 |
1036 | 1037 |
1037 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { | 1038 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { |
1038 if (data_->pipeline_statistics() != NULL) { | 1039 if (data_->pipeline_statistics() != nullptr) { |
1039 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); | 1040 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); |
1040 } | 1041 } |
1041 } | 1042 } |
1042 | 1043 |
1043 | 1044 |
1044 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { | 1045 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { |
1045 if (FLAG_trace_turbo) { | 1046 if (FLAG_trace_turbo) { |
1046 Run<PrintGraphPhase>(phase); | 1047 Run<PrintGraphPhase>(phase); |
1047 } | 1048 } |
1048 if (FLAG_turbo_verify) { | 1049 if (FLAG_turbo_verify) { |
(...skipping 12 matching lines...) Expand all Loading... |
1061 | 1062 |
1062 ZonePool zone_pool; | 1063 ZonePool zone_pool; |
1063 base::SmartPointer<PipelineStatistics> pipeline_statistics; | 1064 base::SmartPointer<PipelineStatistics> pipeline_statistics; |
1064 | 1065 |
1065 if (FLAG_turbo_stats) { | 1066 if (FLAG_turbo_stats) { |
1066 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); | 1067 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); |
1067 pipeline_statistics->BeginPhaseKind("initializing"); | 1068 pipeline_statistics->BeginPhaseKind("initializing"); |
1068 } | 1069 } |
1069 | 1070 |
1070 if (FLAG_trace_turbo) { | 1071 if (FLAG_trace_turbo) { |
1071 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "w+"); | 1072 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "w+"); |
1072 if (json_file != nullptr) { | 1073 if (json_file != nullptr) { |
1073 OFStream json_of(json_file); | 1074 OFStream json_of(json_file); |
1074 Handle<Script> script = info()->script(); | 1075 Handle<Script> script = info()->script(); |
1075 FunctionLiteral* function = info()->literal(); | 1076 FunctionLiteral* function = info()->literal(); |
1076 base::SmartArrayPointer<char> function_name = info()->GetDebugName(); | 1077 base::SmartArrayPointer<char> function_name = info()->GetDebugName(); |
1077 int pos = info()->shared_info()->start_position(); | 1078 int pos = info()->shared_info()->start_position(); |
1078 json_of << "{\"function\":\"" << function_name.get() | 1079 json_of << "{\"function\":\"" << function_name.get() |
1079 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; | 1080 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; |
1080 if (!script->IsUndefined() && !script->source()->IsUndefined()) { | 1081 if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
1081 DisallowHeapAllocation no_allocation; | 1082 DisallowHeapAllocation no_allocation; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 if (FLAG_turbo_stats) { | 1227 if (FLAG_turbo_stats) { |
1227 pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool)); | 1228 pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool)); |
1228 pipeline_statistics->BeginPhaseKind("stub codegen"); | 1229 pipeline_statistics->BeginPhaseKind("stub codegen"); |
1229 } | 1230 } |
1230 | 1231 |
1231 Pipeline pipeline(&info); | 1232 Pipeline pipeline(&info); |
1232 pipeline.data_ = &data; | 1233 pipeline.data_ = &data; |
1233 DCHECK_NOT_NULL(data.schedule()); | 1234 DCHECK_NOT_NULL(data.schedule()); |
1234 | 1235 |
1235 if (FLAG_trace_turbo) { | 1236 if (FLAG_trace_turbo) { |
1236 FILE* json_file = OpenVisualizerLogFile(&info, NULL, "json", "w+"); | 1237 FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+"); |
1237 if (json_file != nullptr) { | 1238 if (json_file != nullptr) { |
1238 OFStream json_of(json_file); | 1239 OFStream json_of(json_file); |
1239 json_of << "{\"function\":\"" << info.GetDebugName().get() | 1240 json_of << "{\"function\":\"" << info.GetDebugName().get() |
1240 << "\", \"source\":\"\",\n\"phases\":["; | 1241 << "\", \"source\":\"\",\n\"phases\":["; |
1241 fclose(json_file); | 1242 fclose(json_file); |
1242 } | 1243 } |
1243 pipeline.Run<PrintGraphPhase>("Machine"); | 1244 pipeline.Run<PrintGraphPhase>("Machine"); |
1244 } | 1245 } |
1245 | 1246 |
1246 return pipeline.ScheduleAndGenerateCode(call_descriptor); | 1247 return pipeline.ScheduleAndGenerateCode(call_descriptor); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1295 | 1296 |
1296 Handle<Code> Pipeline::ScheduleAndGenerateCode( | 1297 Handle<Code> Pipeline::ScheduleAndGenerateCode( |
1297 CallDescriptor* call_descriptor) { | 1298 CallDescriptor* call_descriptor) { |
1298 PipelineData* data = this->data_; | 1299 PipelineData* data = this->data_; |
1299 | 1300 |
1300 DCHECK_NOT_NULL(data->graph()); | 1301 DCHECK_NOT_NULL(data->graph()); |
1301 | 1302 |
1302 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); | 1303 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>(); |
1303 TraceSchedule(data->info(), data->schedule()); | 1304 TraceSchedule(data->info(), data->schedule()); |
1304 | 1305 |
1305 BasicBlockProfiler::Data* profiler_data = NULL; | 1306 BasicBlockProfiler::Data* profiler_data = nullptr; |
1306 if (FLAG_turbo_profiling) { | 1307 if (FLAG_turbo_profiling) { |
1307 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), | 1308 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), |
1308 data->schedule()); | 1309 data->schedule()); |
1309 } | 1310 } |
1310 | 1311 |
1311 data->InitializeInstructionSequence(); | 1312 data->InitializeInstructionSequence(); |
1312 | 1313 |
1313 // Select and schedule instructions covering the scheduled graph. | 1314 // Select and schedule instructions covering the scheduled graph. |
1314 Linkage linkage(call_descriptor); | 1315 Linkage linkage(call_descriptor); |
1315 Run<InstructionSelectionPhase>(&linkage); | 1316 Run<InstructionSelectionPhase>(&linkage); |
(...skipping 28 matching lines...) Expand all Loading... |
1344 | 1345 |
1345 // Optimimize jumps. | 1346 // Optimimize jumps. |
1346 if (FLAG_turbo_jt) { | 1347 if (FLAG_turbo_jt) { |
1347 Run<JumpThreadingPhase>(); | 1348 Run<JumpThreadingPhase>(); |
1348 } | 1349 } |
1349 | 1350 |
1350 // Generate final machine code. | 1351 // Generate final machine code. |
1351 Run<GenerateCodePhase>(&linkage); | 1352 Run<GenerateCodePhase>(&linkage); |
1352 | 1353 |
1353 Handle<Code> code = data->code(); | 1354 Handle<Code> code = data->code(); |
1354 if (profiler_data != NULL) { | 1355 if (profiler_data != nullptr) { |
1355 #if ENABLE_DISASSEMBLER | 1356 #if ENABLE_DISASSEMBLER |
1356 std::ostringstream os; | 1357 std::ostringstream os; |
1357 code->Disassemble(NULL, os); | 1358 code->Disassemble(nullptr, os); |
1358 profiler_data->SetCode(&os); | 1359 profiler_data->SetCode(&os); |
1359 #endif | 1360 #endif |
1360 } | 1361 } |
1361 | 1362 |
1362 info()->SetCode(code); | 1363 info()->SetCode(code); |
1363 v8::internal::CodeGenerator::PrintCode(code, info()); | 1364 v8::internal::CodeGenerator::PrintCode(code, info()); |
1364 | 1365 |
1365 if (FLAG_trace_turbo) { | 1366 if (FLAG_trace_turbo) { |
1366 FILE* json_file = OpenVisualizerLogFile(info(), NULL, "json", "a+"); | 1367 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+"); |
1367 if (json_file != nullptr) { | 1368 if (json_file != nullptr) { |
1368 OFStream json_of(json_file); | 1369 OFStream json_of(json_file); |
1369 json_of | 1370 json_of |
1370 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; | 1371 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; |
1371 #if ENABLE_DISASSEMBLER | 1372 #if ENABLE_DISASSEMBLER |
1372 std::stringstream disassembly_stream; | 1373 std::stringstream disassembly_stream; |
1373 code->Disassemble(NULL, disassembly_stream); | 1374 code->Disassemble(nullptr, disassembly_stream); |
1374 std::string disassembly_string(disassembly_stream.str()); | 1375 std::string disassembly_string(disassembly_stream.str()); |
1375 for (const auto& c : disassembly_string) { | 1376 for (const auto& c : disassembly_string) { |
1376 json_of << AsEscapedUC16ForJSON(c); | 1377 json_of << AsEscapedUC16ForJSON(c); |
1377 } | 1378 } |
1378 #endif // ENABLE_DISASSEMBLER | 1379 #endif // ENABLE_DISASSEMBLER |
1379 json_of << "\"}\n],\n"; | 1380 json_of << "\"}\n],\n"; |
1380 json_of << "\"nodePositions\":"; | 1381 json_of << "\"nodePositions\":"; |
1381 json_of << source_position_output.str(); | 1382 json_of << source_position_output.str(); |
1382 json_of << "}"; | 1383 json_of << "}"; |
1383 fclose(json_file); | 1384 fclose(json_file); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1480 tcf << AsC1VRegisterAllocationData("CodeGen", | 1481 tcf << AsC1VRegisterAllocationData("CodeGen", |
1481 data->register_allocation_data()); | 1482 data->register_allocation_data()); |
1482 } | 1483 } |
1483 | 1484 |
1484 data->DeleteRegisterAllocationZone(); | 1485 data->DeleteRegisterAllocationZone(); |
1485 } | 1486 } |
1486 | 1487 |
1487 } // namespace compiler | 1488 } // namespace compiler |
1488 } // namespace internal | 1489 } // namespace internal |
1489 } // namespace v8 | 1490 } // namespace v8 |
OLD | NEW |