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 |