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 1684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1714 // we don't have one target. | 1715 // we don't have one target. |
1715 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0)); | 1716 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0)); |
1716 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); | 1717 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); |
1717 has_one_target = !polymorphic_target; | 1718 has_one_target = !polymorphic_target; |
1718 } | 1719 } |
1719 | 1720 |
1720 if (has_one_target) { | 1721 if (has_one_target) { |
1721 RawFunction::Kind function_kind = | 1722 RawFunction::Kind function_kind = |
1722 Function::Handle(Z, unary_checks.GetTargetAt(0)).kind(); | 1723 Function::Handle(Z, unary_checks.GetTargetAt(0)).kind(); |
1723 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) { | 1724 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) { |
| 1725 PolymorphicTargets* targets = |
| 1726 JitOptimizer::CreatePolymorphicTargets(Z, unary_checks); |
1724 PolymorphicInstanceCallInstr* call = | 1727 PolymorphicInstanceCallInstr* call = |
1725 new (Z) PolymorphicInstanceCallInstr(instr, unary_checks, | 1728 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
1726 /* with_checks = */ false, | 1729 /* with_checks = */ false, |
1727 /* complete = */ true); | 1730 /* complete = */ true); |
1728 instr->ReplaceWith(call, current_iterator()); | 1731 instr->ReplaceWith(call, current_iterator()); |
1729 return; | 1732 return; |
1730 } | 1733 } |
1731 } | 1734 } |
1732 switch (instr->token_kind()) { | 1735 switch (instr->token_kind()) { |
1733 case Token::kEQ: | 1736 case Token::kEQ: |
1734 case Token::kLT: | 1737 case Token::kLT: |
1735 case Token::kLTE: | 1738 case Token::kLTE: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1776 const intptr_t receiver_cid = | 1779 const intptr_t receiver_cid = |
1777 instr->PushArgumentAt(0)->value()->Type()->ToCid(); | 1780 instr->PushArgumentAt(0)->value()->Type()->ToCid(); |
1778 if (receiver_cid != kDynamicCid) { | 1781 if (receiver_cid != kDynamicCid) { |
1779 const Class& receiver_class = | 1782 const Class& receiver_class = |
1780 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); | 1783 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); |
1781 | 1784 |
1782 const Array& args_desc_array = | 1785 const Array& args_desc_array = |
1783 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(), | 1786 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(), |
1784 instr->argument_names())); | 1787 instr->argument_names())); |
1785 ArgumentsDescriptor args_desc(args_desc_array); | 1788 ArgumentsDescriptor args_desc(args_desc_array); |
1786 const Function& function = Function::Handle( | 1789 Function& function = Function::Handle( |
1787 Z, Resolver::ResolveDynamicForReceiverClass( | 1790 Z, Resolver::ResolveDynamicForReceiverClass( |
1788 receiver_class, instr->function_name(), args_desc)); | 1791 receiver_class, instr->function_name(), args_desc)); |
1789 if (!function.IsNull()) { | 1792 if (!function.IsNull()) { |
1790 const ICData& ic_data = ICData::Handle( | 1793 PolymorphicTargets* targets = new (Z) PolymorphicTargets(Z); |
1791 ICData::New(flow_graph_->function(), instr->function_name(), | 1794 Function& target = Function::ZoneHandle(Z, function.raw()); |
1792 args_desc_array, Thread::kNoDeoptId, | 1795 targets->Add( |
1793 /* args_tested = */ 1, false)); | 1796 CidRangeTarget(receiver_class.id(), receiver_class.id(), &target, 1)); |
1794 ic_data.AddReceiverCheck(receiver_class.id(), function); | |
1795 PolymorphicInstanceCallInstr* call = | 1797 PolymorphicInstanceCallInstr* call = |
1796 new (Z) PolymorphicInstanceCallInstr(instr, ic_data, | 1798 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
1797 /* with_checks = */ false, | 1799 /* with_checks = */ false, |
1798 /* complete = */ true); | 1800 /* complete = */ true); |
1799 instr->ReplaceWith(call, current_iterator()); | 1801 instr->ReplaceWith(call, current_iterator()); |
1800 return; | 1802 return; |
1801 } | 1803 } |
1802 } | 1804 } |
1803 | 1805 |
1804 Definition* callee_receiver = instr->ArgumentAt(0); | 1806 Definition* callee_receiver = instr->ArgumentAt(0); |
1805 const Function& function = flow_graph_->function(); | 1807 const Function& function = flow_graph_->function(); |
1806 Class& receiver_class = Class::Handle(Z); | 1808 Class& receiver_class = Class::Handle(Z); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1909 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) { | 1911 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) { |
1910 args->Add(instr->PushArgumentAt(i)); | 1912 args->Add(instr->PushArgumentAt(i)); |
1911 } | 1913 } |
1912 StaticCallInstr* call = new (Z) StaticCallInstr( | 1914 StaticCallInstr* call = new (Z) StaticCallInstr( |
1913 instr->token_pos(), Function::ZoneHandle(Z, single_target.raw()), | 1915 instr->token_pos(), Function::ZoneHandle(Z, single_target.raw()), |
1914 instr->argument_names(), args, instr->deopt_id()); | 1916 instr->argument_names(), args, instr->deopt_id()); |
1915 instr->ReplaceWith(call, current_iterator()); | 1917 instr->ReplaceWith(call, current_iterator()); |
1916 return; | 1918 return; |
1917 } else if ((ic_data.raw() != ICData::null()) && | 1919 } else if ((ic_data.raw() != ICData::null()) && |
1918 !ic_data.NumberOfChecksIs(0)) { | 1920 !ic_data.NumberOfChecksIs(0)) { |
| 1921 PolymorphicTargets* targets = |
| 1922 JitOptimizer::CreatePolymorphicTargets(Z, ic_data); |
1919 PolymorphicInstanceCallInstr* call = | 1923 PolymorphicInstanceCallInstr* call = |
1920 new (Z) PolymorphicInstanceCallInstr(instr, ic_data, | 1924 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
1921 /* with_checks = */ true, | 1925 /* with_checks = */ true, |
1922 /* complete = */ true); | 1926 /* complete = */ true); |
1923 instr->ReplaceWith(call, current_iterator()); | 1927 instr->ReplaceWith(call, current_iterator()); |
1924 return; | 1928 return; |
1925 } | 1929 } |
1926 } | 1930 } |
1927 } | 1931 } |
1928 | 1932 |
1929 // More than one target. Generate generic polymorphic call without | 1933 // More than one target. Generate generic polymorphic call without |
1930 // deoptimization. | 1934 // deoptimization. |
1931 if (instr->ic_data()->NumberOfUsedChecks() > 0) { | 1935 if (instr->ic_data()->NumberOfUsedChecks() > 0) { |
1932 ASSERT(!FLAG_polymorphic_with_deopt); | 1936 ASSERT(!FLAG_polymorphic_with_deopt); |
1933 // OK to use checks with PolymorphicInstanceCallInstr since no | 1937 // OK to use checks with PolymorphicInstanceCallInstr since no |
1934 // deoptimization is allowed. | 1938 // deoptimization is allowed. |
| 1939 PolymorphicTargets* targets = |
| 1940 JitOptimizer::CreatePolymorphicTargets(Z, *instr->ic_data()); |
1935 PolymorphicInstanceCallInstr* call = | 1941 PolymorphicInstanceCallInstr* call = |
1936 new (Z) PolymorphicInstanceCallInstr(instr, unary_checks, | 1942 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
1937 /* with_checks = */ true, | 1943 /* with_checks = */ true, |
1938 /* complete = */ false); | 1944 /* complete = */ false); |
1939 instr->ReplaceWith(call, current_iterator()); | 1945 instr->ReplaceWith(call, current_iterator()); |
1940 return; | 1946 return; |
1941 } | 1947 } |
1942 } | 1948 } |
1943 | 1949 |
1944 | 1950 |
1945 void AotOptimizer::VisitPolymorphicInstanceCall( | 1951 void AotOptimizer::VisitPolymorphicInstanceCall( |
1946 PolymorphicInstanceCallInstr* call) { | 1952 PolymorphicInstanceCallInstr* call) { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2132 FlowGraph::kEffect); | 2138 FlowGraph::kEffect); |
2133 current_iterator()->RemoveCurrentFromGraph(); | 2139 current_iterator()->RemoveCurrentFromGraph(); |
2134 } | 2140 } |
2135 } | 2141 } |
2136 } | 2142 } |
2137 } | 2143 } |
2138 | 2144 |
2139 #endif // DART_PRECOMPILER | 2145 #endif // DART_PRECOMPILER |
2140 | 2146 |
2141 } // namespace dart | 2147 } // namespace dart |
OLD | NEW |