Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 613 OS::PrintErr("PatchStaticCall: patching from %#" Px " to '%s' %#" Px "\n", | 613 OS::PrintErr("PatchStaticCall: patching from %#" Px " to '%s' %#" Px "\n", |
| 614 caller_frame->pc(), | 614 caller_frame->pc(), |
| 615 target_function.ToFullyQualifiedCString(), | 615 target_function.ToFullyQualifiedCString(), |
| 616 target_code.EntryPoint()); | 616 target_code.EntryPoint()); |
| 617 } | 617 } |
| 618 arguments.SetReturn(target_code); | 618 arguments.SetReturn(target_code); |
| 619 } | 619 } |
| 620 | 620 |
| 621 | 621 |
| 622 // Resolves and compiles the target function of an instance call, updates | 622 // Resolves and compiles the target function of an instance call, updates |
| 623 // function cache of the receiver's class and returns the compiled code or null. | 623 // function cache of the receiver's class and returns the function or null. |
| 624 // Only the number of named arguments is checked, but not the actual names. | 624 // Only the number of named arguments is checked, but not the actual names. |
| 625 RawCode* ResolveCompileInstanceCallTarget(const Instance& receiver, | 625 static RawFunction* ResolveCompileInstanceCallTarget(const Instance& receiver, |
| 626 const ICData& ic_data) { | 626 const ICData& ic_data) { |
|
srdjan
2014/04/03 18:30:23
This method does not compile a function as the nam
Florian Schneider
2014/04/04 09:31:27
Done. Removed this helper since it is only 3 lines
| |
| 627 ArgumentsDescriptor | 627 ArgumentsDescriptor |
| 628 arguments_descriptor(Array::Handle(ic_data.arguments_descriptor())); | 628 arguments_descriptor(Array::Handle(ic_data.arguments_descriptor())); |
| 629 String& function_name = String::Handle(ic_data.target_name()); | 629 String& function_name = String::Handle(ic_data.target_name()); |
| 630 ASSERT(function_name.IsSymbol()); | 630 ASSERT(function_name.IsSymbol()); |
| 631 | 631 |
| 632 Function& function = Function::Handle(); | 632 return Resolver::ResolveDynamic(receiver, |
| 633 function = Resolver::ResolveDynamic(receiver, | 633 function_name, |
| 634 function_name, | 634 arguments_descriptor); |
| 635 arguments_descriptor); | |
| 636 if (function.IsNull()) { | |
| 637 return Code::null(); | |
| 638 } else { | |
| 639 if (!function.HasCode()) { | |
| 640 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | |
| 641 if (!error.IsNull()) { | |
| 642 Exceptions::PropagateError(error); | |
| 643 } | |
| 644 } | |
| 645 return function.CurrentCode(); | |
| 646 } | |
| 647 } | 635 } |
| 648 | 636 |
| 649 | 637 |
| 650 // Result of an invoke may be an unhandled exception, in which case we | 638 // Result of an invoke may be an unhandled exception, in which case we |
| 651 // rethrow it. | 639 // rethrow it. |
| 652 static void CheckResultError(const Object& result) { | 640 static void CheckResultError(const Object& result) { |
| 653 if (result.IsError()) { | 641 if (result.IsError()) { |
| 654 Exceptions::PropagateError(Error::Cast(result)); | 642 Exceptions::PropagateError(Error::Cast(result)); |
| 655 } | 643 } |
| 656 } | 644 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 670 arguments.SetReturn(Smi::Handle(reinterpret_cast<RawSmi*>(orig_stub))); | 658 arguments.SetReturn(Smi::Handle(reinterpret_cast<RawSmi*>(orig_stub))); |
| 671 } | 659 } |
| 672 | 660 |
| 673 | 661 |
| 674 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { | 662 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { |
| 675 ASSERT(isolate->debugger() != NULL); | 663 ASSERT(isolate->debugger() != NULL); |
| 676 isolate->debugger()->DebuggerStepCallback(); | 664 isolate->debugger()->DebuggerStepCallback(); |
| 677 } | 665 } |
| 678 | 666 |
| 679 | 667 |
| 668 // An instance call of the form o.f(...) could not be resolved. Check if | |
| 669 // there is a getter with the same name. If so, invoke it. If the value is | |
| 670 // a closure, invoke it with the given arguments. If the value is a | |
| 671 // non-closure, attempt to invoke "call" on it. | |
| 672 static bool ResolveCallThroughGetter(const Instance& receiver, | |
| 673 const Class& receiver_class, | |
| 674 const String& target_name, | |
| 675 const Array& arguments_descriptor, | |
| 676 const ICData& ic_data, | |
| 677 Function* result) { | |
| 678 // 1. Check if there is a getter with the same name. | |
| 679 const String& getter_name = String::Handle(Field::GetterName(target_name)); | |
| 680 const int kNumArguments = 1; | |
| 681 ArgumentsDescriptor args_desc( | |
| 682 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | |
| 683 const Function& getter = Function::Handle( | |
| 684 Resolver::ResolveDynamicForReceiverClass(receiver_class, | |
| 685 getter_name, | |
| 686 args_desc)); | |
| 687 if (getter.IsNull() || getter.IsMethodExtractor()) { | |
| 688 return false; | |
| 689 } | |
| 690 | |
| 691 const Function& target_function = | |
| 692 Function::Handle(receiver_class.GetInvocationDispatcher( | |
| 693 target_name, | |
| 694 arguments_descriptor, | |
| 695 RawFunction::kInvokeFieldDispatcher)); | |
| 696 ASSERT(!target_function.IsNull()); | |
| 697 if (FLAG_trace_ic) { | |
| 698 OS::PrintErr("InvokeField IC miss: adding <%s> id:%" Pd " -> <%s>\n", | |
| 699 Class::Handle(receiver.clazz()).ToCString(), | |
| 700 receiver.GetClassId(), | |
| 701 target_function.ToCString()); | |
| 702 } | |
| 703 *result = target_function.raw(); | |
| 704 return true; | |
| 705 } | |
| 706 | |
| 707 | |
| 708 // Handle other invocations (implicit closures, noSuchMethod). | |
| 709 RawFunction* InlineCacheMissHelper( | |
| 710 const Instance& receiver, | |
| 711 const ICData& ic_data) { | |
| 712 const Array& args_descriptor = Array::Handle(ic_data.arguments_descriptor()); | |
| 713 | |
| 714 const Class& receiver_class = Class::Handle(receiver.clazz()); | |
| 715 const String& target_name = String::Handle(ic_data.target_name()); | |
| 716 | |
| 717 Function& result = Function::Handle(); | |
| 718 if (!ResolveCallThroughGetter(receiver, | |
| 719 receiver_class, | |
| 720 target_name, | |
| 721 args_descriptor, | |
| 722 ic_data, | |
| 723 &result)) { | |
| 724 ArgumentsDescriptor desc(args_descriptor); | |
| 725 const Function& target_function = | |
| 726 Function::Handle(receiver_class.GetInvocationDispatcher( | |
| 727 target_name, | |
| 728 args_descriptor, | |
| 729 RawFunction::kNoSuchMethodDispatcher)); | |
| 730 if (FLAG_trace_ic) { | |
| 731 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n", | |
| 732 Class::Handle(receiver.clazz()).ToCString(), | |
| 733 receiver.GetClassId(), | |
| 734 target_function.ToCString()); | |
| 735 } | |
| 736 result = target_function.raw(); | |
| 737 } | |
| 738 return result.raw(); | |
| 739 } | |
| 740 | |
| 680 static RawFunction* InlineCacheMissHandler( | 741 static RawFunction* InlineCacheMissHandler( |
| 681 const GrowableArray<const Instance*>& args, | 742 const GrowableArray<const Instance*>& args, |
| 682 const ICData& ic_data) { | 743 const ICData& ic_data) { |
| 683 const Instance& receiver = *args[0]; | 744 const Instance& receiver = *args[0]; |
| 684 const Code& target_code = | 745 Function& target_function = |
| 685 Code::Handle(ResolveCompileInstanceCallTarget(receiver, ic_data)); | 746 Function::Handle(ResolveCompileInstanceCallTarget(receiver, ic_data)); |
| 686 if (target_code.IsNull()) { | 747 if (target_function.IsNull()) { |
| 687 // Let the megamorphic stub handle special cases: NoSuchMethod, | |
| 688 // closure calls. | |
| 689 if (FLAG_trace_ic) { | 748 if (FLAG_trace_ic) { |
| 690 OS::PrintErr("InlineCacheMissHandler NULL code for %s receiver: %s\n", | 749 OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n", |
| 691 String::Handle(ic_data.target_name()).ToCString(), | 750 String::Handle(ic_data.target_name()).ToCString(), |
| 692 receiver.ToCString()); | 751 receiver.ToCString()); |
| 693 } | 752 } |
| 694 return Function::null(); | 753 ic_data.set_is_closure_call(true); |
| 754 target_function = InlineCacheMissHelper(receiver, ic_data); | |
| 695 } | 755 } |
| 696 const Function& target_function = | |
| 697 Function::Handle(target_code.function()); | |
| 698 ASSERT(!target_function.IsNull()); | 756 ASSERT(!target_function.IsNull()); |
| 699 if (args.length() == 1) { | 757 if (args.length() == 1) { |
| 700 ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function); | 758 ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function); |
| 701 } else { | 759 } else { |
| 702 GrowableArray<intptr_t> class_ids(args.length()); | 760 GrowableArray<intptr_t> class_ids(args.length()); |
| 703 ASSERT(ic_data.num_args_tested() == args.length()); | 761 ASSERT(ic_data.num_args_tested() == args.length()); |
| 704 for (intptr_t i = 0; i < args.length(); i++) { | 762 for (intptr_t i = 0; i < args.length(); i++) { |
| 705 class_ids.Add(args[i]->GetClassId()); | 763 class_ids.Add(args[i]->GetClassId()); |
| 706 } | 764 } |
| 707 ic_data.AddCheck(class_ids, target_function); | 765 ic_data.AddCheck(class_ids, target_function); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 825 } | 883 } |
| 826 arguments.SetReturn(target); | 884 arguments.SetReturn(target); |
| 827 } | 885 } |
| 828 | 886 |
| 829 | 887 |
| 830 // Handle a miss of a megamorphic cache. | 888 // Handle a miss of a megamorphic cache. |
| 831 // Arg0: Receiver. | 889 // Arg0: Receiver. |
| 832 // Arg1: ICData object. | 890 // Arg1: ICData object. |
| 833 // Arg2: Arguments descriptor array. | 891 // Arg2: Arguments descriptor array. |
| 834 | 892 |
| 835 // Returns: target instructions to call or null if the | 893 // Returns: target function to call or null if the |
|
srdjan
2014/04/03 18:30:23
truncated comment
Florian Schneider
2014/04/04 09:31:27
Done.
| |
| 836 // InstanceFunctionLookup stub should be used (e.g., to invoke no such | |
| 837 // method and implicit closures).. | |
| 838 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { | 894 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { |
| 839 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 895 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 840 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 896 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 841 const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2)); | 897 const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2)); |
| 842 const String& name = String::Handle(ic_data.target_name()); | 898 const String& name = String::Handle(ic_data.target_name()); |
| 843 const MegamorphicCache& cache = MegamorphicCache::Handle( | 899 const MegamorphicCache& cache = MegamorphicCache::Handle( |
| 844 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); | 900 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); |
| 845 Class& cls = Class::Handle(receiver.clazz()); | 901 Class& cls = Class::Handle(receiver.clazz()); |
| 846 ASSERT(!cls.IsNull()); | 902 ASSERT(!cls.IsNull()); |
| 847 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { | 903 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { |
| 848 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", | 904 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", |
| 849 cls.ToCString(), name.ToCString()); | 905 cls.ToCString(), name.ToCString()); |
| 850 } | 906 } |
| 851 | 907 |
| 852 ArgumentsDescriptor args_desc(descriptor); | 908 ArgumentsDescriptor args_desc(descriptor); |
| 853 const Function& target = Function::Handle( | 909 Function& target_function = Function::Handle( |
| 854 Resolver::ResolveDynamicForReceiverClass(cls, | 910 Resolver::ResolveDynamicForReceiverClass(cls, |
| 855 name, | 911 name, |
| 856 args_desc)); | 912 args_desc)); |
| 913 if (target_function.IsNull()) { | |
| 914 ic_data.set_is_closure_call(true); | |
| 915 target_function = InlineCacheMissHelper(receiver, ic_data); | |
| 916 } | |
| 857 | 917 |
| 858 Instructions& instructions = Instructions::Handle(); | 918 ASSERT(!target_function.IsNull()); |
| 859 if (!target.IsNull()) { | 919 // Insert function found into cache and return it. |
| 860 if (!target.HasCode()) { | |
| 861 const Error& error = Error::Handle(Compiler::CompileFunction(target)); | |
| 862 if (!error.IsNull()) { | |
| 863 Exceptions::PropagateError(error); | |
| 864 } | |
| 865 } | |
| 866 ASSERT(target.HasCode()); | |
| 867 instructions = Code::Handle(target.CurrentCode()).instructions(); | |
| 868 } | |
| 869 arguments.SetReturn(instructions); | |
| 870 if (instructions.IsNull()) return; | |
| 871 | |
| 872 cache.EnsureCapacity(); | 920 cache.EnsureCapacity(); |
| 873 const Smi& class_id = Smi::Handle(Smi::New(cls.id())); | 921 const Smi& class_id = Smi::Handle(Smi::New(cls.id())); |
| 874 cache.Insert(class_id, target); | 922 cache.Insert(class_id, target_function); |
| 875 return; | 923 arguments.SetReturn(target_function); |
|
srdjan
2014/04/03 18:30:23
Who compiles the target_function? The caller of th
Florian Schneider
2014/04/04 09:31:27
The lazy-compile stub compile the target function
srdjan
2014/04/04 15:36:24
It seems that only ARM64 is not installing the laz
| |
| 876 } | 924 } |
| 877 | 925 |
| 878 | 926 |
| 879 // Updates IC data for two arguments. Used by the equality operation when | 927 // Updates IC data for two arguments. Used by the equality operation when |
| 880 // the control flow bypasses regular inline cache (null arguments). | 928 // the control flow bypasses regular inline cache (null arguments). |
| 881 // Arg0: Receiver object. | 929 // Arg0: Receiver object. |
| 882 // Arg1: Argument after receiver. | 930 // Arg1: Argument after receiver. |
| 883 // Arg2: Target's name. | 931 // Arg2: Target's name. |
| 884 // Arg3: ICData. | 932 // Arg3: ICData. |
| 885 DEFINE_RUNTIME_ENTRY(UpdateICDataTwoArgs, 4) { | 933 DEFINE_RUNTIME_ENTRY(UpdateICDataTwoArgs, 4) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(0)); | 991 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(0)); |
| 944 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1)); | 992 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1)); |
| 945 | 993 |
| 946 const Object& result = Object::Handle( | 994 const Object& result = Object::Handle( |
| 947 DartEntry::InvokeClosure(function_args, args_descriptor)); | 995 DartEntry::InvokeClosure(function_args, args_descriptor)); |
| 948 CheckResultError(result); | 996 CheckResultError(result); |
| 949 arguments.SetReturn(result); | 997 arguments.SetReturn(result); |
| 950 } | 998 } |
| 951 | 999 |
| 952 | 1000 |
| 953 // An instance call of the form o.f(...) could not be resolved. Check if | |
| 954 // there is a getter with the same name. If so, invoke it. If the value is | |
| 955 // a closure, invoke it with the given arguments. If the value is a | |
| 956 // non-closure, attempt to invoke "call" on it. | |
| 957 static bool ResolveCallThroughGetter(const Instance& receiver, | |
| 958 const Class& receiver_class, | |
| 959 const String& target_name, | |
| 960 const Array& arguments_descriptor, | |
| 961 const Array& arguments, | |
| 962 const ICData& ic_data, | |
| 963 Object* result) { | |
| 964 // 1. Check if there is a getter with the same name. | |
| 965 const String& getter_name = String::Handle(Field::GetterName(target_name)); | |
| 966 const int kNumArguments = 1; | |
| 967 ArgumentsDescriptor args_desc( | |
| 968 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | |
| 969 const Function& getter = Function::Handle( | |
| 970 Resolver::ResolveDynamicForReceiverClass(receiver_class, | |
| 971 getter_name, | |
| 972 args_desc)); | |
| 973 if (getter.IsNull() || getter.IsMethodExtractor()) { | |
| 974 return false; | |
| 975 } | |
| 976 | |
| 977 const Function& target_function = | |
| 978 Function::Handle(receiver_class.GetInvocationDispatcher( | |
| 979 target_name, | |
| 980 arguments_descriptor, | |
| 981 RawFunction::kInvokeFieldDispatcher)); | |
| 982 // Update IC data. | |
| 983 ASSERT(!target_function.IsNull()); | |
| 984 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); | |
| 985 if (FLAG_trace_ic) { | |
| 986 OS::PrintErr("InvokeField IC miss: adding <%s> id:%" Pd " -> <%s>\n", | |
| 987 Class::Handle(receiver.clazz()).ToCString(), | |
| 988 receiver.GetClassId(), | |
| 989 target_function.ToCString()); | |
| 990 } | |
| 991 *result = DartEntry::InvokeFunction(target_function, | |
| 992 arguments, | |
| 993 arguments_descriptor); | |
| 994 CheckResultError(*result); | |
| 995 return true; | |
| 996 } | |
| 997 | |
| 998 | |
| 999 // The IC miss handler has failed to find a (cacheable) instance function to | |
| 1000 // invoke. Handle three possibilities: | |
| 1001 // | |
| 1002 // 1. If the call was a getter o.f, there may be an instance function with | |
| 1003 // the same name. If so, create an implicit closure and return it. | |
| 1004 // | |
| 1005 // 2. If the call was an instance call o.f(...), there may be a getter with | |
| 1006 // the same name. If so, invoke it. If the value is a closure, invoke | |
| 1007 // it with the given arguments. If the value is a non-closure, attempt | |
| 1008 // to invoke "call" on it. | |
| 1009 // | |
| 1010 // 3. There is no such method. | |
| 1011 DEFINE_RUNTIME_ENTRY(InstanceFunctionLookup, 4) { | |
| 1012 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | |
| 1013 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | |
| 1014 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(2)); | |
| 1015 const Array& args = Array::CheckedHandle(arguments.ArgAt(3)); | |
| 1016 | |
| 1017 const Class& receiver_class = Class::Handle(receiver.clazz()); | |
| 1018 const String& target_name = String::Handle(ic_data.target_name()); | |
| 1019 | |
| 1020 Object& result = Object::Handle(); | |
| 1021 if (!ResolveCallThroughGetter(receiver, | |
| 1022 receiver_class, | |
| 1023 target_name, | |
| 1024 args_descriptor, | |
| 1025 args, | |
| 1026 ic_data, | |
| 1027 &result)) { | |
| 1028 ArgumentsDescriptor desc(args_descriptor); | |
| 1029 const Function& target_function = | |
| 1030 Function::Handle(receiver_class.GetInvocationDispatcher( | |
| 1031 target_name, | |
| 1032 args_descriptor, | |
| 1033 RawFunction::kNoSuchMethodDispatcher)); | |
| 1034 // Update IC data. | |
| 1035 ASSERT(!target_function.IsNull()); | |
| 1036 intptr_t receiver_cid = receiver.GetClassId(); | |
| 1037 if (ic_data.num_args_tested() == 1) { | |
| 1038 // In optimized code we may enter into here via the | |
| 1039 // MegamorphicCacheMissHandler since noSuchMethod dispatchers are not | |
| 1040 // inserted into the megamorphic cache. Therefore, we need to guard | |
| 1041 // against entering the same check twice into the ICData. | |
| 1042 // Note that num_args_tested == 1 in optimized code. | |
| 1043 // TODO(fschneider): Handle extraordinary cases like noSuchMethod and | |
| 1044 // implicit closure invocation properly in the megamorphic cache. | |
| 1045 const Function& target = | |
| 1046 Function::Handle(ic_data.GetTargetForReceiverClassId(receiver_cid)); | |
| 1047 if (target.IsNull()) { | |
| 1048 ic_data.AddReceiverCheck(receiver_cid, target_function); | |
| 1049 } | |
| 1050 } else { | |
| 1051 // Operators calls have two or three arguments tested ([], []=, etc.) | |
| 1052 ASSERT(ic_data.num_args_tested() > 1); | |
| 1053 GrowableArray<intptr_t> class_ids(ic_data.num_args_tested()); | |
| 1054 class_ids.Add(receiver_cid); | |
| 1055 for (intptr_t i = 1; i < ic_data.num_args_tested(); ++i) { | |
| 1056 class_ids.Add(Object::Handle(args.At(i)).GetClassId()); | |
| 1057 } | |
| 1058 ic_data.AddCheck(class_ids, target_function); | |
| 1059 } | |
| 1060 if (FLAG_trace_ic) { | |
| 1061 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n", | |
| 1062 Class::Handle(receiver.clazz()).ToCString(), | |
| 1063 receiver_cid, | |
| 1064 target_function.ToCString()); | |
| 1065 } | |
| 1066 result = DartEntry::InvokeFunction(target_function, args, args_descriptor); | |
| 1067 } | |
| 1068 CheckResultError(result); | |
| 1069 arguments.SetReturn(result); | |
| 1070 } | |
| 1071 | |
| 1072 | |
| 1073 static bool CanOptimizeFunction(const Function& function, Isolate* isolate) { | 1001 static bool CanOptimizeFunction(const Function& function, Isolate* isolate) { |
| 1074 const intptr_t kLowInvocationCount = -100000000; | 1002 const intptr_t kLowInvocationCount = -100000000; |
| 1075 if (isolate->debugger()->IsStepping() || | 1003 if (isolate->debugger()->IsStepping() || |
| 1076 isolate->debugger()->HasBreakpoint(function)) { | 1004 isolate->debugger()->HasBreakpoint(function)) { |
| 1077 // We cannot set breakpoints and single step in optimized code, | 1005 // We cannot set breakpoints and single step in optimized code, |
| 1078 // so do not optimize the function. | 1006 // so do not optimize the function. |
| 1079 function.set_usage_counter(0); | 1007 function.set_usage_counter(0); |
| 1080 return false; | 1008 return false; |
| 1081 } | 1009 } |
| 1082 if (function.deoptimization_counter() >= | 1010 if (function.deoptimization_counter() >= |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1548 // of the given value. | 1476 // of the given value. |
| 1549 // Arg0: Field object; | 1477 // Arg0: Field object; |
| 1550 // Arg1: Value that is being stored. | 1478 // Arg1: Value that is being stored. |
| 1551 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1479 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
| 1552 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1480 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 1553 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1481 const Object& value = Object::Handle(arguments.ArgAt(1)); |
| 1554 field.UpdateGuardedCidAndLength(value); | 1482 field.UpdateGuardedCidAndLength(value); |
| 1555 } | 1483 } |
| 1556 | 1484 |
| 1557 } // namespace dart | 1485 } // namespace dart |
| OLD | NEW |