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/aot_optimizer.h" | 5 #include "vm/aot_optimizer.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
11 #include "vm/cpu.h" | 11 #include "vm/cpu.h" |
12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
13 #include "vm/exceptions.h" | 13 #include "vm/exceptions.h" |
14 #include "vm/flow_graph_builder.h" | 14 #include "vm/flow_graph_builder.h" |
15 #include "vm/flow_graph_compiler.h" | 15 #include "vm/flow_graph_compiler.h" |
16 #include "vm/flow_graph_inliner.h" | 16 #include "vm/flow_graph_inliner.h" |
17 #include "vm/flow_graph_range_analysis.h" | 17 #include "vm/flow_graph_range_analysis.h" |
18 #include "vm/hash_map.h" | 18 #include "vm/hash_map.h" |
19 #include "vm/il_printer.h" | 19 #include "vm/il_printer.h" |
| 20 #include "vm/jit_optimizer.h" |
20 #include "vm/intermediate_language.h" | 21 #include "vm/intermediate_language.h" |
21 #include "vm/object.h" | 22 #include "vm/object.h" |
22 #include "vm/object_store.h" | 23 #include "vm/object_store.h" |
23 #include "vm/parser.h" | 24 #include "vm/parser.h" |
24 #include "vm/precompiler.h" | 25 #include "vm/precompiler.h" |
25 #include "vm/resolver.h" | 26 #include "vm/resolver.h" |
26 #include "vm/scopes.h" | 27 #include "vm/scopes.h" |
27 #include "vm/stack_frame.h" | 28 #include "vm/stack_frame.h" |
28 #include "vm/symbols.h" | 29 #include "vm/symbols.h" |
29 | 30 |
(...skipping 1804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1834 // we don't have one target. | 1835 // we don't have one target. |
1835 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0)); | 1836 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0)); |
1836 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); | 1837 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); |
1837 has_one_target = !polymorphic_target; | 1838 has_one_target = !polymorphic_target; |
1838 } | 1839 } |
1839 | 1840 |
1840 if (has_one_target) { | 1841 if (has_one_target) { |
1841 RawFunction::Kind function_kind = | 1842 RawFunction::Kind function_kind = |
1842 Function::Handle(Z, unary_checks.GetTargetAt(0)).kind(); | 1843 Function::Handle(Z, unary_checks.GetTargetAt(0)).kind(); |
1843 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) { | 1844 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) { |
| 1845 CallTargets* targets = CallTargets::Create(Z, unary_checks); |
1844 PolymorphicInstanceCallInstr* call = | 1846 PolymorphicInstanceCallInstr* call = |
1845 new (Z) PolymorphicInstanceCallInstr(instr, unary_checks, | 1847 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
1846 /* with_checks = */ false, | 1848 /* with_checks = */ false, |
1847 /* complete = */ true); | 1849 /* complete = */ true); |
1848 instr->ReplaceWith(call, current_iterator()); | 1850 instr->ReplaceWith(call, current_iterator()); |
1849 return; | 1851 return; |
1850 } | 1852 } |
1851 } | 1853 } |
1852 switch (instr->token_kind()) { | 1854 switch (instr->token_kind()) { |
1853 case Token::kEQ: | 1855 case Token::kEQ: |
1854 case Token::kLT: | 1856 case Token::kLT: |
1855 case Token::kLTE: | 1857 case Token::kLTE: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1896 const intptr_t receiver_cid = | 1898 const intptr_t receiver_cid = |
1897 instr->PushArgumentAt(0)->value()->Type()->ToCid(); | 1899 instr->PushArgumentAt(0)->value()->Type()->ToCid(); |
1898 if (receiver_cid != kDynamicCid) { | 1900 if (receiver_cid != kDynamicCid) { |
1899 const Class& receiver_class = | 1901 const Class& receiver_class = |
1900 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); | 1902 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); |
1901 | 1903 |
1902 const Array& args_desc_array = | 1904 const Array& args_desc_array = |
1903 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(), | 1905 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(), |
1904 instr->argument_names())); | 1906 instr->argument_names())); |
1905 ArgumentsDescriptor args_desc(args_desc_array); | 1907 ArgumentsDescriptor args_desc(args_desc_array); |
1906 const Function& function = Function::Handle( | 1908 Function& function = Function::Handle( |
1907 Z, Resolver::ResolveDynamicForReceiverClass( | 1909 Z, Resolver::ResolveDynamicForReceiverClass( |
1908 receiver_class, instr->function_name(), args_desc)); | 1910 receiver_class, instr->function_name(), args_desc)); |
1909 if (!function.IsNull()) { | 1911 if (!function.IsNull()) { |
1910 const ICData& ic_data = ICData::Handle( | 1912 CallTargets* targets = new (Z) CallTargets(); |
1911 ICData::New(flow_graph_->function(), instr->function_name(), | 1913 Function& target = Function::ZoneHandle(Z, function.raw()); |
1912 args_desc_array, Thread::kNoDeoptId, | 1914 targets->Add(CidRangeTarget(receiver_class.id(), receiver_class.id(), |
1913 /* args_tested = */ 1, false)); | 1915 &target, /*count = */ 1)); |
1914 ic_data.AddReceiverCheck(receiver_class.id(), function); | |
1915 PolymorphicInstanceCallInstr* call = | 1916 PolymorphicInstanceCallInstr* call = |
1916 new (Z) PolymorphicInstanceCallInstr(instr, ic_data, | 1917 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
1917 /* with_checks = */ false, | 1918 /* with_checks = */ false, |
1918 /* complete = */ true); | 1919 /* complete = */ true); |
1919 instr->ReplaceWith(call, current_iterator()); | 1920 instr->ReplaceWith(call, current_iterator()); |
1920 return; | 1921 return; |
1921 } | 1922 } |
1922 } | 1923 } |
1923 | 1924 |
1924 Definition* callee_receiver = instr->ArgumentAt(0); | 1925 Definition* callee_receiver = instr->ArgumentAt(0); |
1925 const Function& function = flow_graph_->function(); | 1926 const Function& function = flow_graph_->function(); |
1926 Class& receiver_class = Class::Handle(Z); | 1927 Class& receiver_class = Class::Handle(Z); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2029 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) { | 2030 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) { |
2030 args->Add(instr->PushArgumentAt(i)); | 2031 args->Add(instr->PushArgumentAt(i)); |
2031 } | 2032 } |
2032 StaticCallInstr* call = new (Z) StaticCallInstr( | 2033 StaticCallInstr* call = new (Z) StaticCallInstr( |
2033 instr->token_pos(), Function::ZoneHandle(Z, single_target.raw()), | 2034 instr->token_pos(), Function::ZoneHandle(Z, single_target.raw()), |
2034 instr->argument_names(), args, instr->deopt_id()); | 2035 instr->argument_names(), args, instr->deopt_id()); |
2035 instr->ReplaceWith(call, current_iterator()); | 2036 instr->ReplaceWith(call, current_iterator()); |
2036 return; | 2037 return; |
2037 } else if ((ic_data.raw() != ICData::null()) && | 2038 } else if ((ic_data.raw() != ICData::null()) && |
2038 !ic_data.NumberOfChecksIs(0)) { | 2039 !ic_data.NumberOfChecksIs(0)) { |
| 2040 CallTargets* targets = CallTargets::Create(Z, ic_data); |
2039 PolymorphicInstanceCallInstr* call = | 2041 PolymorphicInstanceCallInstr* call = |
2040 new (Z) PolymorphicInstanceCallInstr(instr, ic_data, | 2042 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
2041 /* with_checks = */ true, | 2043 /* with_checks = */ true, |
2042 /* complete = */ true); | 2044 /* complete = */ true); |
2043 instr->ReplaceWith(call, current_iterator()); | 2045 instr->ReplaceWith(call, current_iterator()); |
2044 return; | 2046 return; |
2045 } | 2047 } |
2046 } | 2048 } |
2047 } | 2049 } |
2048 | 2050 |
2049 // More than one target. Generate generic polymorphic call without | 2051 // More than one target. Generate generic polymorphic call without |
2050 // deoptimization. | 2052 // deoptimization. |
2051 if (instr->ic_data()->NumberOfUsedChecks() > 0) { | 2053 if (instr->ic_data()->NumberOfUsedChecks() > 0) { |
2052 ASSERT(!FLAG_polymorphic_with_deopt); | 2054 ASSERT(!FLAG_polymorphic_with_deopt); |
2053 // OK to use checks with PolymorphicInstanceCallInstr since no | 2055 // OK to use checks with PolymorphicInstanceCallInstr since no |
2054 // deoptimization is allowed. | 2056 // deoptimization is allowed. |
| 2057 CallTargets* targets = CallTargets::Create(Z, *instr->ic_data()); |
2055 PolymorphicInstanceCallInstr* call = | 2058 PolymorphicInstanceCallInstr* call = |
2056 new (Z) PolymorphicInstanceCallInstr(instr, unary_checks, | 2059 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
2057 /* with_checks = */ true, | 2060 /* with_checks = */ true, |
2058 /* complete = */ false); | 2061 /* complete = */ false); |
2059 instr->ReplaceWith(call, current_iterator()); | 2062 instr->ReplaceWith(call, current_iterator()); |
2060 return; | 2063 return; |
2061 } | 2064 } |
2062 } | 2065 } |
2063 | 2066 |
2064 | 2067 |
2065 void AotOptimizer::VisitPolymorphicInstanceCall( | 2068 void AotOptimizer::VisitPolymorphicInstanceCall( |
2066 PolymorphicInstanceCallInstr* call) { | 2069 PolymorphicInstanceCallInstr* call) { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 FlowGraph::kEffect); | 2255 FlowGraph::kEffect); |
2253 current_iterator()->RemoveCurrentFromGraph(); | 2256 current_iterator()->RemoveCurrentFromGraph(); |
2254 } | 2257 } |
2255 } | 2258 } |
2256 } | 2259 } |
2257 } | 2260 } |
2258 | 2261 |
2259 #endif // DART_PRECOMPILER | 2262 #endif // DART_PRECOMPILER |
2260 | 2263 |
2261 } // namespace dart | 2264 } // namespace dart |
OLD | NEW |