| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 PcDescriptors::kFuncCall); | 185 PcDescriptors::kFuncCall); |
| 186 __ addq(RSP, Immediate(argument_count * kWordSize)); | 186 __ addq(RSP, Immediate(argument_count * kWordSize)); |
| 187 } | 187 } |
| 188 | 188 |
| 189 | 189 |
| 190 void FlowGraphCompiler::VisitCurrentContext(CurrentContextComp* comp) { | 190 void FlowGraphCompiler::VisitCurrentContext(CurrentContextComp* comp) { |
| 191 __ movq(RAX, CTX); | 191 __ movq(RAX, CTX); |
| 192 } | 192 } |
| 193 | 193 |
| 194 | 194 |
| 195 void FlowGraphCompiler::VisitStoreContext(StoreContextComp* comp) { |
| 196 LoadValue(CTX, comp->value()); |
| 197 } |
| 198 |
| 199 |
| 195 void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) { | 200 void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) { |
| 196 ASSERT(comp->context()->IsTemp()); | 201 ASSERT(comp->context()->IsTemp()); |
| 197 ASSERT(VerifyCallComputation(comp)); | 202 ASSERT(VerifyCallComputation(comp)); |
| 198 // The arguments to the stub include the closure. The arguments | 203 // The arguments to the stub include the closure. The arguments |
| 199 // descriptor describes the closure's arguments (and so does not include | 204 // descriptor describes the closure's arguments (and so does not include |
| 200 // the closure). | 205 // the closure). |
| 201 int argument_count = comp->ArgumentCount(); | 206 int argument_count = comp->ArgumentCount(); |
| 202 const Array& arguments_descriptor = | 207 const Array& arguments_descriptor = |
| 203 CodeGenerator::ArgumentsDescriptor(argument_count - 1, | 208 CodeGenerator::ArgumentsDescriptor(argument_count - 1, |
| 204 comp->argument_names()); | 209 comp->argument_names()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 ASSERT(VerifyCallComputation(comp)); | 252 ASSERT(VerifyCallComputation(comp)); |
| 248 EmitStaticCall(comp->token_index(), | 253 EmitStaticCall(comp->token_index(), |
| 249 comp->function(), | 254 comp->function(), |
| 250 comp->ArgumentCount(), | 255 comp->ArgumentCount(), |
| 251 comp->argument_names()); | 256 comp->argument_names()); |
| 252 } | 257 } |
| 253 | 258 |
| 254 | 259 |
| 255 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) { | 260 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) { |
| 256 if (comp->local().is_captured()) { | 261 if (comp->local().is_captured()) { |
| 257 Bailout("load of context variable"); | 262 // The variable lives in the context. |
| 263 intptr_t delta = comp->context_level() - |
| 264 comp->local().owner()->context_level(); |
| 265 ASSERT(delta >= 0); |
| 266 Register base = CTX; |
| 267 while (delta-- > 0) { |
| 268 __ movq(RAX, FieldAddress(base, Context::parent_offset())); |
| 269 base = RAX; |
| 270 } |
| 271 __ movq(RAX, |
| 272 FieldAddress(base, |
| 273 Context::variable_offset(comp->local().index()))); |
| 274 } else { |
| 275 // The variable lives in the current stack frame. |
| 276 __ movq(RAX, Address(RBP, comp->local().index() * kWordSize)); |
| 258 } | 277 } |
| 259 __ movq(RAX, Address(RBP, comp->local().index() * kWordSize)); | |
| 260 } | 278 } |
| 261 | 279 |
| 262 | 280 |
| 263 void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) { | 281 void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) { |
| 282 LoadValue(RAX, comp->value()); |
| 264 if (comp->local().is_captured()) { | 283 if (comp->local().is_captured()) { |
| 265 Bailout("store to context variable"); | 284 // The variable lives in the context. |
| 285 Register scratch = R10; |
| 286 intptr_t delta = comp->context_level() - |
| 287 comp->local().owner()->context_level(); |
| 288 ASSERT(delta >= 0); |
| 289 Register base = CTX; |
| 290 while (delta-- > 0) { |
| 291 __ movq(scratch, FieldAddress(base, Context::parent_offset())); |
| 292 base = scratch; |
| 293 } |
| 294 __ StoreIntoObject( |
| 295 base, |
| 296 FieldAddress(base, Context::variable_offset(comp->local().index())), |
| 297 RAX); |
| 298 } else { |
| 299 // The variable lives in the current stack frame. |
| 300 __ movq(Address(RBP, comp->local().index() * kWordSize), RAX); |
| 266 } | 301 } |
| 267 LoadValue(RAX, comp->value()); | |
| 268 __ movq(Address(RBP, comp->local().index() * kWordSize), RAX); | |
| 269 } | 302 } |
| 270 | 303 |
| 271 | 304 |
| 272 void FlowGraphCompiler::VisitNativeCall(NativeCallComp* comp) { | 305 void FlowGraphCompiler::VisitNativeCall(NativeCallComp* comp) { |
| 273 // Push the result place holder initialized to NULL. | 306 // Push the result place holder initialized to NULL. |
| 274 __ PushObject(Object::ZoneHandle()); | 307 __ PushObject(Object::ZoneHandle()); |
| 275 // Pass a pointer to the first argument in RAX. | 308 // Pass a pointer to the first argument in RAX. |
| 276 if (!comp->has_optional_parameters()) { | 309 if (!comp->has_optional_parameters()) { |
| 277 __ leaq(RAX, Address(RBP, (1 + comp->argument_count()) * kWordSize)); | 310 __ leaq(RAX, Address(RBP, (1 + comp->argument_count()) * kWordSize)); |
| 278 } else { | 311 } else { |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 // instantiated type arguments, reset instantiator to null. | 777 // instantiated type arguments, reset instantiator to null. |
| 745 __ movq(RAX, raw_null); // Null instantiator. | 778 __ movq(RAX, raw_null); // Null instantiator. |
| 746 __ Bind(&use_instantiator); // Use instantiator in RAX. | 779 __ Bind(&use_instantiator); // Use instantiator in RAX. |
| 747 } | 780 } |
| 748 // In the non-factory case, we rely on the allocation stub to | 781 // In the non-factory case, we rely on the allocation stub to |
| 749 // instantiate the type arguments. | 782 // instantiate the type arguments. |
| 750 // RAX: instantiator or null. | 783 // RAX: instantiator or null. |
| 751 } | 784 } |
| 752 | 785 |
| 753 | 786 |
| 787 void FlowGraphCompiler::VisitAllocateContext(AllocateContextComp* comp) { |
| 788 __ movq(R10, Immediate(comp->num_context_variables())); |
| 789 const ExternalLabel label("alloc_context", |
| 790 StubCode::AllocateContextEntryPoint()); |
| 791 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther); |
| 792 } |
| 793 |
| 794 |
| 795 void FlowGraphCompiler::VisitChainContext(ChainContextComp* comp) { |
| 796 __ popq(RAX); |
| 797 // Chain the new context in RAX to its parent in CTX. |
| 798 __ StoreIntoObject(RAX, |
| 799 FieldAddress(RAX, Context::parent_offset()), |
| 800 CTX); |
| 801 // Set new context as current context. |
| 802 __ movq(CTX, RAX); |
| 803 } |
| 804 |
| 805 |
| 754 void FlowGraphCompiler::VisitBlocks() { | 806 void FlowGraphCompiler::VisitBlocks() { |
| 755 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 807 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 756 // Compile the block entry. | 808 // Compile the block entry. |
| 757 current_block_ = block_order_[i]; | 809 current_block_ = block_order_[i]; |
| 758 Instruction* instr = current_block()->Accept(this); | 810 Instruction* instr = current_block()->Accept(this); |
| 759 // Compile all successors until an exit, branch, or a block entry. | 811 // Compile all successors until an exit, branch, or a block entry. |
| 760 while ((instr != NULL) && !instr->IsBlockEntry()) { | 812 while ((instr != NULL) && !instr->IsBlockEntry()) { |
| 761 instr = instr->Accept(this); | 813 instr = instr->Accept(this); |
| 762 } | 814 } |
| 763 | 815 |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1218 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { | 1270 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { |
| 1219 // We don't compile exception handlers yet. | 1271 // We don't compile exception handlers yet. |
| 1220 code.set_exception_handlers( | 1272 code.set_exception_handlers( |
| 1221 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); | 1273 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); |
| 1222 } | 1274 } |
| 1223 | 1275 |
| 1224 | 1276 |
| 1225 } // namespace dart | 1277 } // namespace dart |
| 1226 | 1278 |
| 1227 #endif // defined TARGET_ARCH_X64 | 1279 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |