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/debugger.h" | 14 #include "vm/debugger.h" |
15 #include "vm/disassembler.h" | 15 #include "vm/disassembler.h" |
16 #include "vm/il_printer.h" | 16 #include "vm/il_printer.h" |
17 #include "vm/intrinsifier.h" | 17 #include "vm/intrinsifier.h" |
18 #include "vm/locations.h" | |
18 #include "vm/longjump.h" | 19 #include "vm/longjump.h" |
19 #include "vm/object_store.h" | 20 #include "vm/object_store.h" |
20 #include "vm/parser.h" | 21 #include "vm/parser.h" |
21 #include "vm/stub_code.h" | 22 #include "vm/stub_code.h" |
22 | 23 |
23 namespace dart { | 24 namespace dart { |
24 | 25 |
25 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); | 26 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); |
26 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); | 27 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); |
27 DECLARE_FLAG(bool, enable_type_checks); | 28 DECLARE_FLAG(bool, enable_type_checks); |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
540 comp->token_index(), | 541 comp->token_index(), |
541 comp->try_index(), | 542 comp->try_index(), |
542 comp->function_name(), | 543 comp->function_name(), |
543 comp->ArgumentCount(), | 544 comp->ArgumentCount(), |
544 comp->argument_names(), | 545 comp->argument_names(), |
545 comp->checked_argument_count()); | 546 comp->checked_argument_count()); |
546 } | 547 } |
547 | 548 |
548 | 549 |
549 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) { | 550 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) { |
550 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 551 UNREACHABLE(); |
srdjan
2012/05/21 16:05:22
Why is that (add comment)? Wait, this is part of t
Vyacheslav Egorov (Google)
2012/05/21 19:53:46
Yes, native template were moved. I added a comment
| |
551 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
552 LoadValue(RDX, comp->right()); | |
553 LoadValue(RAX, comp->left()); | |
554 __ cmpq(RAX, RDX); | |
555 Label load_true, done; | |
556 if (comp->kind() == Token::kEQ_STRICT) { | |
557 __ j(EQUAL, &load_true, Assembler::kNearJump); | |
558 } else { | |
559 __ j(NOT_EQUAL, &load_true, Assembler::kNearJump); | |
560 } | |
561 __ LoadObject(RAX, bool_false); | |
562 __ jmp(&done, Assembler::kNearJump); | |
563 __ Bind(&load_true); | |
564 __ LoadObject(RAX, bool_true); | |
565 __ Bind(&done); | |
566 } | 552 } |
567 | 553 |
568 | 554 |
569 void FlowGraphCompiler::VisitEqualityCompare(EqualityCompareComp* comp) { | 555 void FlowGraphCompiler::VisitEqualityCompare(EqualityCompareComp* comp) { |
570 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 556 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
571 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 557 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
572 const Immediate raw_null = | 558 const Immediate raw_null = |
573 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 559 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
574 Label done, load_true, non_null_compare; | 560 Label done, load_true, non_null_compare; |
575 LoadValue(RDX, comp->right()); | 561 LoadValue(RDX, comp->right()); |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1115 | 1101 |
1116 ASSERT(!comp->exception_var().is_captured()); | 1102 ASSERT(!comp->exception_var().is_captured()); |
1117 ASSERT(!comp->stacktrace_var().is_captured()); | 1103 ASSERT(!comp->stacktrace_var().is_captured()); |
1118 __ movq(Address(RBP, comp->exception_var().index() * kWordSize), | 1104 __ movq(Address(RBP, comp->exception_var().index() * kWordSize), |
1119 kExceptionObjectReg); | 1105 kExceptionObjectReg); |
1120 __ movq(Address(RBP, comp->stacktrace_var().index() * kWordSize), | 1106 __ movq(Address(RBP, comp->stacktrace_var().index() * kWordSize), |
1121 kStackTraceObjectReg); | 1107 kStackTraceObjectReg); |
1122 } | 1108 } |
1123 | 1109 |
1124 | 1110 |
1111 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) { | |
1112 LocationSummary* locs = instr->locs(); | |
1113 ASSERT(locs != NULL); | |
1114 | |
1115 // TODO(vegorov): share this !!! | |
1116 locs->AllocateRegisters(); | |
1117 | |
1118 // Load instruction inputs into allocated registers. | |
1119 for (intptr_t i = locs->count() - 1; i >= 0; i--) { | |
1120 Location loc = locs->in(i); | |
1121 if (loc.kind() == Location::kRegister) { | |
1122 __ popq(loc.AsRegister()); | |
1123 } | |
srdjan
2012/05/21 16:05:22
else? UNIMPLEMENTED? check location is stack OK?
Vyacheslav Egorov (Google)
2012/05/21 19:53:46
Added assert.
| |
1124 } | |
1125 } | |
1126 | |
1127 | |
1125 void FlowGraphCompiler::VisitBlocks() { | 1128 void FlowGraphCompiler::VisitBlocks() { |
1126 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 1129 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
1127 __ Comment("B%d", i); | 1130 __ Comment("B%d", i); |
1128 // Compile the block entry. | 1131 // Compile the block entry. |
1129 current_block_ = block_order_[i]; | 1132 current_block_ = block_order_[i]; |
1130 Instruction* instr = current_block()->Accept(this); | 1133 Instruction* instr = current_block()->Accept(this); |
1131 // Compile all successors until an exit, branch, or a block entry. | 1134 // Compile all successors until an exit, branch, or a block entry. |
1132 while ((instr != NULL) && !instr->IsBlockEntry()) { | 1135 while ((instr != NULL) && !instr->IsBlockEntry()) { |
1133 if (FLAG_code_comments) EmitComment(instr); | 1136 if (FLAG_code_comments) EmitComment(instr); |
1134 instr = instr->Accept(this); | 1137 if (instr->locs() != NULL) { |
1138 EmitInstructionPrologue(instr); | |
1139 instr->EmitNativeCode(this); | |
1140 instr = instr->StraightLineSuccessor(); | |
1141 } else { | |
1142 instr = instr->Accept(this); | |
1143 } | |
1135 } | 1144 } |
1136 | 1145 |
1137 BlockEntryInstr* successor = | 1146 BlockEntryInstr* successor = |
1138 (instr == NULL) ? NULL : instr->AsBlockEntry(); | 1147 (instr == NULL) ? NULL : instr->AsBlockEntry(); |
1139 if (successor != NULL) { | 1148 if (successor != NULL) { |
1140 // Block ended with a "goto". We can fall through if it is the | 1149 // Block ended with a "goto". We can fall through if it is the |
1141 // next block in the list. Otherwise, we need a jump. | 1150 // next block in the list. Otherwise, we need a jump. |
1142 if ((i == block_order_.length() - 1) || | 1151 if ((i == block_order_.length() - 1) || |
1143 (block_order_[i + 1] != successor)) { | 1152 (block_order_[i + 1] != successor)) { |
1144 __ jmp(&block_info_[successor->postorder_number()]->label); | 1153 __ jmp(&block_info_[successor->postorder_number()]->label); |
(...skipping 29 matching lines...) Expand all Loading... | |
1174 } | 1183 } |
1175 } | 1184 } |
1176 | 1185 |
1177 | 1186 |
1178 void FlowGraphCompiler::VisitDo(DoInstr* instr) { | 1187 void FlowGraphCompiler::VisitDo(DoInstr* instr) { |
1179 instr->computation()->Accept(this); | 1188 instr->computation()->Accept(this); |
1180 } | 1189 } |
1181 | 1190 |
1182 | 1191 |
1183 void FlowGraphCompiler::VisitBind(BindInstr* instr) { | 1192 void FlowGraphCompiler::VisitBind(BindInstr* instr) { |
1193 ASSERT(instr->locs() == NULL); | |
1194 | |
1195 // If instruction does not have special location requirements | |
1196 // then it returns result in register RAX. | |
1184 instr->computation()->Accept(this); | 1197 instr->computation()->Accept(this); |
1185 __ pushq(RAX); | 1198 __ pushq(RAX); |
1186 } | 1199 } |
1187 | 1200 |
1188 | 1201 |
1189 void FlowGraphCompiler::VisitReturn(ReturnInstr* instr) { | 1202 void FlowGraphCompiler::VisitReturn(ReturnInstr* instr) { |
1190 LoadValue(RAX, instr->value()); | 1203 LoadValue(RAX, instr->value()); |
1191 if (!is_optimizing()) { | 1204 if (!is_optimizing()) { |
1192 // Count only in unoptimized code. | 1205 // Count only in unoptimized code. |
1193 // TODO(srdjan): Replace the counting code with a type feedback | 1206 // TODO(srdjan): Replace the counting code with a type feedback |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1714 | 1727 |
1715 | 1728 |
1716 void FlowGraphCompiler::FinalizeComments(const Code& code) { | 1729 void FlowGraphCompiler::FinalizeComments(const Code& code) { |
1717 code.set_comments(assembler_->GetCodeComments()); | 1730 code.set_comments(assembler_->GetCodeComments()); |
1718 } | 1731 } |
1719 | 1732 |
1720 | 1733 |
1721 } // namespace dart | 1734 } // namespace dart |
1722 | 1735 |
1723 #endif // defined TARGET_ARCH_X64 | 1736 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |