Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Side by Side Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 19200002: Change resolving of instance methods to check early for name mismatch. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/flow_graph_optimizer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 __ movq(RAX, argument_addr); 886 __ movq(RAX, argument_addr);
887 __ movq(copy_addr, RAX); 887 __ movq(copy_addr, RAX);
888 __ Bind(&loop_condition); 888 __ Bind(&loop_condition);
889 __ decq(RCX); 889 __ decq(RCX);
890 __ j(POSITIVE, &loop, Assembler::kNearJump); 890 __ j(POSITIVE, &loop, Assembler::kNearJump);
891 891
892 // Copy or initialize optional named arguments. 892 // Copy or initialize optional named arguments.
893 const Immediate& raw_null = 893 const Immediate& raw_null =
894 Immediate(reinterpret_cast<intptr_t>(Object::null())); 894 Immediate(reinterpret_cast<intptr_t>(Object::null()));
895 Label all_arguments_processed; 895 Label all_arguments_processed;
896 #ifdef DEBUG
897 const bool check_correct_named_args = true;
898 #else
899 const bool check_correct_named_args = function.IsClosureFunction();
900 #endif
896 if (num_opt_named_params > 0) { 901 if (num_opt_named_params > 0) {
897 // Start by alphabetically sorting the names of the optional parameters. 902 // Start by alphabetically sorting the names of the optional parameters.
898 LocalVariable** opt_param = new LocalVariable*[num_opt_named_params]; 903 LocalVariable** opt_param = new LocalVariable*[num_opt_named_params];
899 int* opt_param_position = new int[num_opt_named_params]; 904 int* opt_param_position = new int[num_opt_named_params];
900 for (int pos = num_fixed_params; pos < num_params; pos++) { 905 for (int pos = num_fixed_params; pos < num_params; pos++) {
901 LocalVariable* parameter = scope->VariableAt(pos); 906 LocalVariable* parameter = scope->VariableAt(pos);
902 const String& opt_param_name = parameter->name(); 907 const String& opt_param_name = parameter->name();
903 int i = pos - num_fixed_params; 908 int i = pos - num_fixed_params;
904 while (--i >= 0) { 909 while (--i >= 0) {
905 LocalVariable* param_i = opt_param[i]; 910 LocalVariable* param_i = opt_param[i];
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 // Assign RAX to fp[kFirstLocalSlotFromFp - param_pos]. 958 // Assign RAX to fp[kFirstLocalSlotFromFp - param_pos].
954 // We do not use the final allocation index of the variable here, i.e. 959 // We do not use the final allocation index of the variable here, i.e.
955 // scope->VariableAt(i)->index(), because captured variables still need 960 // scope->VariableAt(i)->index(), because captured variables still need
956 // to be copied to the context that is not yet allocated. 961 // to be copied to the context that is not yet allocated.
957 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 962 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
958 const Address param_addr(RBP, computed_param_pos * kWordSize); 963 const Address param_addr(RBP, computed_param_pos * kWordSize);
959 __ movq(param_addr, RAX); 964 __ movq(param_addr, RAX);
960 } 965 }
961 delete[] opt_param; 966 delete[] opt_param;
962 delete[] opt_param_position; 967 delete[] opt_param_position;
963 // Check that RDI now points to the null terminator in the array descriptor. 968 if (check_correct_named_args) {
964 __ cmpq(Address(RDI, 0), raw_null); 969 // Check that RDI now points to the null terminator in the arguments
965 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 970 // descriptor.
971 __ cmpq(Address(RDI, 0), raw_null);
972 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
973 }
966 } else { 974 } else {
967 ASSERT(num_opt_pos_params > 0); 975 ASSERT(num_opt_pos_params > 0);
968 __ movq(RCX, 976 __ movq(RCX,
969 FieldAddress(R10, ArgumentsDescriptor::positional_count_offset())); 977 FieldAddress(R10, ArgumentsDescriptor::positional_count_offset()));
970 __ SmiUntag(RCX); 978 __ SmiUntag(RCX);
971 for (int i = 0; i < num_opt_pos_params; i++) { 979 for (int i = 0; i < num_opt_pos_params; i++) {
972 Label next_parameter; 980 Label next_parameter;
973 // Handle this optional positional parameter only if k or fewer positional 981 // Handle this optional positional parameter only if k or fewer positional
974 // arguments have been passed, where k is param_pos, the position of this 982 // arguments have been passed, where k is param_pos, the position of this
975 // optional parameter in the formal parameter list. 983 // optional parameter in the formal parameter list.
976 const int param_pos = num_fixed_params + i; 984 const int param_pos = num_fixed_params + i;
977 __ cmpq(RCX, Immediate(param_pos)); 985 __ cmpq(RCX, Immediate(param_pos));
978 __ j(GREATER, &next_parameter, Assembler::kNearJump); 986 __ j(GREATER, &next_parameter, Assembler::kNearJump);
979 // Load RAX with default argument. 987 // Load RAX with default argument.
980 const Object& value = Object::ZoneHandle( 988 const Object& value = Object::ZoneHandle(
981 parsed_function().default_parameter_values().At(i)); 989 parsed_function().default_parameter_values().At(i));
982 __ LoadObject(RAX, value); 990 __ LoadObject(RAX, value);
983 // Assign RAX to fp[kFirstLocalSlotFromFp - param_pos]. 991 // Assign RAX to fp[kFirstLocalSlotFromFp - param_pos].
984 // We do not use the final allocation index of the variable here, i.e. 992 // We do not use the final allocation index of the variable here, i.e.
985 // scope->VariableAt(i)->index(), because captured variables still need 993 // scope->VariableAt(i)->index(), because captured variables still need
986 // to be copied to the context that is not yet allocated. 994 // to be copied to the context that is not yet allocated.
987 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 995 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
988 const Address param_addr(RBP, computed_param_pos * kWordSize); 996 const Address param_addr(RBP, computed_param_pos * kWordSize);
989 __ movq(param_addr, RAX); 997 __ movq(param_addr, RAX);
990 __ Bind(&next_parameter); 998 __ Bind(&next_parameter);
991 } 999 }
992 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1000 if (check_correct_named_args) {
993 __ SmiUntag(RBX); 1001 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
994 // Check that RCX equals RBX, i.e. no named arguments passed. 1002 __ SmiUntag(RBX);
995 __ cmpq(RCX, RBX); 1003 // Check that RCX equals RBX, i.e. no named arguments passed.
996 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 1004 __ cmpq(RCX, RBX);
1005 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
1006 }
997 } 1007 }
998 1008
999 __ Bind(&wrong_num_arguments); 1009 __ Bind(&wrong_num_arguments);
1000 // Invoke noSuchMethod function passing the original name of the function. 1010 if (function.IsClosureFunction()) {
1001 // If the function is a closure function, use "call" as the original name. 1011 // Invoke noSuchMethod function passing "call" as the original name.
1002 const String& name = String::Handle( 1012 const int kNumArgsChecked = 1;
1003 function.IsClosureFunction() ? Symbols::Call().raw() : function.name()); 1013 const ICData& ic_data = ICData::ZoneHandle(
1004 const int kNumArgsChecked = 1; 1014 ICData::New(function, Symbols::Call(), Object::null_array(),
1005 const ICData& ic_data = ICData::ZoneHandle( 1015 Isolate::kNoDeoptId, kNumArgsChecked));
1006 ICData::New(function, name, Object::null_array(), 1016 __ LoadObject(RBX, ic_data);
1007 Isolate::kNoDeoptId, kNumArgsChecked)); 1017 __ LeaveFrame(); // The arguments are still on the stack.
1008 __ LoadObject(RBX, ic_data); 1018 __ jmp(&StubCode::CallNoSuchMethodFunctionLabel());
1009 __ LeaveFrame(); // The arguments are still on the stack. 1019 // The noSuchMethod call may return to the caller, but not here.
1010 __ jmp(&StubCode::CallNoSuchMethodFunctionLabel()); 1020 __ int3();
1011 // The noSuchMethod call may return to the caller, but not here. 1021 } else if (check_correct_named_args) {
1012 __ int3(); 1022 __ Stop("Wrong arguments");
1023 }
1013 1024
1014 __ Bind(&all_arguments_processed); 1025 __ Bind(&all_arguments_processed);
1015 // Nullify originally passed arguments only after they have been copied and 1026 // Nullify originally passed arguments only after they have been copied and
1016 // checked, otherwise noSuchMethod would not see their original values. 1027 // checked, otherwise noSuchMethod would not see their original values.
1017 // This step can be skipped in case we decide that formal parameters are 1028 // This step can be skipped in case we decide that formal parameters are
1018 // implicitly final, since garbage collecting the unmodified value is not 1029 // implicitly final, since garbage collecting the unmodified value is not
1019 // an issue anymore. 1030 // an issue anymore.
1020 1031
1021 // R10 : arguments descriptor array. 1032 // R10 : arguments descriptor array.
1022 __ movq(RCX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1033 __ movq(RCX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 __ movups(reg, Address(RSP, 0)); 1900 __ movups(reg, Address(RSP, 0));
1890 __ addq(RSP, Immediate(kFpuRegisterSize)); 1901 __ addq(RSP, Immediate(kFpuRegisterSize));
1891 } 1902 }
1892 1903
1893 1904
1894 #undef __ 1905 #undef __
1895 1906
1896 } // namespace dart 1907 } // namespace dart
1897 1908
1898 #endif // defined TARGET_ARCH_X64 1909 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/flow_graph_optimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698