OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 | 25 |
26 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); | 26 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); |
27 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); | 27 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); |
28 DECLARE_FLAG(bool, enable_type_checks); | 28 DECLARE_FLAG(bool, enable_type_checks); |
29 DECLARE_FLAG(bool, intrinsify); | 29 DECLARE_FLAG(bool, intrinsify); |
30 DECLARE_FLAG(bool, optimization_counter_threshold); | 30 DECLARE_FLAG(bool, optimization_counter_threshold); |
31 DECLARE_FLAG(bool, print_ast); | 31 DECLARE_FLAG(bool, print_ast); |
32 DECLARE_FLAG(bool, report_usage_count); | 32 DECLARE_FLAG(bool, report_usage_count); |
33 DECLARE_FLAG(bool, code_comments); | 33 DECLARE_FLAG(bool, code_comments); |
34 | 34 |
| 35 class DeoptimizationStub : public ZoneAllocated { |
| 36 public: |
| 37 DeoptimizationStub(intptr_t deopt_id, |
| 38 intptr_t deopt_token_index, |
| 39 intptr_t try_index, |
| 40 DeoptReasonId reason) |
| 41 : deopt_id_(deopt_id), |
| 42 deopt_token_index_(deopt_token_index), |
| 43 try_index_(try_index), |
| 44 reason_(reason), |
| 45 registers_(2), |
| 46 entry_label_() {} |
| 47 |
| 48 void Push(Register reg) { registers_.Add(reg); } |
| 49 Label* entry_label() { return &entry_label_; } |
| 50 |
| 51 void GenerateCode(FlowGraphCompiler* compiler); |
| 52 |
| 53 private: |
| 54 const intptr_t deopt_id_; |
| 55 const intptr_t deopt_token_index_; |
| 56 const intptr_t try_index_; |
| 57 const DeoptReasonId reason_; |
| 58 GrowableArray<Register> registers_; |
| 59 Label entry_label_; |
| 60 |
| 61 DISALLOW_COPY_AND_ASSIGN(DeoptimizationStub); |
| 62 }; |
| 63 |
| 64 |
| 65 void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler) { |
| 66 Assembler* assem = compiler->assembler(); |
| 67 #define __ assem-> |
| 68 __ Comment("Deopt stub for id %d", deopt_id_); |
| 69 __ Bind(entry_label()); |
| 70 for (intptr_t i = 0; i < registers_.length(); i++) { |
| 71 __ pushq(registers_[i]); |
| 72 } |
| 73 __ movq(RAX, Immediate(Smi::RawValue(reason_))); |
| 74 __ call(&StubCode::DeoptimizeLabel()); |
| 75 compiler->AddCurrentDescriptor(PcDescriptors::kOther, |
| 76 deopt_id_, |
| 77 deopt_token_index_, |
| 78 try_index_); |
| 79 #undef __ |
| 80 } |
| 81 |
35 | 82 |
36 FlowGraphCompiler::FlowGraphCompiler( | 83 FlowGraphCompiler::FlowGraphCompiler( |
37 Assembler* assembler, | 84 Assembler* assembler, |
38 const ParsedFunction& parsed_function, | 85 const ParsedFunction& parsed_function, |
39 const GrowableArray<BlockEntryInstr*>& block_order, | 86 const GrowableArray<BlockEntryInstr*>& block_order, |
40 bool is_optimizing) | 87 bool is_optimizing) |
41 : FlowGraphVisitor(block_order), | 88 : FlowGraphVisitor(block_order), |
42 assembler_(assembler), | 89 assembler_(assembler), |
43 parsed_function_(parsed_function), | 90 parsed_function_(parsed_function), |
44 block_info_(block_order.length()), | 91 block_info_(block_order.length()), |
45 current_block_(NULL), | 92 current_block_(NULL), |
46 pc_descriptors_list_(NULL), | 93 pc_descriptors_list_(NULL), |
47 exception_handlers_list_(NULL), | 94 exception_handlers_list_(NULL), |
| 95 deopt_stubs_(), |
48 is_optimizing_(is_optimizing) { | 96 is_optimizing_(is_optimizing) { |
49 } | 97 } |
50 | 98 |
51 | 99 |
52 void FlowGraphCompiler::InitCompiler() { | 100 void FlowGraphCompiler::InitCompiler() { |
53 pc_descriptors_list_ = new DescriptorList(); | 101 pc_descriptors_list_ = new DescriptorList(); |
54 exception_handlers_list_ = new ExceptionHandlerList(); | 102 exception_handlers_list_ = new ExceptionHandlerList(); |
55 block_info_.Clear(); | 103 block_info_.Clear(); |
56 for (int i = 0; i < block_order_.length(); ++i) { | 104 for (int i = 0; i < block_order_.length(); ++i) { |
57 block_info_.Add(new BlockInfo()); | 105 block_info_.Add(new BlockInfo()); |
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 | 1337 |
1290 ASSERT(!comp->exception_var().is_captured()); | 1338 ASSERT(!comp->exception_var().is_captured()); |
1291 ASSERT(!comp->stacktrace_var().is_captured()); | 1339 ASSERT(!comp->stacktrace_var().is_captured()); |
1292 __ movq(Address(RBP, comp->exception_var().index() * kWordSize), | 1340 __ movq(Address(RBP, comp->exception_var().index() * kWordSize), |
1293 kExceptionObjectReg); | 1341 kExceptionObjectReg); |
1294 __ movq(Address(RBP, comp->stacktrace_var().index() * kWordSize), | 1342 __ movq(Address(RBP, comp->stacktrace_var().index() * kWordSize), |
1295 kStackTraceObjectReg); | 1343 kStackTraceObjectReg); |
1296 } | 1344 } |
1297 | 1345 |
1298 | 1346 |
| 1347 void FlowGraphCompiler::VisitBinaryOp(BinaryOpComp* comp) { |
| 1348 UNIMPLEMENTED(); |
| 1349 } |
| 1350 |
| 1351 |
1299 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) { | 1352 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) { |
1300 LocationSummary* locs = instr->locs(); | 1353 LocationSummary* locs = instr->locs(); |
1301 ASSERT(locs != NULL); | 1354 ASSERT(locs != NULL); |
1302 | 1355 |
1303 locs->AllocateRegisters(); | 1356 locs->AllocateRegisters(); |
1304 | 1357 |
1305 // Load instruction inputs into allocated registers. | 1358 // Load instruction inputs into allocated registers. |
1306 for (intptr_t i = locs->count() - 1; i >= 0; i--) { | 1359 for (intptr_t i = locs->count() - 1; i >= 0; i--) { |
1307 Location loc = locs->in(i); | 1360 Location loc = locs->in(i); |
1308 ASSERT(loc.kind() == Location::kRegister); | 1361 ASSERT(loc.kind() == Location::kRegister); |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1829 if (FLAG_print_ast) { | 1882 if (FLAG_print_ast) { |
1830 // Second printing. | 1883 // Second printing. |
1831 OS::Print("Annotated "); | 1884 OS::Print("Annotated "); |
1832 } | 1885 } |
1833 AstPrinter::PrintFunctionScope(parsed_function_); | 1886 AstPrinter::PrintFunctionScope(parsed_function_); |
1834 } | 1887 } |
1835 | 1888 |
1836 VisitBlocks(); | 1889 VisitBlocks(); |
1837 | 1890 |
1838 __ int3(); | 1891 __ int3(); |
| 1892 GenerateDeferredCode(); |
1839 // Emit function patching code. This will be swapped with the first 13 bytes | 1893 // Emit function patching code. This will be swapped with the first 13 bytes |
1840 // at entry point. | 1894 // at entry point. |
1841 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, | 1895 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, |
1842 assembler_->CodeSize(), | 1896 assembler_->CodeSize(), |
1843 AstNode::kNoId, | 1897 AstNode::kNoId, |
1844 0, | 1898 0, |
1845 -1); | 1899 -1); |
1846 __ jmp(&StubCode::FixCallersTargetLabel()); | 1900 __ jmp(&StubCode::FixCallersTargetLabel()); |
1847 } | 1901 } |
1848 | 1902 |
1849 | 1903 |
| 1904 void FlowGraphCompiler::GenerateDeferredCode() { |
| 1905 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) { |
| 1906 deopt_stubs_[i]->GenerateCode(this); |
| 1907 } |
| 1908 } |
| 1909 |
| 1910 |
1850 // Infrastructure copied from class CodeGenerator. | 1911 // Infrastructure copied from class CodeGenerator. |
1851 void FlowGraphCompiler::GenerateCall(intptr_t token_index, | 1912 void FlowGraphCompiler::GenerateCall(intptr_t token_index, |
1852 intptr_t try_index, | 1913 intptr_t try_index, |
1853 const ExternalLabel* label, | 1914 const ExternalLabel* label, |
1854 PcDescriptors::Kind kind) { | 1915 PcDescriptors::Kind kind) { |
1855 __ call(label); | 1916 __ call(label); |
1856 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index); | 1917 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index); |
1857 } | 1918 } |
1858 | 1919 |
1859 | 1920 |
(...skipping 12 matching lines...) Expand all Loading... |
1872 intptr_t token_index, | 1933 intptr_t token_index, |
1873 intptr_t try_index) { | 1934 intptr_t try_index) { |
1874 pc_descriptors_list_->AddDescriptor(kind, | 1935 pc_descriptors_list_->AddDescriptor(kind, |
1875 assembler_->CodeSize(), | 1936 assembler_->CodeSize(), |
1876 cid, | 1937 cid, |
1877 token_index, | 1938 token_index, |
1878 try_index); | 1939 try_index); |
1879 } | 1940 } |
1880 | 1941 |
1881 | 1942 |
| 1943 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, |
| 1944 intptr_t deopt_token_index, |
| 1945 intptr_t try_index, |
| 1946 DeoptReasonId reason, |
| 1947 Register reg1, |
| 1948 Register reg2) { |
| 1949 DeoptimizationStub* stub = |
| 1950 new DeoptimizationStub(deopt_id, deopt_token_index, try_index, reason); |
| 1951 stub->Push(reg1); |
| 1952 stub->Push(reg2); |
| 1953 deopt_stubs_.Add(stub); |
| 1954 return stub->entry_label(); |
| 1955 } |
| 1956 |
| 1957 |
1882 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { | 1958 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { |
1883 ASSERT(pc_descriptors_list_ != NULL); | 1959 ASSERT(pc_descriptors_list_ != NULL); |
1884 const PcDescriptors& descriptors = PcDescriptors::Handle( | 1960 const PcDescriptors& descriptors = PcDescriptors::Handle( |
1885 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); | 1961 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); |
1886 descriptors.Verify(parsed_function_.function().is_optimizable()); | 1962 descriptors.Verify(parsed_function_.function().is_optimizable()); |
1887 code.set_pc_descriptors(descriptors); | 1963 code.set_pc_descriptors(descriptors); |
1888 } | 1964 } |
1889 | 1965 |
1890 | 1966 |
1891 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { | 1967 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { |
(...skipping 14 matching lines...) Expand all Loading... |
1906 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( | 1982 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( |
1907 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); | 1983 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); |
1908 code.set_exception_handlers(handlers); | 1984 code.set_exception_handlers(handlers); |
1909 } | 1985 } |
1910 | 1986 |
1911 | 1987 |
1912 void FlowGraphCompiler::FinalizeComments(const Code& code) { | 1988 void FlowGraphCompiler::FinalizeComments(const Code& code) { |
1913 code.set_comments(assembler_->GetCodeComments()); | 1989 code.set_comments(assembler_->GetCodeComments()); |
1914 } | 1990 } |
1915 | 1991 |
| 1992 #undef __ |
1916 | 1993 |
1917 } // namespace dart | 1994 } // namespace dart |
1918 | 1995 |
1919 #endif // defined TARGET_ARCH_X64 | 1996 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |