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

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

Issue 1371453002: Precompile invoke-field-dispatchers for closures. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months 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
« no previous file with comments | « no previous file | runtime/vm/object.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) 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/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 730
731 // An instance call of the form o.f(...) could not be resolved. Check if 731 // An instance call of the form o.f(...) could not be resolved. Check if
732 // there is a getter with the same name. If so, invoke it. If the value is 732 // there is a getter with the same name. If so, invoke it. If the value is
733 // a closure, invoke it with the given arguments. If the value is a 733 // a closure, invoke it with the given arguments. If the value is a
734 // non-closure, attempt to invoke "call" on it. 734 // non-closure, attempt to invoke "call" on it.
735 static bool ResolveCallThroughGetter(const Instance& receiver, 735 static bool ResolveCallThroughGetter(const Instance& receiver,
736 const Class& receiver_class, 736 const Class& receiver_class,
737 const String& target_name, 737 const String& target_name,
738 const Array& arguments_descriptor, 738 const Array& arguments_descriptor,
739 Function* result) { 739 Function* result) {
740 ASSERT(FLAG_lazy_dispatchers);
741 // 1. Check if there is a getter with the same name. 740 // 1. Check if there is a getter with the same name.
742 const String& getter_name = String::Handle(Field::GetterName(target_name)); 741 const String& getter_name = String::Handle(Field::GetterName(target_name));
743 const int kNumArguments = 1; 742 const int kNumArguments = 1;
744 ArgumentsDescriptor args_desc( 743 ArgumentsDescriptor args_desc(
745 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); 744 Array::Handle(ArgumentsDescriptor::New(kNumArguments)));
746 const Function& getter = Function::Handle( 745 const Function& getter = Function::Handle(
747 Resolver::ResolveDynamicForReceiverClass(receiver_class, 746 Resolver::ResolveDynamicForReceiverClass(receiver_class,
748 getter_name, 747 getter_name,
749 args_desc)); 748 args_desc));
750 if (getter.IsNull() || getter.IsMethodExtractor()) { 749 if (getter.IsNull() || getter.IsMethodExtractor()) {
751 return false; 750 return false;
752 } 751 }
753 const Class& cache_class = Class::Handle(receiver_class.IsSignatureClass() 752 const Class& cache_class = Class::Handle(receiver_class.IsSignatureClass()
754 ? receiver_class.SuperClass() 753 ? receiver_class.SuperClass()
755 : receiver_class.raw()); 754 : receiver_class.raw());
756 ASSERT( 755 ASSERT(
757 !receiver_class.IsSignatureClass() || 756 !receiver_class.IsSignatureClass() ||
758 (receiver_class.SuperClass() == Type::Handle( 757 (receiver_class.SuperClass() == Type::Handle(
759 Isolate::Current()->object_store()->function_impl_type()).type_class())); 758 Isolate::Current()->object_store()->function_impl_type()).type_class()));
760 const Function& target_function = 759 const Function& target_function =
761 Function::Handle(cache_class.GetInvocationDispatcher( 760 Function::Handle(cache_class.GetInvocationDispatcher(
762 target_name, 761 target_name,
763 arguments_descriptor, 762 arguments_descriptor,
764 RawFunction::kInvokeFieldDispatcher)); 763 RawFunction::kInvokeFieldDispatcher,
765 ASSERT(!target_function.IsNull()); 764 FLAG_lazy_dispatchers));
765 ASSERT(!target_function.IsNull() || !FLAG_lazy_dispatchers);
766 if (FLAG_trace_ic) { 766 if (FLAG_trace_ic) {
767 OS::PrintErr("InvokeField IC miss: adding <%s> id:%" Pd " -> <%s>\n", 767 OS::PrintErr("InvokeField IC miss: adding <%s> id:%" Pd " -> <%s>\n",
768 Class::Handle(receiver.clazz()).ToCString(), 768 Class::Handle(receiver.clazz()).ToCString(),
769 receiver.GetClassId(), 769 receiver.GetClassId(),
770 target_function.ToCString()); 770 target_function.ToCString());
771 } 771 }
772 *result = target_function.raw(); 772 *result = target_function.raw();
773 return true; 773 return true;
774 } 774 }
775 775
776 776
777 // Handle other invocations (implicit closures, noSuchMethod). 777 // Handle other invocations (implicit closures, noSuchMethod).
778 RawFunction* InlineCacheMissHelper( 778 RawFunction* InlineCacheMissHelper(
779 const Instance& receiver, 779 const Instance& receiver,
780 const ICData& ic_data) { 780 const ICData& ic_data) {
781 if (!FLAG_lazy_dispatchers) {
782 return Function::null(); // We'll handle it in the runtime.
783 }
784
785 const Array& args_descriptor = Array::Handle(ic_data.arguments_descriptor()); 781 const Array& args_descriptor = Array::Handle(ic_data.arguments_descriptor());
786 782
787 const Class& receiver_class = Class::Handle(receiver.clazz()); 783 const Class& receiver_class = Class::Handle(receiver.clazz());
788 const String& target_name = String::Handle(ic_data.target_name()); 784 const String& target_name = String::Handle(ic_data.target_name());
789 785
790 Function& result = Function::Handle(); 786 Function& result = Function::Handle();
791 if (!ResolveCallThroughGetter(receiver, 787 if (!ResolveCallThroughGetter(receiver,
792 receiver_class, 788 receiver_class,
793 target_name, 789 target_name,
794 args_descriptor, 790 args_descriptor,
795 &result)) { 791 &result)) {
796 ArgumentsDescriptor desc(args_descriptor); 792 ArgumentsDescriptor desc(args_descriptor);
797 const Function& target_function = 793 const Function& target_function =
798 Function::Handle(receiver_class.GetInvocationDispatcher( 794 Function::Handle(receiver_class.GetInvocationDispatcher(
799 target_name, 795 target_name,
800 args_descriptor, 796 args_descriptor,
801 RawFunction::kNoSuchMethodDispatcher)); 797 RawFunction::kNoSuchMethodDispatcher,
798 FLAG_lazy_dispatchers));
802 if (FLAG_trace_ic) { 799 if (FLAG_trace_ic) {
803 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n", 800 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n",
804 Class::Handle(receiver.clazz()).ToCString(), 801 Class::Handle(receiver.clazz()).ToCString(),
805 receiver.GetClassId(), 802 receiver.GetClassId(),
806 target_function.ToCString()); 803 target_function.ToCString());
807 } 804 }
808 result = target_function.raw(); 805 result = target_function.raw();
809 } 806 }
807 // May be null if --no-lazy-dispatchers, in which case dispatch will be
808 // handled by InvokeNoSuchMethodDispatcher.
809 ASSERT(!result.IsNull() || !FLAG_lazy_dispatchers);
810 return result.raw(); 810 return result.raw();
811 } 811 }
812 812
813 static RawFunction* InlineCacheMissHandler( 813 static RawFunction* InlineCacheMissHandler(
814 const GrowableArray<const Instance*>& args, 814 const GrowableArray<const Instance*>& args,
815 const ICData& ic_data) { 815 const ICData& ic_data) {
816 const Instance& receiver = *args[0]; 816 const Instance& receiver = *args[0];
817 ArgumentsDescriptor 817 ArgumentsDescriptor
818 arguments_descriptor(Array::Handle(ic_data.arguments_descriptor())); 818 arguments_descriptor(Array::Handle(ic_data.arguments_descriptor()));
819 String& function_name = String::Handle(ic_data.target_name()); 819 String& function_name = String::Handle(ic_data.target_name());
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 const intptr_t elm_size = old_data.ElementSizeInBytes(); 1825 const intptr_t elm_size = old_data.ElementSizeInBytes();
1826 const TypedData& new_data = 1826 const TypedData& new_data =
1827 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 1827 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
1828 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 1828 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
1829 typed_data_cell.SetAt(0, new_data); 1829 typed_data_cell.SetAt(0, new_data);
1830 arguments.SetReturn(new_data); 1830 arguments.SetReturn(new_data);
1831 } 1831 }
1832 1832
1833 1833
1834 } // namespace dart 1834 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698