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