| 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" |
| 11 #include "vm/ast_printer.h" | 11 #include "vm/ast_printer.h" |
| 12 #include "vm/code_descriptors.h" | 12 #include "vm/code_descriptors.h" |
| 13 #include "vm/code_generator.h" | 13 #include "vm/code_generator.h" |
| 14 #include "vm/disassembler.h" | 14 #include "vm/disassembler.h" |
| 15 #include "vm/il_printer.h" | 15 #include "vm/il_printer.h" |
| 16 #include "vm/locations.h" | 16 #include "vm/locations.h" |
| 17 #include "vm/object_store.h" | 17 #include "vm/object_store.h" |
| 18 #include "vm/parser.h" | 18 #include "vm/parser.h" |
| 19 #include "vm/stub_code.h" | 19 #include "vm/stub_code.h" |
| 20 | 20 |
| 21 namespace dart { | 21 namespace dart { |
| 22 | 22 |
| 23 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); | 23 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); |
| 24 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); | 24 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); |
| 25 DECLARE_FLAG(bool, enable_type_checks); | 25 DECLARE_FLAG(bool, enable_type_checks); |
| 26 DECLARE_FLAG(bool, print_ast); | 26 DECLARE_FLAG(bool, print_ast); |
| 27 DECLARE_FLAG(bool, code_comments); | |
| 28 | 27 |
| 29 | 28 |
| 30 void DeoptimizationStub::GenerateCode(FlowGraphCompilerShared* compiler) { | 29 void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler) { |
| 31 Assembler* assem = compiler->assembler(); | 30 Assembler* assem = compiler->assembler(); |
| 32 #define __ assem-> | 31 #define __ assem-> |
| 33 __ Comment("Deopt stub for id %d", deopt_id_); | 32 __ Comment("Deopt stub for id %d", deopt_id_); |
| 34 __ Bind(entry_label()); | 33 __ Bind(entry_label()); |
| 35 for (intptr_t i = 0; i < registers_.length(); i++) { | 34 for (intptr_t i = 0; i < registers_.length(); i++) { |
| 36 if (registers_[i] != kNoRegister) { | 35 if (registers_[i] != kNoRegister) { |
| 37 __ pushq(registers_[i]); | 36 __ pushq(registers_[i]); |
| 38 } | 37 } |
| 39 } | 38 } |
| 40 __ movq(RAX, Immediate(Smi::RawValue(reason_))); | 39 __ movq(RAX, Immediate(Smi::RawValue(reason_))); |
| 41 __ call(&StubCode::DeoptimizeLabel()); | 40 __ call(&StubCode::DeoptimizeLabel()); |
| 42 compiler->AddCurrentDescriptor(PcDescriptors::kOther, | 41 compiler->AddCurrentDescriptor(PcDescriptors::kOther, |
| 43 deopt_id_, | 42 deopt_id_, |
| 44 deopt_token_index_, | 43 deopt_token_index_, |
| 45 try_index_); | 44 try_index_); |
| 46 #undef __ | 45 #undef __ |
| 47 } | 46 } |
| 48 | 47 |
| 49 | 48 |
| 50 FlowGraphCompiler::FlowGraphCompiler( | |
| 51 Assembler* assembler, | |
| 52 const ParsedFunction& parsed_function, | |
| 53 const GrowableArray<BlockEntryInstr*>& block_order, | |
| 54 bool is_optimizing) | |
| 55 : FlowGraphCompilerShared(assembler, | |
| 56 parsed_function, | |
| 57 block_order, | |
| 58 is_optimizing) {} | |
| 59 | |
| 60 #define __ assembler()-> | 49 #define __ assembler()-> |
| 61 | 50 |
| 62 | 51 |
| 63 | 52 |
| 64 // Fall through if bool_register contains null. | 53 // Fall through if bool_register contains null. |
| 65 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, | 54 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, |
| 66 Label* is_true, | 55 Label* is_true, |
| 67 Label* is_false) { | 56 Label* is_false) { |
| 68 const Immediate raw_null = | 57 const Immediate raw_null = |
| 69 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 58 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 | 641 |
| 653 // Load instruction inputs into allocated registers. | 642 // Load instruction inputs into allocated registers. |
| 654 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) { | 643 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) { |
| 655 Location loc = locs->in(i); | 644 Location loc = locs->in(i); |
| 656 ASSERT(loc.kind() == Location::kRegister); | 645 ASSERT(loc.kind() == Location::kRegister); |
| 657 __ popq(loc.reg()); | 646 __ popq(loc.reg()); |
| 658 } | 647 } |
| 659 } | 648 } |
| 660 | 649 |
| 661 | 650 |
| 662 void FlowGraphCompiler::VisitBlocks() { | |
| 663 for (intptr_t i = 0; i < block_order().length(); ++i) { | |
| 664 __ Comment("B%d", i); | |
| 665 // Compile the block entry. | |
| 666 set_current_block(block_order()[i]); | |
| 667 current_block()->PrepareEntry(this); | |
| 668 Instruction* instr = current_block()->StraightLineSuccessor(); | |
| 669 // Compile all successors until an exit, branch, or a block entry. | |
| 670 while ((instr != NULL) && !instr->IsBlockEntry()) { | |
| 671 if (FLAG_code_comments) EmitComment(instr); | |
| 672 ASSERT(instr->locs() != NULL); | |
| 673 EmitInstructionPrologue(instr); | |
| 674 instr->EmitNativeCode(this); | |
| 675 instr = instr->StraightLineSuccessor(); | |
| 676 } | |
| 677 | |
| 678 BlockEntryInstr* successor = | |
| 679 (instr == NULL) ? NULL : instr->AsBlockEntry(); | |
| 680 if (successor != NULL) { | |
| 681 // Block ended with a "goto". We can fall through if it is the | |
| 682 // next block in the list. Otherwise, we need a jump. | |
| 683 if ((i == block_order().length() - 1) || | |
| 684 (block_order()[i + 1] != successor)) { | |
| 685 __ jmp(GetBlockLabel(successor)); | |
| 686 } | |
| 687 } | |
| 688 } | |
| 689 } | |
| 690 | |
| 691 | |
| 692 void FlowGraphCompiler::EmitComment(Instruction* instr) { | |
| 693 char buffer[80]; | |
| 694 BufferFormatter f(buffer, sizeof(buffer)); | |
| 695 instr->PrintTo(&f); | |
| 696 __ Comment("@%d: %s", instr->cid(), buffer); | |
| 697 } | |
| 698 | |
| 699 | |
| 700 // Copied from CodeGenerator::CopyParameters (CodeGenerator will be deprecated). | 651 // Copied from CodeGenerator::CopyParameters (CodeGenerator will be deprecated). |
| 701 void FlowGraphCompiler::CopyParameters() { | 652 void FlowGraphCompiler::CopyParameters() { |
| 702 const Function& function = parsed_function().function(); | 653 const Function& function = parsed_function().function(); |
| 703 LocalScope* scope = parsed_function().node_sequence()->scope(); | 654 LocalScope* scope = parsed_function().node_sequence()->scope(); |
| 704 const int num_fixed_params = function.num_fixed_parameters(); | 655 const int num_fixed_params = function.num_fixed_parameters(); |
| 705 const int num_opt_params = function.num_optional_parameters(); | 656 const int num_opt_params = function.num_optional_parameters(); |
| 706 ASSERT(parsed_function().first_parameter_index() == | 657 ASSERT(parsed_function().first_parameter_index() == |
| 707 ParsedFunction::kFirstLocalSlotIndex); | 658 ParsedFunction::kFirstLocalSlotIndex); |
| 708 // Copy positional arguments. | 659 // Copy positional arguments. |
| 709 // Check that no fewer than num_fixed_params positional arguments are passed | 660 // Check that no fewer than num_fixed_params positional arguments are passed |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 __ CallRuntime(entry); | 980 __ CallRuntime(entry); |
| 1030 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index); | 981 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index); |
| 1031 } | 982 } |
| 1032 | 983 |
| 1033 | 984 |
| 1034 #undef __ | 985 #undef __ |
| 1035 | 986 |
| 1036 } // namespace dart | 987 } // namespace dart |
| 1037 | 988 |
| 1038 #endif // defined TARGET_ARCH_X64 | 989 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |