| 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_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 ASSERT(instr->locs() != NULL); | 111 ASSERT(instr->locs() != NULL); |
| 112 EmitInstructionPrologue(instr); | 112 EmitInstructionPrologue(instr); |
| 113 pending_deoptimization_env_ = instr->env(); | 113 pending_deoptimization_env_ = instr->env(); |
| 114 instr->EmitNativeCode(this); | 114 instr->EmitNativeCode(this); |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 if (instr->next() != NULL) { | 117 if (instr->next() != NULL) { |
| 118 BlockEntryInstr* successor = instr->next()->AsBlockEntry(); | 118 BlockEntryInstr* successor = instr->next()->AsBlockEntry(); |
| 119 ASSERT(successor != NULL); | 119 ASSERT(successor != NULL); |
| 120 frame_register_allocator()->Spill(); | 120 frame_register_allocator()->Spill(); |
| 121 // The block ended with a "goto". We can fall through if it is the | 121 if (!IsNextBlock(successor)) { |
| 122 // next block in the list. Otherwise, we need a jump. | |
| 123 if ((i == block_order().length() - 1) || | |
| 124 (block_order()[i + 1] != successor)) { | |
| 125 assembler()->jmp(GetBlockLabel(successor)); | 122 assembler()->jmp(GetBlockLabel(successor)); |
| 126 } | 123 } |
| 127 } | 124 } |
| 128 } | 125 } |
| 129 } | 126 } |
| 130 | 127 |
| 131 | 128 |
| 132 void FlowGraphCompiler::Bailout(const char* reason) { | 129 void FlowGraphCompiler::Bailout(const char* reason) { |
| 133 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; | 130 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; |
| 134 const char* function_name = parsed_function().function().ToCString(); | 131 const char* function_name = parsed_function().function().ToCString(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 148 } | 145 } |
| 149 | 146 |
| 150 | 147 |
| 151 Label* FlowGraphCompiler::GetBlockLabel( | 148 Label* FlowGraphCompiler::GetBlockLabel( |
| 152 BlockEntryInstr* block_entry) const { | 149 BlockEntryInstr* block_entry) const { |
| 153 intptr_t block_index = block_entry->postorder_number(); | 150 intptr_t block_index = block_entry->postorder_number(); |
| 154 return &block_info_[block_index]->label; | 151 return &block_info_[block_index]->label; |
| 155 } | 152 } |
| 156 | 153 |
| 157 | 154 |
| 158 bool FlowGraphCompiler::IsNextBlock(TargetEntryInstr* block_entry) const { | 155 bool FlowGraphCompiler::IsNextBlock(BlockEntryInstr* block_entry) const { |
| 159 intptr_t current_index = reverse_index(current_block()->postorder_number()); | 156 intptr_t current_index = reverse_index(current_block()->postorder_number()); |
| 160 return block_order_[current_index + 1] == block_entry; | 157 return (current_index < (block_order().length() - 1)) && |
| 158 (block_order()[current_index + 1] == block_entry); |
| 161 } | 159 } |
| 162 | 160 |
| 163 | 161 |
| 164 void FlowGraphCompiler::GenerateDeferredCode() { | 162 void FlowGraphCompiler::GenerateDeferredCode() { |
| 165 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) { | 163 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) { |
| 166 deopt_stubs_[i]->GenerateCode(this); | 164 deopt_stubs_[i]->GenerateCode(this); |
| 167 } | 165 } |
| 168 } | 166 } |
| 169 | 167 |
| 170 | 168 |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 reg = AllocateFreeRegister(blocked_registers); | 596 reg = AllocateFreeRegister(blocked_registers); |
| 599 } | 597 } |
| 600 locs->set_in(i, Location::RegisterLocation(reg)); | 598 locs->set_in(i, Location::RegisterLocation(reg)); |
| 601 } | 599 } |
| 602 | 600 |
| 603 Pop(reg, instr->InputAt(i)); | 601 Pop(reg, instr->InputAt(i)); |
| 604 } | 602 } |
| 605 | 603 |
| 606 // If this instruction is call spill everything that was not consumed by | 604 // If this instruction is call spill everything that was not consumed by |
| 607 // input locations. | 605 // input locations. |
| 608 if (locs->is_call() || instr->IsBranch()) { | 606 if (locs->is_call() || instr->IsBranch() || instr->IsGoto()) { |
| 609 Spill(); | 607 Spill(); |
| 610 } | 608 } |
| 611 | 609 |
| 612 // Allocate all unallocated temp locations. | 610 // Allocate all unallocated temp locations. |
| 613 for (intptr_t i = 0; i < locs->temp_count(); i++) { | 611 for (intptr_t i = 0; i < locs->temp_count(); i++) { |
| 614 Location loc = locs->temp(i); | 612 Location loc = locs->temp(i); |
| 615 if (loc.IsUnallocated()) { | 613 if (loc.IsUnallocated()) { |
| 616 ASSERT(loc.policy() == Location::kRequiresRegister); | 614 ASSERT(loc.policy() == Location::kRequiresRegister); |
| 617 loc = Location::RegisterLocation( | 615 loc = Location::RegisterLocation( |
| 618 AllocateFreeRegister(blocked_registers)); | 616 AllocateFreeRegister(blocked_registers)); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 return; | 791 return; |
| 794 } | 792 } |
| 795 } | 793 } |
| 796 | 794 |
| 797 // This move is not blocked. | 795 // This move is not blocked. |
| 798 EmitMove(index); | 796 EmitMove(index); |
| 799 } | 797 } |
| 800 | 798 |
| 801 | 799 |
| 802 } // namespace dart | 800 } // namespace dart |
| OLD | NEW |