| 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 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 target_function.ToFullyQualifiedCString(), | 784 target_function.ToFullyQualifiedCString(), |
| 785 target_code.EntryPoint()); | 785 target_code.EntryPoint()); |
| 786 } | 786 } |
| 787 arguments.SetReturn(target_code); | 787 arguments.SetReturn(target_code); |
| 788 } | 788 } |
| 789 | 789 |
| 790 | 790 |
| 791 // Resolves and compiles the target function of an instance call, updates | 791 // Resolves and compiles the target function of an instance call, updates |
| 792 // function cache of the receiver's class and returns the compiled code or null. | 792 // function cache of the receiver's class and returns the compiled code or null. |
| 793 // Only the number of named arguments is checked, but not the actual names. | 793 // Only the number of named arguments is checked, but not the actual names. |
| 794 RawCode* ResolveCompileInstanceCallTarget(Isolate* isolate, | 794 RawCode* ResolveCompileInstanceCallTarget( |
| 795 const Instance& receiver) { | 795 const Instance& receiver, |
| 796 int num_arguments = -1; | 796 const ICData& ic_data, |
| 797 int num_named_arguments = -1; | 797 const ArgumentsDescriptor& arguments_descriptor) { |
| 798 uword target = 0; | 798 intptr_t num_arguments = arguments_descriptor.Count(); |
| 799 String& function_name = String::Handle(); | 799 int num_named_arguments = arguments_descriptor.NamedCount(); |
| 800 DartFrameIterator iterator; | 800 String& function_name = String::Handle(ic_data.target_name()); |
| 801 StackFrame* caller_frame = iterator.NextFrame(); | |
| 802 ASSERT(caller_frame != NULL); | |
| 803 CodePatcher::GetInstanceCallAt(caller_frame->pc(), | |
| 804 &function_name, | |
| 805 &num_arguments, | |
| 806 &num_named_arguments, | |
| 807 &target); | |
| 808 ASSERT(function_name.IsSymbol()); | 801 ASSERT(function_name.IsSymbol()); |
| 809 | 802 |
| 810 Function& function = Function::Handle(); | 803 Function& function = Function::Handle(); |
| 811 function = Resolver::ResolveDynamic(receiver, | 804 function = Resolver::ResolveDynamic(receiver, |
| 812 function_name, | 805 function_name, |
| 813 num_arguments, | 806 num_arguments, |
| 814 num_named_arguments); | 807 num_named_arguments); |
| 815 if (function.IsNull()) { | 808 if (function.IsNull()) { |
| 816 return Code::null(); | 809 return Code::null(); |
| 817 } else { | 810 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 830 // rethrow it. | 823 // rethrow it. |
| 831 static void CheckResultError(const Object& result) { | 824 static void CheckResultError(const Object& result) { |
| 832 if (result.IsError()) { | 825 if (result.IsError()) { |
| 833 Exceptions::PropagateError(Error::Cast(result)); | 826 Exceptions::PropagateError(Error::Cast(result)); |
| 834 } | 827 } |
| 835 } | 828 } |
| 836 | 829 |
| 837 | 830 |
| 838 // Resolves an instance function and compiles it if necessary. | 831 // Resolves an instance function and compiles it if necessary. |
| 839 // Arg0: receiver object. | 832 // Arg0: receiver object. |
| 833 // Arg1: IC data object. |
| 834 // Arg2: Arguments descriptor array. |
| 840 // Returns: RawCode object or NULL (method not found or not compileable). | 835 // Returns: RawCode object or NULL (method not found or not compileable). |
| 841 // This is called by the megamorphic stub when instance call does not need to be | 836 // This is called by the megamorphic stub when instance call does not need to be |
| 842 // patched. | 837 // patched. |
| 843 // Used by megamorphic lookup/no-such-method-handling. | 838 // Used by megamorphic lookup/no-such-method-handling. |
| 844 DEFINE_RUNTIME_ENTRY(ResolveCompileInstanceFunction, 1) { | 839 DEFINE_RUNTIME_ENTRY(ResolveCompileInstanceFunction, 3) { |
| 845 ASSERT(arguments.ArgCount() == | 840 ASSERT(arguments.ArgCount() == |
| 846 kResolveCompileInstanceFunctionRuntimeEntry.argument_count()); | 841 kResolveCompileInstanceFunctionRuntimeEntry.argument_count()); |
| 847 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 842 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 848 const Code& code = Code::Handle( | 843 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 849 ResolveCompileInstanceCallTarget(isolate, receiver)); | 844 ArgumentsDescriptor arg_descriptor(arguments.ArgAt(2)); |
| 845 const Code& code = |
| 846 Code::Handle(ResolveCompileInstanceCallTarget(receiver, |
| 847 ic_data, |
| 848 arg_descriptor)); |
| 850 arguments.SetReturn(code); | 849 arguments.SetReturn(code); |
| 851 } | 850 } |
| 852 | 851 |
| 853 | 852 |
| 854 // Gets called from debug stub when code reaches a breakpoint. | 853 // Gets called from debug stub when code reaches a breakpoint. |
| 855 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 0) { | 854 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 0) { |
| 856 ASSERT(arguments.ArgCount() == | 855 ASSERT(arguments.ArgCount() == |
| 857 kBreakpointStaticHandlerRuntimeEntry.argument_count()); | 856 kBreakpointStaticHandlerRuntimeEntry.argument_count()); |
| 858 ASSERT(isolate->debugger() != NULL); | 857 ASSERT(isolate->debugger() != NULL); |
| 859 isolate->debugger()->SignalBpReached(); | 858 isolate->debugger()->SignalBpReached(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 890 // Gets called from debug stub when code reaches a breakpoint. | 889 // Gets called from debug stub when code reaches a breakpoint. |
| 891 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) { | 890 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) { |
| 892 ASSERT(arguments.ArgCount() == | 891 ASSERT(arguments.ArgCount() == |
| 893 kBreakpointDynamicHandlerRuntimeEntry.argument_count()); | 892 kBreakpointDynamicHandlerRuntimeEntry.argument_count()); |
| 894 ASSERT(isolate->debugger() != NULL); | 893 ASSERT(isolate->debugger() != NULL); |
| 895 isolate->debugger()->SignalBpReached(); | 894 isolate->debugger()->SignalBpReached(); |
| 896 } | 895 } |
| 897 | 896 |
| 898 | 897 |
| 899 static RawFunction* InlineCacheMissHandler( | 898 static RawFunction* InlineCacheMissHandler( |
| 900 Isolate* isolate, const GrowableArray<const Instance*>& args) { | 899 const GrowableArray<const Instance*>& args, |
| 900 const ICData& ic_data, |
| 901 const ArgumentsDescriptor& arg_descriptor) { |
| 901 const Instance& receiver = *args[0]; | 902 const Instance& receiver = *args[0]; |
| 902 const Code& target_code = | 903 const Code& target_code = |
| 903 Code::Handle(ResolveCompileInstanceCallTarget(isolate, receiver)); | 904 Code::Handle(ResolveCompileInstanceCallTarget(receiver, |
| 905 ic_data, |
| 906 arg_descriptor)); |
| 904 if (target_code.IsNull()) { | 907 if (target_code.IsNull()) { |
| 905 // Let the megamorphic stub handle special cases: NoSuchMethod, | 908 // Let the megamorphic stub handle special cases: NoSuchMethod, |
| 906 // closure calls. | 909 // closure calls. |
| 907 if (FLAG_trace_ic) { | 910 if (FLAG_trace_ic) { |
| 908 OS::Print("InlineCacheMissHandler NULL code for receiver: %s\n", | 911 OS::Print("InlineCacheMissHandler NULL code for receiver: %s\n", |
| 909 receiver.ToCString()); | 912 receiver.ToCString()); |
| 910 } | 913 } |
| 911 return Function::null(); | 914 return Function::null(); |
| 912 } | 915 } |
| 913 const Function& target_function = | 916 const Function& target_function = |
| 914 Function::Handle(target_code.function()); | 917 Function::Handle(target_code.function()); |
| 915 ASSERT(!target_function.IsNull()); | 918 ASSERT(!target_function.IsNull()); |
| 916 DartFrameIterator iterator; | 919 DartFrameIterator iterator; |
| 917 StackFrame* caller_frame = iterator.NextFrame(); | 920 StackFrame* caller_frame = iterator.NextFrame(); |
| 918 ASSERT(caller_frame != NULL); | 921 ASSERT(caller_frame != NULL); |
| 919 ICData& ic_data = ICData::Handle( | |
| 920 CodePatcher::GetInstanceCallIcDataAt(caller_frame->pc())); | |
| 921 if (args.length() == 1) { | 922 if (args.length() == 1) { |
| 922 ic_data.AddReceiverCheck(Class::Handle(args[0]->clazz()).id(), | 923 ic_data.AddReceiverCheck(Class::Handle(args[0]->clazz()).id(), |
| 923 target_function); | 924 target_function); |
| 924 } else { | 925 } else { |
| 925 GrowableArray<intptr_t> class_ids(args.length()); | 926 GrowableArray<intptr_t> class_ids(args.length()); |
| 926 ASSERT(ic_data.num_args_tested() == args.length()); | 927 ASSERT(ic_data.num_args_tested() == args.length()); |
| 927 for (intptr_t i = 0; i < args.length(); i++) { | 928 for (intptr_t i = 0; i < args.length(); i++) { |
| 928 class_ids.Add(Class::Handle(args[i]->clazz()).id()); | 929 class_ids.Add(Class::Handle(args[i]->clazz()).id()); |
| 929 } | 930 } |
| 930 ic_data.AddCheck(class_ids, target_function); | 931 ic_data.AddCheck(class_ids, target_function); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 946 Class::Handle(receiver.clazz()).id(), | 947 Class::Handle(receiver.clazz()).id(), |
| 947 target_function.ToCString()); | 948 target_function.ToCString()); |
| 948 } | 949 } |
| 949 return target_function.raw(); | 950 return target_function.raw(); |
| 950 } | 951 } |
| 951 | 952 |
| 952 | 953 |
| 953 // Handles inline cache misses by updating the IC data array of the call | 954 // Handles inline cache misses by updating the IC data array of the call |
| 954 // site. | 955 // site. |
| 955 // Arg0: Receiver object. | 956 // Arg0: Receiver object. |
| 957 // Arg1: IC data object. |
| 958 // Arg2: Arguments descriptor array. |
| 956 // Returns: target function with compiled code or null. | 959 // Returns: target function with compiled code or null. |
| 957 // Modifies the instance call to hold the updated IC data array. | 960 // Modifies the instance call to hold the updated IC data array. |
| 958 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 1) { | 961 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 3) { |
| 959 ASSERT(arguments.ArgCount() == | 962 ASSERT(arguments.ArgCount() == |
| 960 kInlineCacheMissHandlerOneArgRuntimeEntry.argument_count()); | 963 kInlineCacheMissHandlerOneArgRuntimeEntry.argument_count()); |
| 961 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 964 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 965 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 966 ArgumentsDescriptor arg_descriptor(arguments.ArgAt(2)); |
| 962 GrowableArray<const Instance*> args(1); | 967 GrowableArray<const Instance*> args(1); |
| 963 args.Add(&receiver); | 968 args.Add(&receiver); |
| 964 const Function& result = | 969 const Function& result = |
| 965 Function::Handle(InlineCacheMissHandler(isolate, args)); | 970 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_descriptor)); |
| 966 arguments.SetReturn(result); | 971 arguments.SetReturn(result); |
| 967 } | 972 } |
| 968 | 973 |
| 969 | 974 |
| 970 // Handles inline cache misses by updating the IC data array of the call | 975 // Handles inline cache misses by updating the IC data array of the call |
| 971 // site. | 976 // site. |
| 972 // Arg0: Receiver object. | 977 // Arg0: Receiver object. |
| 973 // Arg1: Argument after receiver. | 978 // Arg1: Argument after receiver. |
| 979 // Arg2: IC data object. |
| 980 // Arg3: Arguments descriptor array. |
| 974 // Returns: target function with compiled code or null. | 981 // Returns: target function with compiled code or null. |
| 975 // Modifies the instance call to hold the updated IC data array. | 982 // Modifies the instance call to hold the updated IC data array. |
| 976 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 2) { | 983 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 4) { |
| 977 ASSERT(arguments.ArgCount() == | 984 ASSERT(arguments.ArgCount() == |
| 978 kInlineCacheMissHandlerTwoArgsRuntimeEntry.argument_count()); | 985 kInlineCacheMissHandlerTwoArgsRuntimeEntry.argument_count()); |
| 979 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 986 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 980 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); | 987 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 988 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); |
| 989 ArgumentsDescriptor arg_descriptor(arguments.ArgAt(3)); |
| 981 GrowableArray<const Instance*> args(2); | 990 GrowableArray<const Instance*> args(2); |
| 982 args.Add(&receiver); | 991 args.Add(&receiver); |
| 983 args.Add(&other); | 992 args.Add(&other); |
| 984 const Function& result = | 993 const Function& result = |
| 985 Function::Handle(InlineCacheMissHandler(isolate, args)); | 994 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_descriptor)); |
| 986 arguments.SetReturn(result); | 995 arguments.SetReturn(result); |
| 987 } | 996 } |
| 988 | 997 |
| 989 | 998 |
| 990 // Handles inline cache misses by updating the IC data array of the call | 999 // Handles inline cache misses by updating the IC data array of the call |
| 991 // site. | 1000 // site. |
| 992 // Arg0: Receiver object. | 1001 // Arg0: Receiver object. |
| 993 // Arg1: Argument after receiver. | 1002 // Arg1: Argument after receiver. |
| 994 // Arg2: Second argument after receiver. | 1003 // Arg2: Second argument after receiver. |
| 1004 // Arg3: IC data object. |
| 1005 // Arg4: Arguments descriptor array. |
| 995 // Returns: target function with compiled code or null. | 1006 // Returns: target function with compiled code or null. |
| 996 // Modifies the instance call to hold the updated IC data array. | 1007 // Modifies the instance call to hold the updated IC data array. |
| 997 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 3) { | 1008 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 5) { |
| 998 ASSERT(arguments.ArgCount() == | 1009 ASSERT(arguments.ArgCount() == |
| 999 kInlineCacheMissHandlerThreeArgsRuntimeEntry.argument_count()); | 1010 kInlineCacheMissHandlerThreeArgsRuntimeEntry.argument_count()); |
| 1000 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 1011 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1001 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); | 1012 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 1002 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); | 1013 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); |
| 1014 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(3)); |
| 1015 ArgumentsDescriptor arg_descriptor(arguments.ArgAt(4)); |
| 1003 GrowableArray<const Instance*> args(3); | 1016 GrowableArray<const Instance*> args(3); |
| 1004 args.Add(&receiver); | 1017 args.Add(&receiver); |
| 1005 args.Add(&arg1); | 1018 args.Add(&arg1); |
| 1006 args.Add(&arg2); | 1019 args.Add(&arg2); |
| 1007 const Function& result = | 1020 const Function& result = |
| 1008 Function::Handle(InlineCacheMissHandler(isolate, args)); | 1021 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_descriptor)); |
| 1009 arguments.SetReturn(result); | 1022 arguments.SetReturn(result); |
| 1010 } | 1023 } |
| 1011 | 1024 |
| 1012 | 1025 |
| 1013 // Updates IC data for two arguments. Used by the equality operation when | 1026 // Updates IC data for two arguments. Used by the equality operation when |
| 1014 // the control flow bypasses regular inline cache (null arguments). | 1027 // the control flow bypasses regular inline cache (null arguments). |
| 1015 // Arg0: Receiver object. | 1028 // Arg0: Receiver object. |
| 1016 // Arg1: Argument after receiver. | 1029 // Arg1: Argument after receiver. |
| 1017 // Arg2: Target's name. | 1030 // Arg2: Target's name. |
| 1018 // Arg3: ICData. | 1031 // Arg3: ICData. |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1878 Isolate* isolate = Isolate::Current(); | 1891 Isolate* isolate = Isolate::Current(); |
| 1879 StackZone zone(isolate); | 1892 StackZone zone(isolate); |
| 1880 HANDLESCOPE(isolate); | 1893 HANDLESCOPE(isolate); |
| 1881 const Bigint& big_left = Bigint::Handle(left); | 1894 const Bigint& big_left = Bigint::Handle(left); |
| 1882 const Bigint& big_right = Bigint::Handle(right); | 1895 const Bigint& big_right = Bigint::Handle(right); |
| 1883 return BigintOperations::Compare(big_left, big_right); | 1896 return BigintOperations::Compare(big_left, big_right); |
| 1884 } | 1897 } |
| 1885 END_LEAF_RUNTIME_ENTRY | 1898 END_LEAF_RUNTIME_ENTRY |
| 1886 | 1899 |
| 1887 } // namespace dart | 1900 } // namespace dart |
| OLD | NEW |