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/code_generator.h" | 5 #include "vm/code_generator.h" |
6 | 6 |
7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 ASSERT(param_name.IsSymbol()); | 676 ASSERT(param_name.IsSymbol()); |
677 const Array& arg_desc_array = Array::CheckedHandle(arguments.ArgAt(2)); | 677 const Array& arg_desc_array = Array::CheckedHandle(arguments.ArgAt(2)); |
678 ArgumentsDescriptor arg_desc(arg_desc_array); | 678 ArgumentsDescriptor arg_desc(arg_desc_array); |
679 const intptr_t num_pos_args = arg_desc.PositionalCount(); | 679 const intptr_t num_pos_args = arg_desc.PositionalCount(); |
680 // Check if the formal parameter is defined by a positional argument. | 680 // Check if the formal parameter is defined by a positional argument. |
681 bool is_defined = num_pos_args > param_index.Value(); | 681 bool is_defined = num_pos_args > param_index.Value(); |
682 if (!is_defined) { | 682 if (!is_defined) { |
683 // Check if the formal parameter is defined by a named argument. | 683 // Check if the formal parameter is defined by a named argument. |
684 const intptr_t num_named_args = arg_desc.NamedCount(); | 684 const intptr_t num_named_args = arg_desc.NamedCount(); |
685 for (intptr_t i = 0; i < num_named_args; i++) { | 685 for (intptr_t i = 0; i < num_named_args; i++) { |
686 if (arg_desc.NameAt(i) == param_name.raw()) { | 686 if (arg_desc.MatchesNameAt(i, param_name)) { |
687 is_defined = true; | 687 is_defined = true; |
688 break; | 688 break; |
689 } | 689 } |
690 } | 690 } |
691 } | 691 } |
692 arguments.SetReturn(Bool::Handle(Bool::Get(is_defined))); | 692 arguments.SetReturn(Bool::Handle(Bool::Get(is_defined))); |
693 } | 693 } |
694 | 694 |
695 | 695 |
696 // Report that the type of the given object is not bool in conditional context. | 696 // Report that the type of the given object is not bool in conditional context. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 arguments.SetReturn(target_code); | 785 arguments.SetReturn(target_code); |
786 } | 786 } |
787 | 787 |
788 | 788 |
789 // Resolves and compiles the target function of an instance call, updates | 789 // Resolves and compiles the target function of an instance call, updates |
790 // function cache of the receiver's class and returns the compiled code or null. | 790 // function cache of the receiver's class and returns the compiled code or null. |
791 // Only the number of named arguments is checked, but not the actual names. | 791 // Only the number of named arguments is checked, but not the actual names. |
792 RawCode* ResolveCompileInstanceCallTarget( | 792 RawCode* ResolveCompileInstanceCallTarget( |
793 const Instance& receiver, | 793 const Instance& receiver, |
794 const ICData& ic_data, | 794 const ICData& ic_data, |
795 const ArgumentsDescriptor& arguments_descriptor) { | 795 const Array& arguments_descriptor_array) { |
| 796 ArgumentsDescriptor arguments_descriptor(arguments_descriptor_array); |
796 intptr_t num_arguments = arguments_descriptor.Count(); | 797 intptr_t num_arguments = arguments_descriptor.Count(); |
797 int num_named_arguments = arguments_descriptor.NamedCount(); | 798 int num_named_arguments = arguments_descriptor.NamedCount(); |
798 String& function_name = String::Handle(ic_data.target_name()); | 799 String& function_name = String::Handle(ic_data.target_name()); |
799 ASSERT(function_name.IsSymbol()); | 800 ASSERT(function_name.IsSymbol()); |
800 | 801 |
801 Function& function = Function::Handle(); | 802 Function& function = Function::Handle(); |
802 function = Resolver::ResolveDynamic(receiver, | 803 function = Resolver::ResolveDynamic(receiver, |
803 function_name, | 804 function_name, |
804 num_arguments, | 805 num_arguments, |
805 num_named_arguments); | 806 num_named_arguments); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
867 ASSERT(arguments.ArgCount() == | 868 ASSERT(arguments.ArgCount() == |
868 kBreakpointDynamicHandlerRuntimeEntry.argument_count()); | 869 kBreakpointDynamicHandlerRuntimeEntry.argument_count()); |
869 ASSERT(isolate->debugger() != NULL); | 870 ASSERT(isolate->debugger() != NULL); |
870 isolate->debugger()->SignalBpReached(); | 871 isolate->debugger()->SignalBpReached(); |
871 } | 872 } |
872 | 873 |
873 | 874 |
874 static RawFunction* InlineCacheMissHandler( | 875 static RawFunction* InlineCacheMissHandler( |
875 const GrowableArray<const Instance*>& args, | 876 const GrowableArray<const Instance*>& args, |
876 const ICData& ic_data, | 877 const ICData& ic_data, |
877 const ArgumentsDescriptor& arg_descriptor) { | 878 const Array& arg_descriptor_array) { |
878 const Instance& receiver = *args[0]; | 879 const Instance& receiver = *args[0]; |
879 const Code& target_code = | 880 const Code& target_code = |
880 Code::Handle(ResolveCompileInstanceCallTarget(receiver, | 881 Code::Handle(ResolveCompileInstanceCallTarget(receiver, |
881 ic_data, | 882 ic_data, |
882 arg_descriptor)); | 883 arg_descriptor_array)); |
883 if (target_code.IsNull()) { | 884 if (target_code.IsNull()) { |
884 // Let the megamorphic stub handle special cases: NoSuchMethod, | 885 // Let the megamorphic stub handle special cases: NoSuchMethod, |
885 // closure calls. | 886 // closure calls. |
886 if (FLAG_trace_ic) { | 887 if (FLAG_trace_ic) { |
887 OS::Print("InlineCacheMissHandler NULL code for receiver: %s\n", | 888 OS::Print("InlineCacheMissHandler NULL code for receiver: %s\n", |
888 receiver.ToCString()); | 889 receiver.ToCString()); |
889 } | 890 } |
890 return Function::null(); | 891 return Function::null(); |
891 } | 892 } |
892 const Function& target_function = | 893 const Function& target_function = |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 // Arg1: IC data object. | 934 // Arg1: IC data object. |
934 // Arg2: Arguments descriptor array. | 935 // Arg2: Arguments descriptor array. |
935 // Returns: target function with compiled code or null. | 936 // Returns: target function with compiled code or null. |
936 // Modifies the instance call to hold the updated IC data array. | 937 // Modifies the instance call to hold the updated IC data array. |
937 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 3) { | 938 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 3) { |
938 ASSERT(arguments.ArgCount() == | 939 ASSERT(arguments.ArgCount() == |
939 kInlineCacheMissHandlerOneArgRuntimeEntry.argument_count()); | 940 kInlineCacheMissHandlerOneArgRuntimeEntry.argument_count()); |
940 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 941 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
941 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 942 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
942 const Array& arg_desc_array = Array::CheckedHandle(arguments.ArgAt(2)); | 943 const Array& arg_desc_array = Array::CheckedHandle(arguments.ArgAt(2)); |
943 ArgumentsDescriptor arg_descriptor(arg_desc_array); | |
944 GrowableArray<const Instance*> args(1); | 944 GrowableArray<const Instance*> args(1); |
945 args.Add(&receiver); | 945 args.Add(&receiver); |
946 const Function& result = | 946 const Function& result = |
947 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_descriptor)); | 947 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_desc_array)); |
948 arguments.SetReturn(result); | 948 arguments.SetReturn(result); |
949 } | 949 } |
950 | 950 |
951 | 951 |
952 // Handles inline cache misses by updating the IC data array of the call | 952 // Handles inline cache misses by updating the IC data array of the call |
953 // site. | 953 // site. |
954 // Arg0: Receiver object. | 954 // Arg0: Receiver object. |
955 // Arg1: Argument after receiver. | 955 // Arg1: Argument after receiver. |
956 // Arg2: IC data object. | 956 // Arg2: IC data object. |
957 // Arg3: Arguments descriptor array. | 957 // Arg3: Arguments descriptor array. |
958 // Returns: target function with compiled code or null. | 958 // Returns: target function with compiled code or null. |
959 // Modifies the instance call to hold the updated IC data array. | 959 // Modifies the instance call to hold the updated IC data array. |
960 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 4) { | 960 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 4) { |
961 ASSERT(arguments.ArgCount() == | 961 ASSERT(arguments.ArgCount() == |
962 kInlineCacheMissHandlerTwoArgsRuntimeEntry.argument_count()); | 962 kInlineCacheMissHandlerTwoArgsRuntimeEntry.argument_count()); |
963 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 963 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
964 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); | 964 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); |
965 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); | 965 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); |
966 const Array& arg_desc_array = Array::CheckedHandle(arguments.ArgAt(3)); | 966 const Array& arg_desc_array = Array::CheckedHandle(arguments.ArgAt(3)); |
967 ArgumentsDescriptor arg_descriptor(arg_desc_array); | |
968 GrowableArray<const Instance*> args(2); | 967 GrowableArray<const Instance*> args(2); |
969 args.Add(&receiver); | 968 args.Add(&receiver); |
970 args.Add(&other); | 969 args.Add(&other); |
971 const Function& result = | 970 const Function& result = |
972 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_descriptor)); | 971 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_desc_array)); |
973 arguments.SetReturn(result); | 972 arguments.SetReturn(result); |
974 } | 973 } |
975 | 974 |
976 | 975 |
977 // Handles inline cache misses by updating the IC data array of the call | 976 // Handles inline cache misses by updating the IC data array of the call |
978 // site. | 977 // site. |
979 // Arg0: Receiver object. | 978 // Arg0: Receiver object. |
980 // Arg1: Argument after receiver. | 979 // Arg1: Argument after receiver. |
981 // Arg2: Second argument after receiver. | 980 // Arg2: Second argument after receiver. |
982 // Arg3: IC data object. | 981 // Arg3: IC data object. |
983 // Arg4: Arguments descriptor array. | 982 // Arg4: Arguments descriptor array. |
984 // Returns: target function with compiled code or null. | 983 // Returns: target function with compiled code or null. |
985 // Modifies the instance call to hold the updated IC data array. | 984 // Modifies the instance call to hold the updated IC data array. |
986 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 5) { | 985 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 5) { |
987 ASSERT(arguments.ArgCount() == | 986 ASSERT(arguments.ArgCount() == |
988 kInlineCacheMissHandlerThreeArgsRuntimeEntry.argument_count()); | 987 kInlineCacheMissHandlerThreeArgsRuntimeEntry.argument_count()); |
989 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 988 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
990 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); | 989 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
991 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); | 990 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); |
992 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(3)); | 991 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(3)); |
993 const Array& arg_desc_array = Array::CheckedHandle(arguments.ArgAt(4)); | 992 const Array& arg_desc_array = Array::CheckedHandle(arguments.ArgAt(4)); |
994 ArgumentsDescriptor arg_descriptor(arg_desc_array); | |
995 GrowableArray<const Instance*> args(3); | 993 GrowableArray<const Instance*> args(3); |
996 args.Add(&receiver); | 994 args.Add(&receiver); |
997 args.Add(&arg1); | 995 args.Add(&arg1); |
998 args.Add(&arg2); | 996 args.Add(&arg2); |
999 const Function& result = | 997 const Function& result = |
1000 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_descriptor)); | 998 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_desc_array)); |
1001 arguments.SetReturn(result); | 999 arguments.SetReturn(result); |
1002 } | 1000 } |
1003 | 1001 |
1004 | 1002 |
1005 // Updates IC data for two arguments. Used by the equality operation when | 1003 // Updates IC data for two arguments. Used by the equality operation when |
1006 // the control flow bypasses regular inline cache (null arguments). | 1004 // the control flow bypasses regular inline cache (null arguments). |
1007 // Arg0: Receiver object. | 1005 // Arg0: Receiver object. |
1008 // Arg1: Argument after receiver. | 1006 // Arg1: Argument after receiver. |
1009 // Arg2: Target's name. | 1007 // Arg2: Target's name. |
1010 // Arg3: ICData. | 1008 // Arg3: ICData. |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1870 Isolate* isolate = Isolate::Current(); | 1868 Isolate* isolate = Isolate::Current(); |
1871 StackZone zone(isolate); | 1869 StackZone zone(isolate); |
1872 HANDLESCOPE(isolate); | 1870 HANDLESCOPE(isolate); |
1873 const Bigint& big_left = Bigint::Handle(left); | 1871 const Bigint& big_left = Bigint::Handle(left); |
1874 const Bigint& big_right = Bigint::Handle(right); | 1872 const Bigint& big_right = Bigint::Handle(right); |
1875 return BigintOperations::Compare(big_left, big_right); | 1873 return BigintOperations::Compare(big_left, big_right); |
1876 } | 1874 } |
1877 END_LEAF_RUNTIME_ENTRY | 1875 END_LEAF_RUNTIME_ENTRY |
1878 | 1876 |
1879 } // namespace dart | 1877 } // namespace dart |
OLD | NEW |