Chromium Code Reviews| 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/platform/elapsed-timer.h" | 10 #include "src/base/platform/elapsed-timer.h" |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 static const char* phase_name() { return "generate code"; } | 682 static const char* phase_name() { return "generate code"; } |
| 683 | 683 |
| 684 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { | 684 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { |
| 685 CodeGenerator generator(data->frame(), linkage, data->sequence(), | 685 CodeGenerator generator(data->frame(), linkage, data->sequence(), |
| 686 data->info()); | 686 data->info()); |
| 687 data->set_code(generator.GenerateCode()); | 687 data->set_code(generator.GenerateCode()); |
| 688 } | 688 } |
| 689 }; | 689 }; |
| 690 | 690 |
| 691 | 691 |
| 692 namespace { | |
| 693 | |
| 694 FILE* OpenLogFile(CompilationInfo* info, const char* phase, const char* suffix, | |
| 695 const char* mode) { | |
|
titzer
2015/02/02 17:25:36
This is starting to get pretty unwieldy. Can we pl
Michael Starzinger
2015/02/02 17:26:09
Strong +1 here, this should be part of the graph-v
| |
| 696 EmbeddedVector<char, 256> filename; | |
| 697 SmartArrayPointer<char> function_name; | |
| 698 if (!info->shared_info().is_null()) { | |
| 699 function_name = info->shared_info()->DebugName()->ToCString(); | |
| 700 if (strlen(function_name.get()) > 0) { | |
| 701 SNPrintF(filename, "turbo-%s", function_name.get()); | |
| 702 } else { | |
| 703 SNPrintF(filename, "turbo-%p", static_cast<void*>(info)); | |
| 704 } | |
| 705 } else { | |
| 706 SNPrintF(filename, "turbo-none-%s", phase); | |
| 707 } | |
| 708 std::replace(filename.start(), filename.start() + filename.length(), ' ', | |
| 709 '_'); | |
| 710 | |
| 711 EmbeddedVector<char, 256> full_filename; | |
| 712 if (phase == NULL) { | |
| 713 SNPrintF(full_filename, "%s.%s", filename.start(), suffix); | |
| 714 } else { | |
| 715 SNPrintF(full_filename, "%s-%s.%s", filename.start(), phase, suffix); | |
| 716 } | |
| 717 return base::OS::FOpen(full_filename.start(), mode); | |
| 718 } | |
| 719 } | |
| 720 | |
| 692 struct PrintGraphPhase { | 721 struct PrintGraphPhase { |
| 693 static const char* phase_name() { return nullptr; } | 722 static const char* phase_name() { return nullptr; } |
| 694 | 723 |
| 695 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { | 724 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { |
| 696 CompilationInfo* info = data->info(); | 725 CompilationInfo* info = data->info(); |
| 697 Graph* graph = data->graph(); | 726 Graph* graph = data->graph(); |
| 698 char buffer[256]; | |
| 699 Vector<char> filename(buffer, sizeof(buffer)); | |
| 700 SmartArrayPointer<char> functionname; | |
| 701 if (!info->shared_info().is_null()) { | |
| 702 functionname = info->shared_info()->DebugName()->ToCString(); | |
| 703 if (strlen(functionname.get()) > 0) { | |
| 704 SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase); | |
| 705 } else { | |
| 706 SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info), phase); | |
| 707 } | |
| 708 } else { | |
| 709 SNPrintF(filename, "turbo-none-%s", phase); | |
| 710 } | |
| 711 std::replace(filename.start(), filename.start() + filename.length(), ' ', | |
| 712 '_'); | |
| 713 | 727 |
| 714 { // Print dot. | 728 { // Print dot. |
| 715 char dot_buffer[256]; | 729 FILE* dot_file = OpenLogFile(info, phase, "dot", "w+"); |
| 716 Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer)); | |
| 717 SNPrintF(dot_filename, "%s.dot", filename.start()); | |
| 718 FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+"); | |
| 719 if (dot_file == nullptr) return; | 730 if (dot_file == nullptr) return; |
| 720 OFStream dot_of(dot_file); | 731 OFStream dot_of(dot_file); |
| 721 dot_of << AsDOT(*graph); | 732 dot_of << AsDOT(*graph); |
| 722 fclose(dot_file); | 733 fclose(dot_file); |
| 723 } | 734 } |
| 724 | 735 |
| 725 { // Print JSON. | 736 { // Print JSON. |
| 726 char json_buffer[256]; | 737 FILE* json_file = OpenLogFile(info, NULL, "json", "a+"); |
| 727 Vector<char> json_filename(json_buffer, sizeof(json_buffer)); | |
| 728 SNPrintF(json_filename, "%s.json", filename.start()); | |
| 729 FILE* json_file = base::OS::FOpen(json_filename.start(), "w+"); | |
| 730 if (json_file == nullptr) return; | 738 if (json_file == nullptr) return; |
| 731 OFStream json_of(json_file); | 739 OFStream json_of(json_file); |
| 732 json_of << AsJSON(*graph); | 740 json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":" |
| 741 << AsJSON(*graph, data->source_positions()) << "},\n"; | |
| 733 fclose(json_file); | 742 fclose(json_file); |
| 734 } | 743 } |
| 735 | 744 |
| 736 OFStream os(stdout); | 745 OFStream os(stdout); |
| 737 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 746 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
| 738 os << "-- Graph after " << phase << " -- " << std::endl; | 747 os << "-- Graph after " << phase << " -- " << std::endl; |
| 739 os << AsRPO(*graph); | 748 os << AsRPO(*graph); |
| 740 } | 749 } |
| 741 | |
| 742 os << "-- " << phase << " graph printed to file " << filename.start() | |
| 743 << std::endl; | |
| 744 } | 750 } |
| 745 }; | 751 }; |
| 746 | 752 |
| 747 | 753 |
| 748 struct VerifyGraphPhase { | 754 struct VerifyGraphPhase { |
| 749 static const char* phase_name() { return nullptr; } | 755 static const char* phase_name() { return nullptr; } |
| 750 | 756 |
| 751 void Run(PipelineData* data, Zone* temp_zone, const bool untyped) { | 757 void Run(PipelineData* data, Zone* temp_zone, const bool untyped) { |
| 752 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped | 758 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped |
| 753 ? Verifier::TYPED | 759 ? Verifier::TYPED |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 789 } | 795 } |
| 790 | 796 |
| 791 ZonePool zone_pool; | 797 ZonePool zone_pool; |
| 792 SmartPointer<PipelineStatistics> pipeline_statistics; | 798 SmartPointer<PipelineStatistics> pipeline_statistics; |
| 793 | 799 |
| 794 if (FLAG_turbo_stats) { | 800 if (FLAG_turbo_stats) { |
| 795 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); | 801 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); |
| 796 pipeline_statistics->BeginPhaseKind("initializing"); | 802 pipeline_statistics->BeginPhaseKind("initializing"); |
| 797 } | 803 } |
| 798 | 804 |
| 805 if (FLAG_trace_turbo) { | |
| 806 FILE* json_file = OpenLogFile(info(), NULL, "json", "w+"); | |
| 807 if (json_file != nullptr) { | |
| 808 OFStream json_of(json_file); | |
| 809 Handle<Script> script = info()->script(); | |
| 810 FunctionLiteral* function = info()->function(); | |
| 811 SmartArrayPointer<char> function_name = | |
| 812 info()->shared_info()->DebugName()->ToCString(); | |
| 813 int pos = info()->shared_info()->start_position(); | |
| 814 json_of << "{\"function\":\"" << function_name.get() | |
| 815 << "\", \"sourcePosition\":" << pos << ", \"source\":\""; | |
| 816 if (!script->IsUndefined() && !script->source()->IsUndefined()) { | |
| 817 DisallowHeapAllocation no_allocation; | |
| 818 int start = function->start_position(); | |
| 819 int len = function->end_position() - start + 1; | |
| 820 String::SubStringRange source(String::cast(script->source()), start, | |
| 821 len); | |
| 822 for (const auto& c : source) { | |
| 823 json_of << AsEscapedUC16ForJSON(c); | |
| 824 } | |
| 825 } | |
| 826 json_of << "\",\n\"phases\":["; | |
| 827 fclose(json_file); | |
| 828 } | |
| 829 } | |
| 830 | |
| 799 PipelineData data(&zone_pool, info()); | 831 PipelineData data(&zone_pool, info()); |
| 800 this->data_ = &data; | 832 this->data_ = &data; |
| 801 data.Initialize(pipeline_statistics.get()); | 833 data.Initialize(pipeline_statistics.get()); |
| 802 | 834 |
| 803 BeginPhaseKind("graph creation"); | 835 BeginPhaseKind("graph creation"); |
| 804 | 836 |
| 805 if (FLAG_trace_turbo) { | 837 if (FLAG_trace_turbo) { |
| 806 OFStream os(stdout); | 838 OFStream os(stdout); |
| 807 os << "---------------------------------------------------\n" | 839 os << "---------------------------------------------------\n" |
| 808 << "Begin compiling method " << GetDebugName(info()).get() | 840 << "Begin compiling method " << GetDebugName(info()).get() |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 901 Linkage linkage(data.instruction_zone(), info()); | 933 Linkage linkage(data.instruction_zone(), info()); |
| 902 GenerateCode(&linkage); | 934 GenerateCode(&linkage); |
| 903 } | 935 } |
| 904 Handle<Code> code = data.code(); | 936 Handle<Code> code = data.code(); |
| 905 info()->SetCode(code); | 937 info()->SetCode(code); |
| 906 | 938 |
| 907 // Print optimized code. | 939 // Print optimized code. |
| 908 v8::internal::CodeGenerator::PrintCode(code, info()); | 940 v8::internal::CodeGenerator::PrintCode(code, info()); |
| 909 | 941 |
| 910 if (FLAG_trace_turbo) { | 942 if (FLAG_trace_turbo) { |
| 943 FILE* json_file = OpenLogFile(info(), NULL, "json", "a+"); | |
| 944 if (json_file != nullptr) { | |
| 945 OFStream json_of(json_file); | |
| 946 json_of | |
| 947 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\""; | |
| 948 #if ENABLE_DISASSEMBLER | |
| 949 std::stringstream disassembly_stream; | |
| 950 code->Disassemble(NULL, disassembly_stream); | |
| 951 std::string disassembly_string(disassembly_stream.str()); | |
| 952 for (const auto& c : disassembly_string) { | |
| 953 json_of << AsEscapedUC16ForJSON(c); | |
| 954 } | |
| 955 #endif // ENABLE_DISASSEMBLER | |
| 956 json_of << "\"}\n]}"; | |
| 957 fclose(json_file); | |
| 958 } | |
| 911 OFStream os(stdout); | 959 OFStream os(stdout); |
| 912 os << "---------------------------------------------------\n" | 960 os << "---------------------------------------------------\n" |
| 913 << "Finished compiling method " << GetDebugName(info()).get() | 961 << "Finished compiling method " << GetDebugName(info()).get() |
| 914 << " using Turbofan" << std::endl; | 962 << " using Turbofan" << std::endl; |
| 915 } | 963 } |
| 916 | 964 |
| 917 return code; | 965 return code; |
| 918 } | 966 } |
| 919 | 967 |
| 920 | 968 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1114 } | 1162 } |
| 1115 | 1163 |
| 1116 | 1164 |
| 1117 void Pipeline::TearDown() { | 1165 void Pipeline::TearDown() { |
| 1118 InstructionOperand::TearDownCaches(); | 1166 InstructionOperand::TearDownCaches(); |
| 1119 } | 1167 } |
| 1120 | 1168 |
| 1121 } // namespace compiler | 1169 } // namespace compiler |
| 1122 } // namespace internal | 1170 } // namespace internal |
| 1123 } // namespace v8 | 1171 } // namespace v8 |
| OLD | NEW |