| 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 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 | 699 |
| 700 | 700 |
| 701 // An instance call of the form o.f(...) could not be resolved. Check if | 701 // An instance call of the form o.f(...) could not be resolved. Check if |
| 702 // there is a getter with the same name. If so, invoke it. If the value is | 702 // there is a getter with the same name. If so, invoke it. If the value is |
| 703 // a closure, invoke it with the given arguments. If the value is a | 703 // a closure, invoke it with the given arguments. If the value is a |
| 704 // non-closure, attempt to invoke "call" on it. | 704 // non-closure, attempt to invoke "call" on it. |
| 705 static bool ResolveCallThroughGetter(const Instance& receiver, | 705 static bool ResolveCallThroughGetter(const Instance& receiver, |
| 706 const Class& receiver_class, | 706 const Class& receiver_class, |
| 707 const String& target_name, | 707 const String& target_name, |
| 708 const Array& arguments_descriptor, | 708 const Array& arguments_descriptor, |
| 709 const ICData& ic_data, | |
| 710 Function* result) { | 709 Function* result) { |
| 711 // 1. Check if there is a getter with the same name. | 710 // 1. Check if there is a getter with the same name. |
| 712 const String& getter_name = String::Handle(Field::GetterName(target_name)); | 711 const String& getter_name = String::Handle(Field::GetterName(target_name)); |
| 713 const int kNumArguments = 1; | 712 const int kNumArguments = 1; |
| 714 ArgumentsDescriptor args_desc( | 713 ArgumentsDescriptor args_desc( |
| 715 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 714 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
| 716 const Function& getter = Function::Handle( | 715 const Function& getter = Function::Handle( |
| 717 Resolver::ResolveDynamicForReceiverClass(receiver_class, | 716 Resolver::ResolveDynamicForReceiverClass(receiver_class, |
| 718 getter_name, | 717 getter_name, |
| 719 args_desc)); | 718 args_desc)); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 745 const Array& args_descriptor = Array::Handle(ic_data.arguments_descriptor()); | 744 const Array& args_descriptor = Array::Handle(ic_data.arguments_descriptor()); |
| 746 | 745 |
| 747 const Class& receiver_class = Class::Handle(receiver.clazz()); | 746 const Class& receiver_class = Class::Handle(receiver.clazz()); |
| 748 const String& target_name = String::Handle(ic_data.target_name()); | 747 const String& target_name = String::Handle(ic_data.target_name()); |
| 749 | 748 |
| 750 Function& result = Function::Handle(); | 749 Function& result = Function::Handle(); |
| 751 if (!ResolveCallThroughGetter(receiver, | 750 if (!ResolveCallThroughGetter(receiver, |
| 752 receiver_class, | 751 receiver_class, |
| 753 target_name, | 752 target_name, |
| 754 args_descriptor, | 753 args_descriptor, |
| 755 ic_data, | |
| 756 &result)) { | 754 &result)) { |
| 757 ArgumentsDescriptor desc(args_descriptor); | 755 ArgumentsDescriptor desc(args_descriptor); |
| 758 const Function& target_function = | 756 const Function& target_function = |
| 759 Function::Handle(receiver_class.GetInvocationDispatcher( | 757 Function::Handle(receiver_class.GetInvocationDispatcher( |
| 760 target_name, | 758 target_name, |
| 761 args_descriptor, | 759 args_descriptor, |
| 762 RawFunction::kNoSuchMethodDispatcher)); | 760 RawFunction::kNoSuchMethodDispatcher)); |
| 763 if (FLAG_trace_ic) { | 761 if (FLAG_trace_ic) { |
| 764 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n", | 762 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n", |
| 765 Class::Handle(receiver.clazz()).ToCString(), | 763 Class::Handle(receiver.clazz()).ToCString(), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 780 String& function_name = String::Handle(ic_data.target_name()); | 778 String& function_name = String::Handle(ic_data.target_name()); |
| 781 ASSERT(function_name.IsSymbol()); | 779 ASSERT(function_name.IsSymbol()); |
| 782 Function& target_function = Function::Handle( | 780 Function& target_function = Function::Handle( |
| 783 Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor)); | 781 Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor)); |
| 784 if (target_function.IsNull()) { | 782 if (target_function.IsNull()) { |
| 785 if (FLAG_trace_ic) { | 783 if (FLAG_trace_ic) { |
| 786 OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n", | 784 OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n", |
| 787 String::Handle(ic_data.target_name()).ToCString(), | 785 String::Handle(ic_data.target_name()).ToCString(), |
| 788 receiver.ToCString()); | 786 receiver.ToCString()); |
| 789 } | 787 } |
| 790 ic_data.SetIsClosureCall(); | |
| 791 target_function = InlineCacheMissHelper(receiver, ic_data); | 788 target_function = InlineCacheMissHelper(receiver, ic_data); |
| 792 } | 789 } |
| 793 ASSERT(!target_function.IsNull()); | 790 ASSERT(!target_function.IsNull()); |
| 794 if (args.length() == 1) { | 791 if (args.length() == 1) { |
| 795 ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function); | 792 ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function); |
| 796 } else { | 793 } else { |
| 797 GrowableArray<intptr_t> class_ids(args.length()); | 794 GrowableArray<intptr_t> class_ids(args.length()); |
| 798 ASSERT(ic_data.NumArgsTested() == args.length()); | 795 ASSERT(ic_data.NumArgsTested() == args.length()); |
| 799 for (intptr_t i = 0; i < args.length(); i++) { | 796 for (intptr_t i = 0; i < args.length(); i++) { |
| 800 class_ids.Add(args[i]->GetClassId()); | 797 class_ids.Add(args[i]->GetClassId()); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", | 979 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", |
| 983 cls.ToCString(), name.ToCString()); | 980 cls.ToCString(), name.ToCString()); |
| 984 } | 981 } |
| 985 | 982 |
| 986 ArgumentsDescriptor args_desc(descriptor); | 983 ArgumentsDescriptor args_desc(descriptor); |
| 987 Function& target_function = Function::Handle( | 984 Function& target_function = Function::Handle( |
| 988 Resolver::ResolveDynamicForReceiverClass(cls, | 985 Resolver::ResolveDynamicForReceiverClass(cls, |
| 989 name, | 986 name, |
| 990 args_desc)); | 987 args_desc)); |
| 991 if (target_function.IsNull()) { | 988 if (target_function.IsNull()) { |
| 992 ic_data.SetIsClosureCall(); | |
| 993 target_function = InlineCacheMissHelper(receiver, ic_data); | 989 target_function = InlineCacheMissHelper(receiver, ic_data); |
| 994 } | 990 } |
| 995 | 991 |
| 996 ASSERT(!target_function.IsNull()); | 992 ASSERT(!target_function.IsNull()); |
| 997 // Insert function found into cache and return it. | 993 // Insert function found into cache and return it. |
| 998 cache.EnsureCapacity(); | 994 cache.EnsureCapacity(); |
| 999 const Smi& class_id = Smi::Handle(Smi::New(cls.id())); | 995 const Smi& class_id = Smi::Handle(Smi::New(cls.id())); |
| 1000 cache.Insert(class_id, target_function); | 996 cache.Insert(class_id, target_function); |
| 1001 arguments.SetReturn(target_function); | 997 arguments.SetReturn(target_function); |
| 1002 } | 998 } |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 } | 1247 } |
| 1252 | 1248 |
| 1253 | 1249 |
| 1254 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { | 1250 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { |
| 1255 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); | 1251 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); |
| 1256 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); | 1252 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); |
| 1257 DartFrameIterator iterator; | 1253 DartFrameIterator iterator; |
| 1258 StackFrame* frame = iterator.NextFrame(); | 1254 StackFrame* frame = iterator.NextFrame(); |
| 1259 ASSERT(frame != NULL); | 1255 ASSERT(frame != NULL); |
| 1260 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd | 1256 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd |
| 1261 " %s %s\n", | 1257 " %s\n", |
| 1262 frame->pc(), | 1258 frame->pc(), |
| 1263 ic_data.raw(), | 1259 ic_data.raw(), |
| 1264 function.usage_counter(), | 1260 function.usage_counter(), |
| 1265 ic_data.NumberOfChecks(), | 1261 ic_data.NumberOfChecks(), |
| 1266 ic_data.IsClosureCall() ? "closure" : "", | |
| 1267 function.ToFullyQualifiedCString()); | 1262 function.ToFullyQualifiedCString()); |
| 1268 } | 1263 } |
| 1269 | 1264 |
| 1270 | 1265 |
| 1271 // This is called from function that needs to be optimized. | 1266 // This is called from function that needs to be optimized. |
| 1272 // The requesting function can be already optimized (reoptimization). | 1267 // The requesting function can be already optimized (reoptimization). |
| 1273 // Returns the Code object where to continue execution. | 1268 // Returns the Code object where to continue execution. |
| 1274 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 1269 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
| 1275 const Function& function = Function::CheckedHandle(isolate, | 1270 const Function& function = Function::CheckedHandle(isolate, |
| 1276 arguments.ArgAt(0)); | 1271 arguments.ArgAt(0)); |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1581 field.RecordStore(value); | 1576 field.RecordStore(value); |
| 1582 } | 1577 } |
| 1583 | 1578 |
| 1584 | 1579 |
| 1585 DEFINE_RUNTIME_ENTRY(InitStaticField, 1) { | 1580 DEFINE_RUNTIME_ENTRY(InitStaticField, 1) { |
| 1586 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1581 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 1587 field.EvaluateInitializer(); | 1582 field.EvaluateInitializer(); |
| 1588 } | 1583 } |
| 1589 | 1584 |
| 1590 } // namespace dart | 1585 } // namespace dart |
| OLD | NEW |