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