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/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 target_function.IsNull() ? "null" : target_function.ToCString()); | 775 target_function.IsNull() ? "null" : target_function.ToCString()); |
776 } | 776 } |
777 result = target_function.raw(); | 777 result = target_function.raw(); |
778 } | 778 } |
779 // May be null if --no-lazy-dispatchers, in which case dispatch will be | 779 // May be null if --no-lazy-dispatchers, in which case dispatch will be |
780 // handled by InvokeNoSuchMethodDispatcher. | 780 // handled by InvokeNoSuchMethodDispatcher. |
781 ASSERT(!result.IsNull() || !FLAG_lazy_dispatchers); | 781 ASSERT(!result.IsNull() || !FLAG_lazy_dispatchers); |
782 return result.raw(); | 782 return result.raw(); |
783 } | 783 } |
784 | 784 |
| 785 |
| 786 // Perform the subtype and return constant function based on the result. |
| 787 static RawFunction* ComputeTypeCheckTarget(const Instance& receiver, |
| 788 const AbstractType& type, |
| 789 const ArgumentsDescriptor& desc) { |
| 790 const TypeArguments& checked_type_arguments = TypeArguments::Handle(); |
| 791 Error& error = Error::Handle(); |
| 792 bool result = receiver.IsInstanceOf(type, checked_type_arguments, &error); |
| 793 ASSERT(error.IsNull()); |
| 794 ObjectStore* store = Isolate::Current()->object_store(); |
| 795 const Function& target |
| 796 = Function::Handle(result |
| 797 ? store->simple_instance_of_true_function() |
| 798 : store->simple_instance_of_false_function()); |
| 799 ASSERT(!target.IsNull()); |
| 800 return target.raw();; |
| 801 } |
| 802 |
| 803 |
785 static RawFunction* InlineCacheMissHandler( | 804 static RawFunction* InlineCacheMissHandler( |
786 const GrowableArray<const Instance*>& args, | 805 const GrowableArray<const Instance*>& args, |
787 const ICData& ic_data) { | 806 const ICData& ic_data) { |
788 const Instance& receiver = *args[0]; | 807 const Instance& receiver = *args[0]; |
789 ArgumentsDescriptor | 808 ArgumentsDescriptor |
790 arguments_descriptor(Array::Handle(ic_data.arguments_descriptor())); | 809 arguments_descriptor(Array::Handle(ic_data.arguments_descriptor())); |
791 String& function_name = String::Handle(ic_data.target_name()); | 810 String& function_name = String::Handle(ic_data.target_name()); |
792 ASSERT(function_name.IsSymbol()); | 811 ASSERT(function_name.IsSymbol()); |
| 812 |
793 Function& target_function = Function::Handle( | 813 Function& target_function = Function::Handle( |
794 Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor)); | 814 Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor)); |
| 815 |
| 816 ObjectStore* store = Isolate::Current()->object_store(); |
| 817 if (target_function.raw() == store->simple_instance_of_function()) { |
| 818 // Replace the target function with constant function. |
| 819 const AbstractType& type = AbstractType::Cast(*args[1]); |
| 820 target_function |
| 821 = ComputeTypeCheckTarget(receiver, type, arguments_descriptor); |
| 822 } |
795 if (target_function.IsNull()) { | 823 if (target_function.IsNull()) { |
796 if (FLAG_trace_ic) { | 824 if (FLAG_trace_ic) { |
797 OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n", | 825 OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n", |
798 String::Handle(ic_data.target_name()).ToCString(), | 826 String::Handle(ic_data.target_name()).ToCString(), |
799 receiver.ToCString()); | 827 receiver.ToCString()); |
800 } | 828 } |
801 const Array& args_descriptor = | 829 const Array& args_descriptor = |
802 Array::Handle(ic_data.arguments_descriptor()); | 830 Array::Handle(ic_data.arguments_descriptor()); |
803 const String& target_name = String::Handle(ic_data.target_name()); | 831 const String& target_name = String::Handle(ic_data.target_name()); |
804 target_function = InlineCacheMissHelper(receiver, | 832 target_function = InlineCacheMissHelper(receiver, |
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1902 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 1930 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
1903 const TypedData& new_data = | 1931 const TypedData& new_data = |
1904 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 1932 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
1905 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 1933 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
1906 typed_data_cell.SetAt(0, new_data); | 1934 typed_data_cell.SetAt(0, new_data); |
1907 arguments.SetReturn(new_data); | 1935 arguments.SetReturn(new_data); |
1908 } | 1936 } |
1909 | 1937 |
1910 | 1938 |
1911 } // namespace dart | 1939 } // namespace dart |
OLD | NEW |