Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: runtime/vm/flow_graph_compiler.cc

Issue 10823308: Implement basic support for deferred slow path code with calls that save and restore live registers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Kevin's comments Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 } 198 }
199 199
200 200
201 bool FlowGraphCompiler::IsNextBlock(BlockEntryInstr* block_entry) const { 201 bool FlowGraphCompiler::IsNextBlock(BlockEntryInstr* block_entry) const {
202 intptr_t current_index = reverse_index(current_block()->postorder_number()); 202 intptr_t current_index = reverse_index(current_block()->postorder_number());
203 return (current_index < (block_order().length() - 1)) && 203 return (current_index < (block_order().length() - 1)) &&
204 (block_order()[current_index + 1] == block_entry); 204 (block_order()[current_index + 1] == block_entry);
205 } 205 }
206 206
207 207
208 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
209 // TODO(vegorov): consider saving only caller save (volatile) registers.
210 for (intptr_t reg_idx = 0; reg_idx < kNumberOfCpuRegisters; ++reg_idx) {
211 Register reg = static_cast<Register>(reg_idx);
212 if (locs->live_registers()->Contains(reg)) {
213 assembler()->PushRegister(reg);
srdjan 2012/08/15 00:12:03 How does GC work here, e.g., if a register contain
Kevin Millikin (Google) 2012/08/15 08:02:15 Exactly. It works now but needs to be changed whe
214 }
215 }
216 }
217
218
219 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
220 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
221 Register reg = static_cast<Register>(reg_idx);
222 if (locs->live_registers()->Contains(reg)) {
223 assembler()->PopRegister(reg);
224 }
225 }
226 }
227
228
229 void FlowGraphCompiler::AddSlowPathCode(SlowPathCode* code) {
230 slow_path_code_.Add(code);
231 }
232
233
208 void FlowGraphCompiler::GenerateDeferredCode() { 234 void FlowGraphCompiler::GenerateDeferredCode() {
235 for (intptr_t i = 0; i < slow_path_code_.length(); i++) {
236 slow_path_code_[i]->EmitNativeCode(this);
237 }
209 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) { 238 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) {
210 deopt_stubs_[i]->GenerateCode(this, i); 239 deopt_stubs_[i]->GenerateCode(this, i);
211 } 240 }
212 } 241 }
213 242
214 243
215 void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index, 244 void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index,
216 intptr_t pc_offset) { 245 intptr_t pc_offset) {
217 exception_handlers_list_->AddHandler(try_index, pc_offset); 246 exception_handlers_list_->AddHandler(try_index, pc_offset);
218 } 247 }
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 locs->set_in(i, Location::RegisterLocation(reg)); 700 locs->set_in(i, Location::RegisterLocation(reg));
672 } 701 }
673 702
674 // Inputs are consumed from the simulated frame. In case of a call argument 703 // Inputs are consumed from the simulated frame. In case of a call argument
675 // we leave it until the call instruction. 704 // we leave it until the call instruction.
676 if (!instr->IsPushArgument()) Pop(reg, instr->InputAt(i)); 705 if (!instr->IsPushArgument()) Pop(reg, instr->InputAt(i));
677 } 706 }
678 707
679 // If this instruction is call spill everything that was not consumed by 708 // If this instruction is call spill everything that was not consumed by
680 // input locations. 709 // input locations.
681 if (locs->is_call() || instr->IsBranch() || instr->IsGoto()) { 710 if (locs->contains_call() || instr->IsBranch() || instr->IsGoto()) {
682 Spill(); 711 Spill();
683 } 712 }
684 713
685 // Allocate all unallocated temp locations. 714 // Allocate all unallocated temp locations.
686 for (intptr_t i = 0; i < locs->temp_count(); i++) { 715 for (intptr_t i = 0; i < locs->temp_count(); i++) {
687 Location loc = locs->temp(i); 716 Location loc = locs->temp(i);
688 if (loc.IsUnallocated()) { 717 if (loc.IsUnallocated()) {
689 ASSERT(loc.policy() == Location::kRequiresRegister); 718 ASSERT(loc.policy() == Location::kRequiresRegister);
690 loc = Location::RegisterLocation( 719 loc = Location::RegisterLocation(
691 AllocateFreeRegister(blocked_registers)); 720 AllocateFreeRegister(blocked_registers));
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 return; 897 return;
869 } 898 }
870 } 899 }
871 900
872 // This move is not blocked. 901 // This move is not blocked.
873 EmitMove(index); 902 EmitMove(index);
874 } 903 }
875 904
876 905
877 } // namespace dart 906 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698