Chromium Code Reviews| Index: runtime/vm/flow_graph_compiler_ia32.cc |
| diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc |
| index a81a07587378194695e00deffdf6529fce7b94b8..d563434f0f83ef4746819304705659b6f0e234aa 100644 |
| --- a/runtime/vm/flow_graph_compiler_ia32.cc |
| +++ b/runtime/vm/flow_graph_compiler_ia32.cc |
| @@ -28,11 +28,34 @@ void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler) { |
| #define __ assem-> |
| __ Comment("Deopt stub for id %d", deopt_id_); |
| __ Bind(entry_label()); |
| - for (intptr_t i = 0; i < registers_.length(); i++) { |
| - if (registers_[i] != kNoRegister) { |
| - __ pushl(registers_[i]); |
| + |
| + if (deoptimization_env_ == NULL) { |
|
srdjan
2012/07/11 17:22:32
ASSERT in ia32 that deoptimization_env_ == NULL (s
|
| + for (intptr_t i = 0; i < registers_.length(); i++) { |
| + if (registers_[i] != kNoRegister) { |
| + __ pushl(registers_[i]); |
| + } |
| + } |
| + } else { |
| + // We have a deoptimization environment, we have to tear down optimized |
| + // frame and recreate non-optimized one. |
| + __ leal(ESP, |
| + Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
| + |
| + const ZoneGrowableArray<Value*>& values = deoptimization_env_->values(); |
| + const GrowableArray<Location>* locations = deoptimization_env_->locations(); |
| + |
| + for (intptr_t i = 0; i < values.length(); i++) { |
| + Location loc = (*locations)[i]; |
| + if (loc.IsInvalid()) { |
| + ASSERT(values[i]->IsConstant()); |
| + __ PushObject(values[i]->AsConstant()->value()); |
| + } else { |
| + ASSERT(loc.IsRegister()); |
| + __ pushl(loc.reg()); |
| + } |
| } |
| } |
| + |
| if (compiler->IsLeaf()) { |
| Label L; |
| __ call(&L); |
| @@ -1077,6 +1100,50 @@ void FlowGraphCompiler::LoadDoubleOrSmiToXmm(XmmRegister result, |
| #undef __ |
| +#define __ compiler_->assembler()-> |
| + |
| + |
| +void ParallelMoveResolver::EmitMove(int index) { |
| + Location source = moves_[index].src(); |
| + Location destination = moves_[index].dest(); |
| + |
| + ASSERT(destination.IsRegister()); |
| + if (source.IsRegister()) { |
| + __ movl(destination.reg(), source.reg()); |
| + } else { |
| + ASSERT(source.IsConstant()); |
| + __ LoadObject(destination.reg(), source.constant()); |
| + } |
| + moves_[index].Eliminate(); |
| +} |
| + |
| + |
| +void ParallelMoveResolver::EmitSwap(int index) { |
| + Location source = moves_[index].src(); |
| + Location destination = moves_[index].dest(); |
| + |
| + ASSERT(source.IsRegister() && destination.IsRegister()); |
| + __ xchgl(destination.reg(), source.reg()); |
| + |
| + // The swap of source and destination has executed a move from source to |
| + // destination. |
| + moves_[index].Eliminate(); |
| + |
| + // Any unperformed (including pending) move with a source of either |
| + // this move's source or destination needs to have their source |
| + // changed to reflect the state of affairs after the swap. |
| + for (int i = 0; i < moves_.length(); ++i) { |
| + MoveOperands other_move = moves_[i]; |
| + if (other_move.Blocks(source)) { |
| + moves_[i].set_src(destination); |
| + } else if (other_move.Blocks(destination)) { |
| + moves_[i].set_src(source); |
| + } |
| + } |
| +} |
| + |
| + |
| +#undef __ |
| } // namespace dart |