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

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

Issue 11438017: Pass IC data and arguments descriptor to IC miss runtime functions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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/code_generator.h ('k') | runtime/vm/code_patcher.h » ('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) 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/code_patcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698