| 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 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 reg = AllocateFreeRegister(blocked_registers); | 595 reg = AllocateFreeRegister(blocked_registers); |
| 598 } | 596 } |
| 599 locs->set_in(i, Location::RegisterLocation(reg)); | 597 locs->set_in(i, Location::RegisterLocation(reg)); |
| 600 } | 598 } |
| 601 | 599 |
| 602 Pop(reg, instr->InputAt(i)); | 600 Pop(reg, instr->InputAt(i)); |
| 603 } | 601 } |
| 604 | 602 |
| 605 // If this instruction is call spill everything that was not consumed by | 603 // If this instruction is call spill everything that was not consumed by |
| 606 // input locations. | 604 // input locations. |
| 607 if (locs->is_call() || instr->IsBranch()) { | 605 if (locs->is_call() || instr->IsBranch() || instr->IsGoto()) { |
| 608 Spill(); | 606 Spill(); |
| 609 } | 607 } |
| 610 | 608 |
| 611 // Allocate all unallocated temp locations. | 609 // Allocate all unallocated temp locations. |
| 612 for (intptr_t i = 0; i < locs->temp_count(); i++) { | 610 for (intptr_t i = 0; i < locs->temp_count(); i++) { |
| 613 Location loc = locs->temp(i); | 611 Location loc = locs->temp(i); |
| 614 if (loc.IsUnallocated()) { | 612 if (loc.IsUnallocated()) { |
| 615 ASSERT(loc.policy() == Location::kRequiresRegister); | 613 ASSERT(loc.policy() == Location::kRequiresRegister); |
| 616 loc = Location::RegisterLocation( | 614 loc = Location::RegisterLocation( |
| 617 AllocateFreeRegister(blocked_registers)); | 615 AllocateFreeRegister(blocked_registers)); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 return; | 790 return; |
| 793 } | 791 } |
| 794 } | 792 } |
| 795 | 793 |
| 796 // This move is not blocked. | 794 // This move is not blocked. |
| 797 EmitMove(index); | 795 EmitMove(index); |
| 798 } | 796 } |
| 799 | 797 |
| 800 | 798 |
| 801 } // namespace dart | 799 } // namespace dart |
| OLD | NEW |