Chromium Code Reviews| Index: runtime/vm/flow_graph_compiler_x64.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_compiler_x64.cc (revision 5781) |
| +++ runtime/vm/flow_graph_compiler_x64.cc (working copy) |
| @@ -192,6 +192,12 @@ |
| } |
| +void FlowGraphCompiler::VisitStoreContext(StoreContextComp* comp) { |
| + LoadValue(RAX, comp->value()); |
| + __ movq(CTX, RAX); |
|
regis
2012/03/23 20:50:25
Why not load directly into CTX?
srdjan
2012/03/23 21:22:19
Done.
|
| +} |
| + |
| + |
| void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) { |
| ASSERT(comp->context()->IsTemp()); |
| ASSERT(VerifyCallComputation(comp)); |
| @@ -254,18 +260,46 @@ |
| void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) { |
| if (comp->local().is_captured()) { |
| - Bailout("load of context variable"); |
| + // The variable lives in the context. |
| + intptr_t delta = comp->context_level() - |
| + comp->local().owner()->context_level(); |
| + ASSERT(delta >= 0); |
| + Register base = CTX; |
| + while (delta-- > 0) { |
| + __ movq(RAX, FieldAddress(base, Context::parent_offset())); |
| + base = RAX; |
| + } |
| + __ movq(RAX, |
| + FieldAddress(base, |
| + Context::variable_offset(comp->local().index()))); |
| + } else { |
| + // The variable lives in the current stack frame. |
| + __ movq(RAX, Address(RBP, comp->local().index() * kWordSize)); |
| } |
| - __ movq(RAX, Address(RBP, comp->local().index() * kWordSize)); |
| } |
| void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) { |
| + LoadValue(RAX, comp->value()); |
| if (comp->local().is_captured()) { |
| - Bailout("store to context variable"); |
| + // The variable lives in the context. |
| + Register scratch = R10; |
| + intptr_t delta = comp->context_level() - |
| + comp->local().owner()->context_level(); |
| + ASSERT(delta >= 0); |
| + Register base = CTX; |
| + while (delta-- > 0) { |
| + __ movq(scratch, FieldAddress(base, Context::parent_offset())); |
| + base = scratch; |
| + } |
| + __ StoreIntoObject( |
| + base, |
| + FieldAddress(base, Context::variable_offset(comp->local().index())), |
| + RAX); |
| + } else { |
| + // The variable lives in the current stack frame. |
| + __ movq(Address(RBP, comp->local().index() * kWordSize), RAX); |
| } |
| - LoadValue(RAX, comp->value()); |
| - __ movq(Address(RBP, comp->local().index() * kWordSize), RAX); |
| } |
| @@ -751,6 +785,25 @@ |
| } |
| +void FlowGraphCompiler::VisitAllocateContext(AllocateContextComp* comp) { |
| + __ movq(R10, Immediate(comp->num_context_variables())); |
| + const ExternalLabel label("alloc_context", |
| + StubCode::AllocateContextEntryPoint()); |
| + GenerateCall(comp->token_index(), &label, PcDescriptors::kOther); |
| +} |
| + |
| + |
| +void FlowGraphCompiler::VisitChainContext(ChainContextComp* comp) { |
| + __ popq(RAX); |
| + // Chain the new context in RAX to its parent in CTX. |
| + __ StoreIntoObject(RAX, |
| + FieldAddress(RAX, Context::parent_offset()), |
| + CTX); |
| + // Set new context as current context. |
| + __ movq(CTX, RAX); |
| +} |
| + |
| + |
| void FlowGraphCompiler::VisitBlocks() { |
| for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| // Compile the block entry. |