| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 __ pushq(RDX); // Instantiator type arguments. | 341 __ pushq(RDX); // Instantiator type arguments. |
| 342 } | 342 } |
| 343 __ PushObject(dst_name); // Push the name of the destination. | 343 __ PushObject(dst_name); // Push the name of the destination. |
| 344 __ pushq(raw_null); // SubtypeTestCache not yet supported. | 344 __ pushq(raw_null); // SubtypeTestCache not yet supported. |
| 345 GenerateCallRuntime(cid, | 345 GenerateCallRuntime(cid, |
| 346 token_index, | 346 token_index, |
| 347 try_index, | 347 try_index, |
| 348 kTypeCheckRuntimeEntry); | 348 kTypeCheckRuntimeEntry); |
| 349 // Pop the parameters supplied to the runtime entry. The result of the | 349 // Pop the parameters supplied to the runtime entry. The result of the |
| 350 // type check runtime call is the checked value. | 350 // type check runtime call is the checked value. |
| 351 __ addq(RSP, Immediate(8 * kWordSize)); | 351 __ Drop(8); |
| 352 __ popq(RAX); | 352 __ popq(RAX); |
| 353 | 353 |
| 354 __ Bind(&is_assignable); | 354 __ Bind(&is_assignable); |
| 355 } | 355 } |
| 356 | 356 |
| 357 | 357 |
| 358 void FlowGraphCompiler::LoadValue(Register dst, Value* value) { | 358 void FlowGraphCompiler::LoadValue(Register dst, Value* value) { |
| 359 if (value->IsConstant()) { | 359 if (value->IsConstant()) { |
| 360 ConstantVal* constant = value->AsConstant(); | 360 ConstantVal* constant = value->AsConstant(); |
| 361 if (constant->value().IsSmi()) { | 361 if (constant->value().IsSmi()) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 break; | 472 break; |
| 473 case 2: | 473 case 2: |
| 474 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); | 474 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); |
| 475 break; | 475 break; |
| 476 default: | 476 default: |
| 477 UNIMPLEMENTED(); | 477 UNIMPLEMENTED(); |
| 478 } | 478 } |
| 479 ExternalLabel target_label("InlineCache", label_address); | 479 ExternalLabel target_label("InlineCache", label_address); |
| 480 __ call(&target_label); | 480 __ call(&target_label); |
| 481 AddCurrentDescriptor(PcDescriptors::kIcCall, cid, token_index, try_index); | 481 AddCurrentDescriptor(PcDescriptors::kIcCall, cid, token_index, try_index); |
| 482 __ addq(RSP, Immediate(argument_count * kWordSize)); | 482 __ Drop(argument_count); |
| 483 } | 483 } |
| 484 | 484 |
| 485 | 485 |
| 486 void FlowGraphCompiler::EmitStaticCall(intptr_t token_index, | 486 void FlowGraphCompiler::EmitStaticCall(intptr_t token_index, |
| 487 intptr_t try_index, | 487 intptr_t try_index, |
| 488 const Function& function, | 488 const Function& function, |
| 489 intptr_t argument_count, | 489 intptr_t argument_count, |
| 490 const Array& argument_names) { | 490 const Array& argument_names) { |
| 491 const Array& arguments_descriptor = | 491 const Array& arguments_descriptor = |
| 492 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names); | 492 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names); |
| 493 __ LoadObject(RBX, function); | 493 __ LoadObject(RBX, function); |
| 494 __ LoadObject(R10, arguments_descriptor); | 494 __ LoadObject(R10, arguments_descriptor); |
| 495 | 495 |
| 496 GenerateCall(token_index, | 496 GenerateCall(token_index, |
| 497 try_index, | 497 try_index, |
| 498 &StubCode::CallStaticFunctionLabel(), | 498 &StubCode::CallStaticFunctionLabel(), |
| 499 PcDescriptors::kFuncCall); | 499 PcDescriptors::kFuncCall); |
| 500 __ addq(RSP, Immediate(argument_count * kWordSize)); | 500 __ Drop(argument_count); |
| 501 } | 501 } |
| 502 | 502 |
| 503 | 503 |
| 504 void FlowGraphCompiler::VisitCurrentContext(CurrentContextComp* comp) { | 504 void FlowGraphCompiler::VisitCurrentContext(CurrentContextComp* comp) { |
| 505 __ movq(RAX, CTX); | 505 __ movq(RAX, CTX); |
| 506 } | 506 } |
| 507 | 507 |
| 508 | 508 |
| 509 void FlowGraphCompiler::VisitStoreContext(StoreContextComp* comp) { | 509 void FlowGraphCompiler::VisitStoreContext(StoreContextComp* comp) { |
| 510 LoadValue(CTX, comp->value()); | 510 LoadValue(CTX, comp->value()); |
| 511 } | 511 } |
| 512 | 512 |
| 513 | 513 |
| 514 void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) { | 514 void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) { |
| 515 ASSERT(comp->context()->IsUse()); | 515 ASSERT(comp->context()->IsUse()); |
| 516 ASSERT(VerifyCallComputation(comp)); | 516 ASSERT(VerifyCallComputation(comp)); |
| 517 // The arguments to the stub include the closure. The arguments | 517 // The arguments to the stub include the closure. The arguments |
| 518 // descriptor describes the closure's arguments (and so does not include | 518 // descriptor describes the closure's arguments (and so does not include |
| 519 // the closure). | 519 // the closure). |
| 520 int argument_count = comp->ArgumentCount(); | 520 int argument_count = comp->ArgumentCount(); |
| 521 const Array& arguments_descriptor = | 521 const Array& arguments_descriptor = |
| 522 CodeGenerator::ArgumentsDescriptor(argument_count - 1, | 522 CodeGenerator::ArgumentsDescriptor(argument_count - 1, |
| 523 comp->argument_names()); | 523 comp->argument_names()); |
| 524 __ LoadObject(R10, arguments_descriptor); | 524 __ LoadObject(R10, arguments_descriptor); |
| 525 | 525 |
| 526 GenerateCall(comp->token_index(), | 526 GenerateCall(comp->token_index(), |
| 527 comp->try_index(), | 527 comp->try_index(), |
| 528 &StubCode::CallClosureFunctionLabel(), | 528 &StubCode::CallClosureFunctionLabel(), |
| 529 PcDescriptors::kOther); | 529 PcDescriptors::kOther); |
| 530 __ addq(RSP, Immediate(argument_count * kWordSize)); | 530 __ Drop(argument_count); |
| 531 __ popq(CTX); | 531 __ popq(CTX); |
| 532 } | 532 } |
| 533 | 533 |
| 534 | 534 |
| 535 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) { | 535 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) { |
| 536 ASSERT(VerifyCallComputation(comp)); | 536 ASSERT(VerifyCallComputation(comp)); |
| 537 EmitInstanceCall(comp->cid(), | 537 EmitInstanceCall(comp->cid(), |
| 538 comp->token_index(), | 538 comp->token_index(), |
| 539 comp->try_index(), | 539 comp->try_index(), |
| 540 comp->function_name(), | 540 comp->function_name(), |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 __ pushq(raw_null); // TODO(srdjan): Pass instantiator instead of null. | 829 __ pushq(raw_null); // TODO(srdjan): Pass instantiator instead of null. |
| 830 if (type.IsInstantiated()) { | 830 if (type.IsInstantiated()) { |
| 831 __ pushq(raw_null); // Null instantiator type arguments. | 831 __ pushq(raw_null); // Null instantiator type arguments. |
| 832 } else { | 832 } else { |
| 833 __ pushq(RDX); // Instantiator type arguments. | 833 __ pushq(RDX); // Instantiator type arguments. |
| 834 } | 834 } |
| 835 __ pushq(raw_null); // SubtypeTestCache not yet supported. | 835 __ pushq(raw_null); // SubtypeTestCache not yet supported. |
| 836 GenerateCallRuntime(cid, token_index, try_index, kInstanceofRuntimeEntry); | 836 GenerateCallRuntime(cid, token_index, try_index, kInstanceofRuntimeEntry); |
| 837 // Pop the two parameters supplied to the runtime entry. The result of the | 837 // Pop the two parameters supplied to the runtime entry. The result of the |
| 838 // instanceof runtime call will be left as the result of the operation. | 838 // instanceof runtime call will be left as the result of the operation. |
| 839 __ addq(RSP, Immediate(7 * kWordSize)); | 839 __ Drop(7); |
| 840 Label done; | 840 Label done; |
| 841 if (negate_result) { | 841 if (negate_result) { |
| 842 __ popq(RDX); | 842 __ popq(RDX); |
| 843 __ LoadObject(RAX, bool_true); | 843 __ LoadObject(RAX, bool_true); |
| 844 __ cmpq(RDX, RAX); | 844 __ cmpq(RDX, RAX); |
| 845 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 845 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 846 __ LoadObject(RAX, bool_false); | 846 __ LoadObject(RAX, bool_false); |
| 847 } else { | 847 } else { |
| 848 __ popq(RAX); | 848 __ popq(RAX); |
| 849 } | 849 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 871 comp->negate_result()); | 871 comp->negate_result()); |
| 872 } | 872 } |
| 873 | 873 |
| 874 | 874 |
| 875 void FlowGraphCompiler::VisitAllocateObject(AllocateObjectComp* comp) { | 875 void FlowGraphCompiler::VisitAllocateObject(AllocateObjectComp* comp) { |
| 876 const Class& cls = Class::ZoneHandle(comp->constructor().owner()); | 876 const Class& cls = Class::ZoneHandle(comp->constructor().owner()); |
| 877 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); | 877 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); |
| 878 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); | 878 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); |
| 879 GenerateCall(comp->token_index(), comp->try_index(), &label, | 879 GenerateCall(comp->token_index(), comp->try_index(), &label, |
| 880 PcDescriptors::kOther); | 880 PcDescriptors::kOther); |
| 881 for (intptr_t i = 0; i < comp->arguments().length(); i++) { | 881 __ Drop(comp->arguments().length()); // Discard allocation argument. |
| 882 __ popq(RCX); // Discard allocation argument | |
| 883 } | |
| 884 } | 882 } |
| 885 | 883 |
| 886 | 884 |
| 887 void FlowGraphCompiler::VisitAllocateObjectWithBoundsCheck( | 885 void FlowGraphCompiler::VisitAllocateObjectWithBoundsCheck( |
| 888 AllocateObjectWithBoundsCheckComp* comp) { | 886 AllocateObjectWithBoundsCheckComp* comp) { |
| 889 const Class& cls = Class::ZoneHandle(comp->constructor().owner()); | 887 const Class& cls = Class::ZoneHandle(comp->constructor().owner()); |
| 890 __ popq(RCX); // Pop instantiator type arguments. | 888 __ popq(RCX); // Pop instantiator type arguments. |
| 891 __ popq(RAX); // Pop type arguments. | 889 __ popq(RAX); // Pop type arguments. |
| 892 | 890 |
| 893 // Push the result place holder initialized to NULL. | 891 // Push the result place holder initialized to NULL. |
| 894 __ PushObject(Object::ZoneHandle()); | 892 __ PushObject(Object::ZoneHandle()); |
| 895 __ pushq(Immediate(Smi::RawValue(comp->token_index()))); | 893 __ pushq(Immediate(Smi::RawValue(comp->token_index()))); |
| 896 __ PushObject(cls); | 894 __ PushObject(cls); |
| 897 __ pushq(RAX); // Push type arguments. | 895 __ pushq(RAX); // Push type arguments. |
| 898 __ pushq(RCX); // Push instantiator type arguments. | 896 __ pushq(RCX); // Push instantiator type arguments. |
| 899 GenerateCallRuntime(comp->cid(), | 897 GenerateCallRuntime(comp->cid(), |
| 900 comp->token_index(), | 898 comp->token_index(), |
| 901 comp->try_index(), | 899 comp->try_index(), |
| 902 kAllocateObjectWithBoundsCheckRuntimeEntry); | 900 kAllocateObjectWithBoundsCheckRuntimeEntry); |
| 903 __ popq(RCX); // Pop instantiator type arguments. | 901 // Pop instantiator type arguments, type arguments, class, and |
| 904 __ popq(RCX); // Pop type arguments. | 902 // source location. |
| 905 __ popq(RCX); // Pop class. | 903 __ Drop(4); |
| 906 __ popq(RCX); // Pop source location. | |
| 907 __ popq(RAX); // Pop new instance. | 904 __ popq(RAX); // Pop new instance. |
| 908 } | 905 } |
| 909 | 906 |
| 910 | 907 |
| 911 void FlowGraphCompiler::VisitCreateArray(CreateArrayComp* comp) { | 908 void FlowGraphCompiler::VisitCreateArray(CreateArrayComp* comp) { |
| 912 // 1. Allocate the array. R10 = length, RBX = element type. | 909 // 1. Allocate the array. R10 = length, RBX = element type. |
| 913 __ movq(R10, Immediate(Smi::RawValue(comp->ElementCount()))); | 910 __ movq(R10, Immediate(Smi::RawValue(comp->ElementCount()))); |
| 914 LoadValue(RBX, comp->element_type()); | 911 LoadValue(RBX, comp->element_type()); |
| 915 GenerateCall(comp->token_index(), | 912 GenerateCall(comp->token_index(), |
| 916 comp->try_index(), | 913 comp->try_index(), |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 ASSERT(exception_handlers_list_ != NULL); | 1714 ASSERT(exception_handlers_list_ != NULL); |
| 1718 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( | 1715 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( |
| 1719 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); | 1716 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); |
| 1720 code.set_exception_handlers(handlers); | 1717 code.set_exception_handlers(handlers); |
| 1721 } | 1718 } |
| 1722 | 1719 |
| 1723 | 1720 |
| 1724 } // namespace dart | 1721 } // namespace dart |
| 1725 | 1722 |
| 1726 #endif // defined TARGET_ARCH_X64 | 1723 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |