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 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); | 772 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
773 } | 773 } |
774 | 774 |
775 __ Bind(&wrong_num_arguments); | 775 __ Bind(&wrong_num_arguments); |
776 if (StackSize() != 0) { | 776 if (StackSize() != 0) { |
777 // We need to unwind the space we reserved for locals and copied parameters. | 777 // We need to unwind the space we reserved for locals and copied parameters. |
778 // The NoSuchMethodFunction stub does not expect to see that area on the | 778 // The NoSuchMethodFunction stub does not expect to see that area on the |
779 // stack. | 779 // stack. |
780 __ addq(RSP, Immediate(StackSize() * kWordSize)); | 780 __ addq(RSP, Immediate(StackSize() * kWordSize)); |
781 } | 781 } |
782 // The calls immediately below have empty stackmaps because we have just | 782 // The call below has an empty stackmap because we have just |
783 // dropped the spill slots. | 783 // dropped the spill slots. |
784 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); | 784 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); |
785 if (function.IsClosureFunction()) { | 785 |
786 // TODO(regis): Call NoSuchMethod with "call" as name of original function. | 786 // Invoke noSuchMethod function passing the original name of the function. |
787 // We do not use GenerateCallRuntime because of the non-standard (empty) | 787 // If the function is a closure function, use "call" as the original name. |
788 // stackmap used here. | 788 const String& name = String::Handle( |
789 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry); | 789 function.IsClosureFunction() ? Symbols::Call() : function.name()); |
790 AddCurrentDescriptor(PcDescriptors::kOther, | 790 const int kNumArgsChecked = 1; |
791 Isolate::kNoDeoptId, | 791 const ICData& ic_data = ICData::ZoneHandle( |
792 0); // No token position. | 792 ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked)); |
793 } else { | 793 __ LoadObject(RBX, ic_data); |
794 // Invoke noSuchMethod function. | 794 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj. |
795 const int kNumArgsChecked = 1; | 795 // RBP : points to previous frame pointer. |
796 ICData& ic_data = ICData::ZoneHandle(); | 796 // RBP + 8 : points to return address. |
797 ic_data = ICData::New(function, | 797 // RBP + 16 : address of last argument (arg n-1). |
798 String::Handle(function.name()), | 798 // RSP + 16 + 8*(n-1) : address of first argument (arg 0). |
799 Isolate::kNoDeoptId, | 799 // RBX : ic-data. |
800 kNumArgsChecked); | 800 // R10 : arguments descriptor array. |
801 __ LoadObject(RBX, ic_data); | 801 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); |
802 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj. | |
803 // RBP : points to previous frame pointer. | |
804 // RBP + 8 : points to return address. | |
805 // RBP + 16 : address of last argument (arg n-1). | |
806 // RSP + 16 + 8*(n-1) : address of first argument (arg 0). | |
807 // RBX : ic-data. | |
808 // R10 : arguments descriptor array. | |
809 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); | |
810 } | |
811 if (is_optimizing()) { | 802 if (is_optimizing()) { |
812 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), | 803 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), |
813 empty_stack_bitmap, | 804 empty_stack_bitmap, |
814 0); // No registers. | 805 0); // No registers. |
815 } | 806 } |
816 | 807 // The noSuchMethod call may return. |
817 __ LeaveFrame(); | 808 __ LeaveFrame(); |
818 __ ret(); | 809 __ ret(); |
819 | 810 |
820 __ Bind(&all_arguments_processed); | 811 __ Bind(&all_arguments_processed); |
821 // Nullify originally passed arguments only after they have been copied and | 812 // Nullify originally passed arguments only after they have been copied and |
822 // checked, otherwise noSuchMethod would not see their original values. | 813 // checked, otherwise noSuchMethod would not see their original values. |
823 // This step can be skipped in case we decide that formal parameters are | 814 // This step can be skipped in case we decide that formal parameters are |
824 // implicitly final, since garbage collecting the unmodified value is not | 815 // implicitly final, since garbage collecting the unmodified value is not |
825 // an issue anymore. | 816 // an issue anymore. |
826 | 817 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 #endif | 899 #endif |
909 if (check_arguments) { | 900 if (check_arguments) { |
910 __ Comment("Check argument count"); | 901 __ Comment("Check argument count"); |
911 // Check that num_fixed <= argc <= num_params. | 902 // Check that num_fixed <= argc <= num_params. |
912 Label argc_in_range; | 903 Label argc_in_range; |
913 // Total number of args is the first Smi in args descriptor array (R10). | 904 // Total number of args is the first Smi in args descriptor array (R10). |
914 __ movq(RAX, FieldAddress(R10, Array::data_offset())); | 905 __ movq(RAX, FieldAddress(R10, Array::data_offset())); |
915 __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params))); | 906 __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params))); |
916 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); | 907 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); |
917 if (function.IsClosureFunction()) { | 908 if (function.IsClosureFunction()) { |
918 // TODO(regis): Call NoSuchMethod with "call" as name of original | 909 if (StackSize() != 0) { |
919 // function. | 910 // We need to unwind the space we reserved for locals and copied |
920 GenerateCallRuntime(function.token_pos(), | 911 // parameters. The NoSuchMethodFunction stub does not expect to see |
921 kClosureArgumentMismatchRuntimeEntry, | 912 // that area on the stack. |
922 prologue_locs); | 913 __ addq(RSP, Immediate(StackSize() * kWordSize)); |
| 914 } |
| 915 // The call below has an empty stackmap because we have just |
| 916 // dropped the spill slots. |
| 917 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); |
| 918 |
| 919 // Invoke noSuchMethod function passing "call" as the function name. |
| 920 const String& name = String::Handle(Symbols::Call()); |
| 921 const int kNumArgsChecked = 1; |
| 922 const ICData& ic_data = ICData::ZoneHandle( |
| 923 ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked)); |
| 924 __ LoadObject(RBX, ic_data); |
| 925 // RBP - 8 : PC marker, for easy identification of RawInstruction obj. |
| 926 // RBP : points to previous frame pointer. |
| 927 // RBP + 8 : points to return address. |
| 928 // RBP + 16 : address of last argument (arg n-1). |
| 929 // RSP + 16 + 8*(n-1) : address of first argument (arg 0). |
| 930 // RBX : ic-data. |
| 931 // R10 : arguments descriptor array. |
| 932 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); |
| 933 if (is_optimizing()) { |
| 934 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), |
| 935 empty_stack_bitmap, |
| 936 0); // No registers. |
| 937 } |
| 938 // The noSuchMethod call may return. |
| 939 __ LeaveFrame(); |
| 940 __ ret(); |
923 } else { | 941 } else { |
924 __ Stop("Wrong number of arguments"); | 942 __ Stop("Wrong number of arguments"); |
925 } | 943 } |
926 __ Bind(&argc_in_range); | 944 __ Bind(&argc_in_range); |
927 } | 945 } |
928 // The arguments descriptor is never saved in the absence of optional | 946 // The arguments descriptor is never saved in the absence of optional |
929 // parameters, since any argument definition test would always yield true. | 947 // parameters, since any argument definition test would always yield true. |
930 ASSERT(saved_args_desc_var == NULL); | 948 ASSERT(saved_args_desc_var == NULL); |
931 } else { | 949 } else { |
932 if (saved_args_desc_var != NULL) { | 950 if (saved_args_desc_var != NULL) { |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1377 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1395 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
1378 __ Exchange(mem1, mem2); | 1396 __ Exchange(mem1, mem2); |
1379 } | 1397 } |
1380 | 1398 |
1381 | 1399 |
1382 #undef __ | 1400 #undef __ |
1383 | 1401 |
1384 } // namespace dart | 1402 } // namespace dart |
1385 | 1403 |
1386 #endif // defined TARGET_ARCH_X64 | 1404 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |