| 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 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 // - Class equality (only if class is not parameterized). | 446 // - Class equality (only if class is not parameterized). |
| 447 // Inputs: | 447 // Inputs: |
| 448 // - RAX: object. | 448 // - RAX: object. |
| 449 // - RDX: instantiator type arguments or raw_null. | 449 // - RDX: instantiator type arguments or raw_null. |
| 450 // - RCX: instantiator or raw_null. | 450 // - RCX: instantiator or raw_null. |
| 451 // Clobbers RCX and RDX. | 451 // Clobbers RCX and RDX. |
| 452 // Returns: | 452 // Returns: |
| 453 // - true or false in RAX. | 453 // - true or false in RAX. |
| 454 void FlowGraphCompiler::GenerateInstanceOf(intptr_t deopt_id, | 454 void FlowGraphCompiler::GenerateInstanceOf(intptr_t deopt_id, |
| 455 intptr_t token_pos, | 455 intptr_t token_pos, |
| 456 intptr_t try_index, | |
| 457 const AbstractType& type, | 456 const AbstractType& type, |
| 458 bool negate_result, | 457 bool negate_result, |
| 459 LocationSummary* locs) { | 458 LocationSummary* locs) { |
| 460 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 459 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 461 | 460 |
| 462 const Immediate raw_null = | 461 const Immediate raw_null = |
| 463 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 462 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 464 Label is_instance, is_not_instance; | 463 Label is_instance, is_not_instance; |
| 465 __ pushq(RCX); // Store instantiator on stack. | 464 __ pushq(RCX); // Store instantiator on stack. |
| 466 __ pushq(RDX); // Store instantiator type arguments. | 465 __ pushq(RDX); // Store instantiator type arguments. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 489 // Generate runtime call. | 488 // Generate runtime call. |
| 490 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. | 489 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. |
| 491 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. | 490 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. |
| 492 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 491 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 493 __ pushq(RAX); // Push the instance. | 492 __ pushq(RAX); // Push the instance. |
| 494 __ PushObject(type); // Push the type. | 493 __ PushObject(type); // Push the type. |
| 495 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. | 494 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. |
| 496 __ pushq(RDX); // Instantiator type arguments. | 495 __ pushq(RDX); // Instantiator type arguments. |
| 497 __ LoadObject(RAX, test_cache); | 496 __ LoadObject(RAX, test_cache); |
| 498 __ pushq(RAX); | 497 __ pushq(RAX); |
| 499 GenerateCallRuntime(deopt_id, token_pos, try_index, | 498 GenerateCallRuntime(deopt_id, token_pos, kInstanceofRuntimeEntry, locs); |
| 500 kInstanceofRuntimeEntry, locs); | |
| 501 // Pop the parameters supplied to the runtime entry. The result of the | 499 // Pop the parameters supplied to the runtime entry. The result of the |
| 502 // instanceof runtime call will be left as the result of the operation. | 500 // instanceof runtime call will be left as the result of the operation. |
| 503 __ Drop(5); | 501 __ Drop(5); |
| 504 if (negate_result) { | 502 if (negate_result) { |
| 505 __ popq(RDX); | 503 __ popq(RDX); |
| 506 __ LoadObject(RAX, bool_true()); | 504 __ LoadObject(RAX, bool_true()); |
| 507 __ cmpq(RDX, RAX); | 505 __ cmpq(RDX, RAX); |
| 508 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 506 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 509 __ LoadObject(RAX, bool_false()); | 507 __ LoadObject(RAX, bool_false()); |
| 510 } else { | 508 } else { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 531 // Inputs: | 529 // Inputs: |
| 532 // - RAX: object. | 530 // - RAX: object. |
| 533 // - RDX: instantiator type arguments or raw_null. | 531 // - RDX: instantiator type arguments or raw_null. |
| 534 // - RCX: instantiator or raw_null. | 532 // - RCX: instantiator or raw_null. |
| 535 // Returns: | 533 // Returns: |
| 536 // - object in RAX for successful assignable check (or throws TypeError). | 534 // - object in RAX for successful assignable check (or throws TypeError). |
| 537 // Performance notes: positive checks must be quick, negative checks can be slow | 535 // Performance notes: positive checks must be quick, negative checks can be slow |
| 538 // as they throw an exception. | 536 // as they throw an exception. |
| 539 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t deopt_id, | 537 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t deopt_id, |
| 540 intptr_t token_pos, | 538 intptr_t token_pos, |
| 541 intptr_t try_index, | |
| 542 const AbstractType& dst_type, | 539 const AbstractType& dst_type, |
| 543 const String& dst_name, | 540 const String& dst_name, |
| 544 LocationSummary* locs) { | 541 LocationSummary* locs) { |
| 545 ASSERT(token_pos >= 0); | 542 ASSERT(token_pos >= 0); |
| 546 ASSERT(!dst_type.IsNull()); | 543 ASSERT(!dst_type.IsNull()); |
| 547 ASSERT(dst_type.IsFinalized()); | 544 ASSERT(dst_type.IsFinalized()); |
| 548 // Assignable check is skipped in FlowGraphBuilder, not here. | 545 // Assignable check is skipped in FlowGraphBuilder, not here. |
| 549 ASSERT(dst_type.IsMalformed() || | 546 ASSERT(dst_type.IsMalformed() || |
| 550 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); | 547 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); |
| 551 __ pushq(RCX); // Store instantiator. | 548 __ pushq(RCX); // Store instantiator. |
| 552 __ pushq(RDX); // Store instantiator type arguments. | 549 __ pushq(RDX); // Store instantiator type arguments. |
| 553 // A null object is always assignable and is returned as result. | 550 // A null object is always assignable and is returned as result. |
| 554 const Immediate raw_null = | 551 const Immediate raw_null = |
| 555 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 552 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 556 Label is_assignable, runtime_call; | 553 Label is_assignable, runtime_call; |
| 557 __ cmpq(RAX, raw_null); | 554 __ cmpq(RAX, raw_null); |
| 558 __ j(EQUAL, &is_assignable); | 555 __ j(EQUAL, &is_assignable); |
| 559 | 556 |
| 560 // Generate throw new TypeError() if the type is malformed. | 557 // Generate throw new TypeError() if the type is malformed. |
| 561 if (dst_type.IsMalformed()) { | 558 if (dst_type.IsMalformed()) { |
| 562 const Error& error = Error::Handle(dst_type.malformed_error()); | 559 const Error& error = Error::Handle(dst_type.malformed_error()); |
| 563 const String& error_message = String::ZoneHandle( | 560 const String& error_message = String::ZoneHandle( |
| 564 Symbols::New(error.ToErrorCString())); | 561 Symbols::New(error.ToErrorCString())); |
| 565 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 562 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 566 __ pushq(RAX); // Push the source object. | 563 __ pushq(RAX); // Push the source object. |
| 567 __ PushObject(dst_name); // Push the name of the destination. | 564 __ PushObject(dst_name); // Push the name of the destination. |
| 568 __ PushObject(error_message); | 565 __ PushObject(error_message); |
| 569 GenerateCallRuntime(deopt_id, | 566 GenerateCallRuntime(deopt_id, |
| 570 token_pos, | 567 token_pos, |
| 571 try_index, | |
| 572 kMalformedTypeErrorRuntimeEntry, | 568 kMalformedTypeErrorRuntimeEntry, |
| 573 locs); | 569 locs); |
| 574 // We should never return here. | 570 // We should never return here. |
| 575 __ int3(); | 571 __ int3(); |
| 576 | 572 |
| 577 __ Bind(&is_assignable); // For a null object. | 573 __ Bind(&is_assignable); // For a null object. |
| 578 __ popq(RDX); // Remove pushed instantiator type arguments. | 574 __ popq(RDX); // Remove pushed instantiator type arguments. |
| 579 __ popq(RCX); // Remove pushed instantiator. | 575 __ popq(RCX); // Remove pushed instantiator. |
| 580 return; | 576 return; |
| 581 } | 577 } |
| 582 | 578 |
| 583 // Generate inline type check, linking to runtime call if not assignable. | 579 // Generate inline type check, linking to runtime call if not assignable. |
| 584 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); | 580 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); |
| 585 test_cache = GenerateInlineInstanceof(token_pos, dst_type, | 581 test_cache = GenerateInlineInstanceof(token_pos, dst_type, |
| 586 &is_assignable, &runtime_call); | 582 &is_assignable, &runtime_call); |
| 587 | 583 |
| 588 __ Bind(&runtime_call); | 584 __ Bind(&runtime_call); |
| 589 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. | 585 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. |
| 590 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. | 586 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. |
| 591 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 587 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 592 __ pushq(RAX); // Push the source object. | 588 __ pushq(RAX); // Push the source object. |
| 593 __ PushObject(dst_type); // Push the type of the destination. | 589 __ PushObject(dst_type); // Push the type of the destination. |
| 594 __ pushq(RCX); // Instantiator. | 590 __ pushq(RCX); // Instantiator. |
| 595 __ pushq(RDX); // Instantiator type arguments. | 591 __ pushq(RDX); // Instantiator type arguments. |
| 596 __ PushObject(dst_name); // Push the name of the destination. | 592 __ PushObject(dst_name); // Push the name of the destination. |
| 597 __ LoadObject(RAX, test_cache); | 593 __ LoadObject(RAX, test_cache); |
| 598 __ pushq(RAX); | 594 __ pushq(RAX); |
| 599 GenerateCallRuntime(deopt_id, | 595 GenerateCallRuntime(deopt_id, |
| 600 token_pos, | 596 token_pos, |
| 601 try_index, | |
| 602 kTypeCheckRuntimeEntry, | 597 kTypeCheckRuntimeEntry, |
| 603 locs); | 598 locs); |
| 604 // Pop the parameters supplied to the runtime entry. The result of the | 599 // Pop the parameters supplied to the runtime entry. The result of the |
| 605 // type check runtime call is the checked value. | 600 // type check runtime call is the checked value. |
| 606 __ Drop(6); | 601 __ Drop(6); |
| 607 __ popq(RAX); | 602 __ popq(RAX); |
| 608 | 603 |
| 609 __ Bind(&is_assignable); | 604 __ Bind(&is_assignable); |
| 610 __ popq(RDX); // Remove pushed instantiator type arguments. | 605 __ popq(RDX); // Remove pushed instantiator type arguments. |
| 611 __ popq(RCX); // Remove pushed instantiator. | 606 __ popq(RCX); // Remove pushed instantiator. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 } | 769 } |
| 775 // The calls immediately below have empty stackmaps because we have just | 770 // The calls immediately below have empty stackmaps because we have just |
| 776 // dropped the spill slots. | 771 // dropped the spill slots. |
| 777 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); | 772 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); |
| 778 if (function.IsClosureFunction()) { | 773 if (function.IsClosureFunction()) { |
| 779 // We do not use GenerateCallRuntime because of the non-standard (empty) | 774 // We do not use GenerateCallRuntime because of the non-standard (empty) |
| 780 // stackmap used here. | 775 // stackmap used here. |
| 781 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry); | 776 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry); |
| 782 AddCurrentDescriptor(PcDescriptors::kOther, | 777 AddCurrentDescriptor(PcDescriptors::kOther, |
| 783 Isolate::kNoDeoptId, | 778 Isolate::kNoDeoptId, |
| 784 0, // No token position. | 779 0); // No token position. |
| 785 CatchClauseNode::kInvalidTryIndex); | |
| 786 } else { | 780 } else { |
| 787 ASSERT(!IsLeaf()); | 781 ASSERT(!IsLeaf()); |
| 788 // Invoke noSuchMethod function. | 782 // Invoke noSuchMethod function. |
| 789 const int kNumArgsChecked = 1; | 783 const int kNumArgsChecked = 1; |
| 790 ICData& ic_data = ICData::ZoneHandle(); | 784 ICData& ic_data = ICData::ZoneHandle(); |
| 791 ic_data = ICData::New(function, | 785 ic_data = ICData::New(function, |
| 792 String::Handle(function.name()), | 786 String::Handle(function.name()), |
| 793 Isolate::kNoDeoptId, | 787 Isolate::kNoDeoptId, |
| 794 kNumArgsChecked); | 788 kNumArgsChecked); |
| 795 __ LoadObject(RBX, ic_data); | 789 __ LoadObject(RBX, ic_data); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 808 } | 802 } |
| 809 | 803 |
| 810 if (FLAG_trace_functions) { | 804 if (FLAG_trace_functions) { |
| 811 __ pushq(RAX); // Preserve result. | 805 __ pushq(RAX); // Preserve result. |
| 812 __ PushObject(Function::ZoneHandle(function.raw())); | 806 __ PushObject(Function::ZoneHandle(function.raw())); |
| 813 // We do not use GenerateCallRuntime because of the non-standard (empty) | 807 // We do not use GenerateCallRuntime because of the non-standard (empty) |
| 814 // stackmap used here. | 808 // stackmap used here. |
| 815 __ CallRuntime(kTraceFunctionExitRuntimeEntry); | 809 __ CallRuntime(kTraceFunctionExitRuntimeEntry); |
| 816 AddCurrentDescriptor(PcDescriptors::kOther, | 810 AddCurrentDescriptor(PcDescriptors::kOther, |
| 817 Isolate::kNoDeoptId, | 811 Isolate::kNoDeoptId, |
| 818 0, // No token position. | 812 0); // No token position. |
| 819 CatchClauseNode::kInvalidTryIndex); | |
| 820 if (is_optimizing()) { | 813 if (is_optimizing()) { |
| 821 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), | 814 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), |
| 822 empty_stack_bitmap); | 815 empty_stack_bitmap); |
| 823 } | 816 } |
| 824 __ popq(RAX); // Remove argument. | 817 __ popq(RAX); // Remove argument. |
| 825 __ popq(RAX); // Restore result. | 818 __ popq(RAX); // Restore result. |
| 826 } | 819 } |
| 827 __ LeaveFrame(); | 820 __ LeaveFrame(); |
| 828 __ ret(); | 821 __ ret(); |
| 829 | 822 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 __ Comment("Check argument count"); | 940 __ Comment("Check argument count"); |
| 948 // Check that num_fixed <= argc <= num_params. | 941 // Check that num_fixed <= argc <= num_params. |
| 949 Label argc_in_range; | 942 Label argc_in_range; |
| 950 // Total number of args is the first Smi in args descriptor array (R10). | 943 // Total number of args is the first Smi in args descriptor array (R10). |
| 951 __ movq(RAX, FieldAddress(R10, Array::data_offset())); | 944 __ movq(RAX, FieldAddress(R10, Array::data_offset())); |
| 952 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count))); | 945 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count))); |
| 953 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); | 946 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); |
| 954 if (function.IsClosureFunction()) { | 947 if (function.IsClosureFunction()) { |
| 955 GenerateCallRuntime(Isolate::kNoDeoptId, | 948 GenerateCallRuntime(Isolate::kNoDeoptId, |
| 956 function.token_pos(), | 949 function.token_pos(), |
| 957 CatchClauseNode::kInvalidTryIndex, | |
| 958 kClosureArgumentMismatchRuntimeEntry, | 950 kClosureArgumentMismatchRuntimeEntry, |
| 959 prologue_locs); | 951 prologue_locs); |
| 960 } else { | 952 } else { |
| 961 __ Stop("Wrong number of arguments"); | 953 __ Stop("Wrong number of arguments"); |
| 962 } | 954 } |
| 963 __ Bind(&argc_in_range); | 955 __ Bind(&argc_in_range); |
| 964 } | 956 } |
| 965 } else { | 957 } else { |
| 966 CopyParameters(); | 958 CopyParameters(); |
| 967 } | 959 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode, | 992 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode, |
| 1001 assembler()->CodeSize(), | 993 assembler()->CodeSize(), |
| 1002 Isolate::kNoDeoptId, | 994 Isolate::kNoDeoptId, |
| 1003 0, | 995 0, |
| 1004 -1); | 996 -1); |
| 1005 __ jmp(&StubCode::FixCallersTargetLabel()); | 997 __ jmp(&StubCode::FixCallersTargetLabel()); |
| 1006 } | 998 } |
| 1007 | 999 |
| 1008 | 1000 |
| 1009 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, | 1001 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, |
| 1010 intptr_t try_index, | |
| 1011 const ExternalLabel* label, | 1002 const ExternalLabel* label, |
| 1012 PcDescriptors::Kind kind, | 1003 PcDescriptors::Kind kind, |
| 1013 LocationSummary* locs) { | 1004 LocationSummary* locs) { |
| 1014 ASSERT(!IsLeaf()); | 1005 ASSERT(!IsLeaf()); |
| 1015 __ call(label); | 1006 __ call(label); |
| 1016 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index); | 1007 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); |
| 1017 RecordSafepoint(locs); | 1008 RecordSafepoint(locs); |
| 1018 } | 1009 } |
| 1019 | 1010 |
| 1020 | 1011 |
| 1021 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id, | 1012 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id, |
| 1022 intptr_t token_pos, | 1013 intptr_t token_pos, |
| 1023 intptr_t try_index, | |
| 1024 const RuntimeEntry& entry, | 1014 const RuntimeEntry& entry, |
| 1025 LocationSummary* locs) { | 1015 LocationSummary* locs) { |
| 1026 ASSERT(!IsLeaf()); | 1016 ASSERT(!IsLeaf()); |
| 1027 __ CallRuntime(entry); | 1017 __ CallRuntime(entry); |
| 1028 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index); | 1018 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); |
| 1029 RecordSafepoint(locs); | 1019 RecordSafepoint(locs); |
| 1030 } | 1020 } |
| 1031 | 1021 |
| 1032 | 1022 |
| 1033 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, | 1023 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, |
| 1034 const ICData& ic_data, | 1024 const ICData& ic_data, |
| 1035 const Array& arguments_descriptor, | 1025 const Array& arguments_descriptor, |
| 1036 intptr_t argument_count, | 1026 intptr_t argument_count, |
| 1037 intptr_t deopt_id, | 1027 intptr_t deopt_id, |
| 1038 intptr_t token_pos, | 1028 intptr_t token_pos, |
| 1039 intptr_t try_index, | |
| 1040 LocationSummary* locs) { | 1029 LocationSummary* locs) { |
| 1041 ASSERT(!IsLeaf()); | 1030 ASSERT(!IsLeaf()); |
| 1042 __ LoadObject(RBX, ic_data); | 1031 __ LoadObject(RBX, ic_data); |
| 1043 __ LoadObject(R10, arguments_descriptor); | 1032 __ LoadObject(R10, arguments_descriptor); |
| 1044 | 1033 |
| 1045 __ call(target_label); | 1034 __ call(target_label); |
| 1046 AddCurrentDescriptor(PcDescriptors::kIcCall, deopt_id, token_pos, try_index); | 1035 AddCurrentDescriptor(PcDescriptors::kIcCall, deopt_id, token_pos); |
| 1047 RecordSafepoint(locs); | 1036 RecordSafepoint(locs); |
| 1048 | 1037 |
| 1049 __ Drop(argument_count); | 1038 __ Drop(argument_count); |
| 1050 } | 1039 } |
| 1051 | 1040 |
| 1052 | 1041 |
| 1053 void FlowGraphCompiler::EmitStaticCall(const Function& function, | 1042 void FlowGraphCompiler::EmitStaticCall(const Function& function, |
| 1054 const Array& arguments_descriptor, | 1043 const Array& arguments_descriptor, |
| 1055 intptr_t argument_count, | 1044 intptr_t argument_count, |
| 1056 intptr_t deopt_id, | 1045 intptr_t deopt_id, |
| 1057 intptr_t token_pos, | 1046 intptr_t token_pos, |
| 1058 intptr_t try_index, | |
| 1059 LocationSummary* locs) { | 1047 LocationSummary* locs) { |
| 1060 ASSERT(!IsLeaf()); | 1048 ASSERT(!IsLeaf()); |
| 1061 __ LoadObject(RBX, function); | 1049 __ LoadObject(RBX, function); |
| 1062 __ LoadObject(R10, arguments_descriptor); | 1050 __ LoadObject(R10, arguments_descriptor); |
| 1063 __ call(&StubCode::CallStaticFunctionLabel()); | 1051 __ call(&StubCode::CallStaticFunctionLabel()); |
| 1064 AddCurrentDescriptor(PcDescriptors::kFuncCall, deopt_id, token_pos, | 1052 AddCurrentDescriptor(PcDescriptors::kFuncCall, deopt_id, token_pos); |
| 1065 try_index); | |
| 1066 RecordSafepoint(locs); | 1053 RecordSafepoint(locs); |
| 1067 if (is_optimizing()) { | 1054 if (is_optimizing()) { |
| 1068 AddDeoptIndexAtCall(deopt_id, token_pos); | 1055 AddDeoptIndexAtCall(deopt_id, token_pos); |
| 1069 } | 1056 } |
| 1070 __ Drop(argument_count); | 1057 __ Drop(argument_count); |
| 1071 } | 1058 } |
| 1072 | 1059 |
| 1073 | 1060 |
| 1074 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label | 1061 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label |
| 1075 // if no match or instance is Smi. | 1062 // if no match or instance is Smi. |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1292 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1306 __ Exchange(mem1, mem2); | 1293 __ Exchange(mem1, mem2); |
| 1307 } | 1294 } |
| 1308 | 1295 |
| 1309 | 1296 |
| 1310 #undef __ | 1297 #undef __ |
| 1311 | 1298 |
| 1312 } // namespace dart | 1299 } // namespace dart |
| 1313 | 1300 |
| 1314 #endif // defined TARGET_ARCH_X64 | 1301 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |