Chromium Code Reviews| 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" |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 return false; | 106 return false; |
| 107 } | 107 } |
| 108 | 108 |
| 109 if (call->function_name().raw() != Symbols::GetRuntimeType().raw()) { | 109 if (call->function_name().raw() != Symbols::GetRuntimeType().raw()) { |
| 110 return false; | 110 return false; |
| 111 } | 111 } |
| 112 | 112 |
| 113 // There is only a single function Object.get:runtimeType that can be invoked | 113 // There is only a single function Object.get:runtimeType that can be invoked |
| 114 // by this call. Convert dynamic invocation to a static one. | 114 // by this call. Convert dynamic invocation to a static one. |
| 115 const Class& cls = Class::Handle(Z, I->object_store()->object_class()); | 115 const Class& cls = Class::Handle(Z, I->object_store()->object_class()); |
| 116 const intptr_t kTypeArgsLen = 0; | |
| 117 ASSERT(call->type_args_len() == kTypeArgsLen); | |
| 116 const Array& args_desc_array = Array::Handle( | 118 const Array& args_desc_array = Array::Handle( |
| 117 Z, | 119 Z, ArgumentsDescriptor::New(kTypeArgsLen, call->ArgumentCount(), |
| 118 ArgumentsDescriptor::New(call->ArgumentCount(), call->argument_names())); | 120 call->argument_names())); |
| 119 ArgumentsDescriptor args_desc(args_desc_array); | 121 ArgumentsDescriptor args_desc(args_desc_array); |
| 120 const Function& function = | 122 const Function& function = |
| 121 Function::Handle(Z, Resolver::ResolveDynamicForReceiverClass( | 123 Function::Handle(Z, Resolver::ResolveDynamicForReceiverClass( |
| 122 cls, call->function_name(), args_desc)); | 124 cls, call->function_name(), args_desc)); |
| 123 ASSERT(!function.IsNull()); | 125 ASSERT(!function.IsNull()); |
| 124 | 126 |
| 125 ZoneGrowableArray<PushArgumentInstr*>* args = | 127 ZoneGrowableArray<PushArgumentInstr*>* args = |
| 126 new (Z) ZoneGrowableArray<PushArgumentInstr*>(call->ArgumentCount()); | 128 new (Z) ZoneGrowableArray<PushArgumentInstr*>(call->ArgumentCount()); |
| 127 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { | 129 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { |
| 128 args->Add(call->PushArgumentAt(i)); | 130 args->Add(call->PushArgumentAt(i)); |
| 129 } | 131 } |
| 130 StaticCallInstr* static_call = new (Z) StaticCallInstr( | 132 StaticCallInstr* static_call = new (Z) StaticCallInstr( |
| 131 call->token_pos(), Function::ZoneHandle(Z, function.raw()), | 133 call->token_pos(), Function::ZoneHandle(Z, function.raw()), kTypeArgsLen, |
| 132 call->argument_names(), args, call->deopt_id()); | 134 call->argument_names(), args, call->deopt_id()); |
| 133 static_call->set_result_cid(kTypeCid); | 135 static_call->set_result_cid(kTypeCid); |
| 134 call->ReplaceWith(static_call, current_iterator()); | 136 call->ReplaceWith(static_call, current_iterator()); |
| 135 return true; | 137 return true; |
| 136 } | 138 } |
| 137 | 139 |
| 138 | 140 |
| 139 // Optimize instance calls using cid. This is called after optimizer | 141 // Optimize instance calls using cid. This is called after optimizer |
| 140 // converted instance calls to instructions. Any remaining | 142 // converted instance calls to instructions. Any remaining |
| 141 // instance calls are either megamorphic calls, cannot be optimized or | 143 // instance calls are either megamorphic calls, cannot be optimized or |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 | 217 |
| 216 if (all_cids_known) { | 218 if (all_cids_known) { |
| 217 const Class& receiver_class = | 219 const Class& receiver_class = |
| 218 Class::Handle(Z, isolate()->class_table()->At(class_ids[0])); | 220 Class::Handle(Z, isolate()->class_table()->At(class_ids[0])); |
| 219 if (!receiver_class.is_finalized()) { | 221 if (!receiver_class.is_finalized()) { |
| 220 // Do not eagerly finalize classes. ResolveDynamicForReceiverClass can | 222 // Do not eagerly finalize classes. ResolveDynamicForReceiverClass can |
| 221 // cause class finalization, since callee's receiver class may not be | 223 // cause class finalization, since callee's receiver class may not be |
| 222 // finalized yet. | 224 // finalized yet. |
| 223 return false; | 225 return false; |
| 224 } | 226 } |
| 225 const Array& args_desc_array = | 227 const Array& args_desc_array = Array::Handle( |
| 226 Array::Handle(Z, ArgumentsDescriptor::New(call->ArgumentCount(), | 228 Z, ArgumentsDescriptor::New( |
| 227 call->argument_names())); | 229 call->type_args_len(), |
| 230 call->ArgumentCount() - (call->type_args_len() > 0 ? 1 : 0), | |
|
zra
2017/05/03 15:03:24
This pattern gets repeated a lot. I'd recommend mo
regis
2017/05/09 18:31:22
Done.
| |
| 231 call->argument_names())); | |
| 228 ArgumentsDescriptor args_desc(args_desc_array); | 232 ArgumentsDescriptor args_desc(args_desc_array); |
| 229 const Function& function = Function::Handle( | 233 const Function& function = Function::Handle( |
| 230 Z, Resolver::ResolveDynamicForReceiverClass( | 234 Z, Resolver::ResolveDynamicForReceiverClass( |
| 231 receiver_class, call->function_name(), args_desc)); | 235 receiver_class, call->function_name(), args_desc)); |
| 232 if (function.IsNull()) { | 236 if (function.IsNull()) { |
| 233 return false; | 237 return false; |
| 234 } | 238 } |
| 235 | 239 |
| 236 // Create new ICData, do not modify the one attached to the instruction | 240 // Create new ICData, do not modify the one attached to the instruction |
| 237 // since it is attached to the assembly instruction itself. | 241 // since it is attached to the assembly instruction itself. |
| 238 // TODO(srdjan): Prevent modification of ICData object that is | 242 // TODO(srdjan): Prevent modification of ICData object that is |
| 239 // referenced in assembly code. | 243 // referenced in assembly code. |
| 240 const ICData& ic_data = ICData::ZoneHandle( | 244 const ICData& ic_data = ICData::ZoneHandle( |
| 241 Z, ICData::NewFrom(*call->ic_data(), class_ids.length())); | 245 Z, ICData::NewFrom(*call->ic_data(), class_ids.length())); |
| 242 if (class_ids.length() > 1) { | 246 if (class_ids.length() > 1) { |
| 243 ic_data.AddCheck(class_ids, function); | 247 ic_data.AddCheck(class_ids, function); |
| 244 } else { | 248 } else { |
| 245 ASSERT(class_ids.length() == 1); | 249 ASSERT(class_ids.length() == 1); |
| 246 ic_data.AddReceiverCheck(class_ids[0], function); | 250 ic_data.AddReceiverCheck(class_ids[0], function); |
| 247 } | 251 } |
| 248 call->set_ic_data(&ic_data); | 252 call->set_ic_data(&ic_data); |
| 249 return true; | 253 return true; |
| 250 } | 254 } |
| 251 | 255 |
| 252 if (isolate()->object_store()->unique_dynamic_targets() != Array::null()) { | 256 if (isolate()->object_store()->unique_dynamic_targets() != Array::null()) { |
| 253 // Check if the target is unique. | 257 // Check if the target is unique. |
| 254 Function& target_function = Function::Handle(Z); | 258 Function& target_function = Function::Handle(Z); |
| 255 GetUniqueDynamicTarget(isolate(), call->function_name(), &target_function); | 259 GetUniqueDynamicTarget(isolate(), call->function_name(), &target_function); |
| 256 // Calls with named arguments must be resolved/checked at runtime. | 260 // Calls passing named arguments and calls to a function taking named |
| 261 // arguments must be resolved/checked at runtime. | |
| 262 // Calls passing a type argument vector and calls to a generic function must | |
| 263 // be resolved/checked at runtime. | |
| 257 if (!target_function.IsNull() && | 264 if (!target_function.IsNull() && |
| 258 !target_function.HasOptionalNamedParameters() && | 265 !target_function.HasOptionalNamedParameters() && |
| 259 target_function.AreValidArgumentCounts(call->ArgumentCount(), 0, | 266 !target_function.IsGeneric() && |
| 267 target_function.AreValidArgumentCounts(call->type_args_len(), | |
| 268 call->ArgumentCount(), | |
| 269 call->argument_names().Length(), | |
| 260 /* error_message = */ NULL)) { | 270 /* error_message = */ NULL)) { |
| 261 const Class& cls = Class::Handle(Z, target_function.Owner()); | 271 const Class& cls = Class::Handle(Z, target_function.Owner()); |
| 262 if (!CHA::IsImplemented(cls) && !CHA::HasSubclasses(cls)) { | 272 if (!CHA::IsImplemented(cls) && !CHA::HasSubclasses(cls)) { |
| 263 const ICData& ic_data = | 273 const ICData& ic_data = |
| 264 ICData::ZoneHandle(Z, ICData::NewFrom(*call->ic_data(), 1)); | 274 ICData::ZoneHandle(Z, ICData::NewFrom(*call->ic_data(), 1)); |
| 265 ic_data.AddReceiverCheck(cls.id(), target_function); | 275 ic_data.AddReceiverCheck(cls.id(), target_function); |
| 266 call->set_ic_data(&ic_data); | 276 call->set_ic_data(&ic_data); |
| 267 if (has_unique_no_such_method_) { | 277 if (has_unique_no_such_method_) { |
| 268 call->set_has_unique_selector(true); | 278 call->set_has_unique_selector(true); |
| 269 // Add redefinition of the receiver to prevent code motion across | 279 // Add redefinition of the receiver to prevent code motion across |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 642 | 652 |
| 643 ZoneGrowableArray<PushArgumentInstr*>* args = | 653 ZoneGrowableArray<PushArgumentInstr*>* args = |
| 644 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); | 654 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 645 PushArgumentInstr* arg = | 655 PushArgumentInstr* arg = |
| 646 new (Z) PushArgumentInstr(new (Z) Value(left->ArgumentAt(0))); | 656 new (Z) PushArgumentInstr(new (Z) Value(left->ArgumentAt(0))); |
| 647 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | 657 InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| 648 args->Add(arg); | 658 args->Add(arg); |
| 649 arg = new (Z) PushArgumentInstr(new (Z) Value(right->ArgumentAt(0))); | 659 arg = new (Z) PushArgumentInstr(new (Z) Value(right->ArgumentAt(0))); |
| 650 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | 660 InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
| 651 args->Add(arg); | 661 args->Add(arg); |
| 652 StaticCallInstr* static_call = | 662 const intptr_t kTypeArgsLen = 0; |
|
zra
2017/05/03 15:03:24
ASSERT(call->type_args_len() == kTypeArgsLen) ?
regis
2017/05/09 18:31:22
Done, although arguments names and others were not
| |
| 653 new (Z) StaticCallInstr(call->token_pos(), have_same_runtime_type, | 663 StaticCallInstr* static_call = new (Z) |
| 654 Object::null_array(), // argument_names | 664 StaticCallInstr(call->token_pos(), have_same_runtime_type, kTypeArgsLen, |
| 655 args, call->deopt_id()); | 665 Object::null_array(), // argument_names |
| 666 args, call->deopt_id()); | |
| 656 static_call->set_result_cid(kBoolCid); | 667 static_call->set_result_cid(kBoolCid); |
| 657 ReplaceCall(call, static_call); | 668 ReplaceCall(call, static_call); |
| 658 return true; | 669 return true; |
| 659 } | 670 } |
| 660 | 671 |
| 661 return false; | 672 return false; |
| 662 } | 673 } |
| 663 | 674 |
| 664 | 675 |
| 665 bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call, | 676 bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call, |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1508 args->Add(arg); | 1519 args->Add(arg); |
| 1509 | 1520 |
| 1510 const Library& dart_internal = | 1521 const Library& dart_internal = |
| 1511 Library::Handle(Z, Library::InternalLibrary()); | 1522 Library::Handle(Z, Library::InternalLibrary()); |
| 1512 const String& target_name = Symbols::_classRangeCheck(); | 1523 const String& target_name = Symbols::_classRangeCheck(); |
| 1513 const Function& target = Function::ZoneHandle( | 1524 const Function& target = Function::ZoneHandle( |
| 1514 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); | 1525 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); |
| 1515 ASSERT(!target.IsNull()); | 1526 ASSERT(!target.IsNull()); |
| 1516 ASSERT(target.IsRecognized() && target.always_inline()); | 1527 ASSERT(target.IsRecognized() && target.always_inline()); |
| 1517 | 1528 |
| 1529 const intptr_t kTypeArgsLen = 0; | |
|
zra
2017/05/03 15:03:24
ditto.
regis
2017/05/09 18:31:22
Done.
| |
| 1518 StaticCallInstr* new_call = | 1530 StaticCallInstr* new_call = |
| 1519 new (Z) StaticCallInstr(call->token_pos(), target, | 1531 new (Z) StaticCallInstr(call->token_pos(), target, kTypeArgsLen, |
| 1520 Object::null_array(), // argument_names | 1532 Object::null_array(), // argument_names |
| 1521 args, call->deopt_id()); | 1533 args, call->deopt_id()); |
| 1522 Environment* copy = call->env()->DeepCopy( | 1534 Environment* copy = call->env()->DeepCopy( |
| 1523 Z, call->env()->Length() - call->ArgumentCount()); | 1535 Z, call->env()->Length() - call->ArgumentCount()); |
| 1524 for (intptr_t i = 0; i < args->length(); ++i) { | 1536 for (intptr_t i = 0; i < args->length(); ++i) { |
| 1525 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); | 1537 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); |
| 1526 } | 1538 } |
| 1527 call->RemoveEnvironment(); | 1539 call->RemoveEnvironment(); |
| 1528 ReplaceCall(call, new_call); | 1540 ReplaceCall(call, new_call); |
| 1529 copy->DeepCopyTo(Z, new_call); | 1541 copy->DeepCopyTo(Z, new_call); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1600 args->Add(arg); | 1612 args->Add(arg); |
| 1601 | 1613 |
| 1602 const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); | 1614 const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); |
| 1603 const String& target_name = Symbols::_classIdEqualsAssert(); | 1615 const String& target_name = Symbols::_classIdEqualsAssert(); |
| 1604 const Function& target = Function::ZoneHandle( | 1616 const Function& target = Function::ZoneHandle( |
| 1605 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); | 1617 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); |
| 1606 ASSERT(!target.IsNull()); | 1618 ASSERT(!target.IsNull()); |
| 1607 ASSERT(target.IsRecognized()); | 1619 ASSERT(target.IsRecognized()); |
| 1608 ASSERT(target.always_inline()); | 1620 ASSERT(target.always_inline()); |
| 1609 | 1621 |
| 1622 const intptr_t kTypeArgsLen = 0; | |
|
zra
2017/05/03 15:03:24
ditto.
regis
2017/05/09 18:31:22
Done.
| |
| 1610 StaticCallInstr* new_call = | 1623 StaticCallInstr* new_call = |
| 1611 new (Z) StaticCallInstr(call->token_pos(), target, | 1624 new (Z) StaticCallInstr(call->token_pos(), target, kTypeArgsLen, |
| 1612 Object::null_array(), // argument_names | 1625 Object::null_array(), // argument_names |
| 1613 args, call->deopt_id()); | 1626 args, call->deopt_id()); |
| 1614 Environment* copy = | 1627 Environment* copy = |
| 1615 call->env()->DeepCopy(Z, call->env()->Length() - call->ArgumentCount()); | 1628 call->env()->DeepCopy(Z, call->env()->Length() - call->ArgumentCount()); |
| 1616 for (intptr_t i = 0; i < args->length(); ++i) { | 1629 for (intptr_t i = 0; i < args->length(); ++i) { |
| 1617 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); | 1630 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); |
| 1618 } | 1631 } |
| 1619 call->RemoveEnvironment(); | 1632 call->RemoveEnvironment(); |
| 1620 ReplaceCall(call, new_call); | 1633 ReplaceCall(call, new_call); |
| 1621 copy->DeepCopyTo(Z, new_call); | 1634 copy->DeepCopyTo(Z, new_call); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1663 args->Add(arg); | 1676 args->Add(arg); |
| 1664 | 1677 |
| 1665 const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); | 1678 const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); |
| 1666 const String& target_name = Symbols::_classRangeAssert(); | 1679 const String& target_name = Symbols::_classRangeAssert(); |
| 1667 const Function& target = Function::ZoneHandle( | 1680 const Function& target = Function::ZoneHandle( |
| 1668 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); | 1681 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); |
| 1669 ASSERT(!target.IsNull()); | 1682 ASSERT(!target.IsNull()); |
| 1670 ASSERT(target.IsRecognized()); | 1683 ASSERT(target.IsRecognized()); |
| 1671 ASSERT(target.always_inline()); | 1684 ASSERT(target.always_inline()); |
| 1672 | 1685 |
| 1686 const intptr_t kTypeArgsLen = 0; | |
|
zra
2017/05/03 15:03:24
ditto.
regis
2017/05/09 18:31:22
Done.
| |
| 1673 StaticCallInstr* new_call = | 1687 StaticCallInstr* new_call = |
| 1674 new (Z) StaticCallInstr(call->token_pos(), target, | 1688 new (Z) StaticCallInstr(call->token_pos(), target, kTypeArgsLen, |
| 1675 Object::null_array(), // argument_names | 1689 Object::null_array(), // argument_names |
| 1676 args, call->deopt_id()); | 1690 args, call->deopt_id()); |
| 1677 Environment* copy = call->env()->DeepCopy( | 1691 Environment* copy = call->env()->DeepCopy( |
| 1678 Z, call->env()->Length() - call->ArgumentCount()); | 1692 Z, call->env()->Length() - call->ArgumentCount()); |
| 1679 for (intptr_t i = 0; i < args->length(); ++i) { | 1693 for (intptr_t i = 0; i < args->length(); ++i) { |
| 1680 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); | 1694 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); |
| 1681 } | 1695 } |
| 1682 call->RemoveEnvironment(); | 1696 call->RemoveEnvironment(); |
| 1683 ReplaceCall(call, new_call); | 1697 ReplaceCall(call, new_call); |
| 1684 copy->DeepCopyTo(Z, new_call); | 1698 copy->DeepCopyTo(Z, new_call); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1894 break; | 1908 break; |
| 1895 } | 1909 } |
| 1896 | 1910 |
| 1897 // No IC data checks. Try resolve target using the propagated cid. | 1911 // No IC data checks. Try resolve target using the propagated cid. |
| 1898 const intptr_t receiver_cid = | 1912 const intptr_t receiver_cid = |
| 1899 instr->PushArgumentAt(0)->value()->Type()->ToCid(); | 1913 instr->PushArgumentAt(0)->value()->Type()->ToCid(); |
| 1900 if (receiver_cid != kDynamicCid) { | 1914 if (receiver_cid != kDynamicCid) { |
| 1901 const Class& receiver_class = | 1915 const Class& receiver_class = |
| 1902 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); | 1916 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); |
| 1903 | 1917 |
| 1904 const Array& args_desc_array = | 1918 const Array& args_desc_array = Array::Handle( |
| 1905 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(), | 1919 Z, ArgumentsDescriptor::New( |
| 1906 instr->argument_names())); | 1920 instr->type_args_len(), |
| 1921 instr->ArgumentCount() - (instr->type_args_len() > 0 ? 1 : 0), | |
| 1922 instr->argument_names())); | |
| 1907 ArgumentsDescriptor args_desc(args_desc_array); | 1923 ArgumentsDescriptor args_desc(args_desc_array); |
| 1908 Function& function = Function::Handle( | 1924 Function& function = Function::Handle( |
| 1909 Z, Resolver::ResolveDynamicForReceiverClass( | 1925 Z, Resolver::ResolveDynamicForReceiverClass( |
| 1910 receiver_class, instr->function_name(), args_desc)); | 1926 receiver_class, instr->function_name(), args_desc)); |
| 1911 if (!function.IsNull()) { | 1927 if (!function.IsNull()) { |
| 1912 CallTargets* targets = new (Z) CallTargets(); | 1928 CallTargets* targets = new (Z) CallTargets(); |
| 1913 Function& target = Function::ZoneHandle(Z, function.raw()); | 1929 Function& target = Function::ZoneHandle(Z, function.raw()); |
| 1914 targets->Add(CidRangeTarget(receiver_class.id(), receiver_class.id(), | 1930 targets->Add(CidRangeTarget(receiver_class.id(), receiver_class.id(), |
| 1915 &target, /*count = */ 1)); | 1931 &target, /*count = */ 1)); |
| 1916 PolymorphicInstanceCallInstr* call = | 1932 PolymorphicInstanceCallInstr* call = |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1945 GrowableArray<intptr_t> class_ids(6); | 1961 GrowableArray<intptr_t> class_ids(6); |
| 1946 if (thread()->cha()->ConcreteSubclasses(receiver_class, &class_ids)) { | 1962 if (thread()->cha()->ConcreteSubclasses(receiver_class, &class_ids)) { |
| 1947 // First check if all subclasses end up calling the same method. | 1963 // First check if all subclasses end up calling the same method. |
| 1948 // If this is the case we will replace instance call with a direct | 1964 // If this is the case we will replace instance call with a direct |
| 1949 // static call. | 1965 // static call. |
| 1950 // Otherwise we will try to create ICData that contains all possible | 1966 // Otherwise we will try to create ICData that contains all possible |
| 1951 // targets with appropriate checks. | 1967 // targets with appropriate checks. |
| 1952 Function& single_target = Function::Handle(Z); | 1968 Function& single_target = Function::Handle(Z); |
| 1953 ICData& ic_data = ICData::Handle(Z); | 1969 ICData& ic_data = ICData::Handle(Z); |
| 1954 | 1970 |
| 1955 const Array& args_desc_array = | 1971 const Array& args_desc_array = Array::Handle( |
| 1956 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(), | 1972 Z, ArgumentsDescriptor::New( |
| 1957 instr->argument_names())); | 1973 instr->type_args_len(), |
| 1974 instr->ArgumentCount() - (instr->type_args_len() > 0 ? 1 : 0), | |
| 1975 instr->argument_names())); | |
| 1958 ArgumentsDescriptor args_desc(args_desc_array); | 1976 ArgumentsDescriptor args_desc(args_desc_array); |
| 1959 | 1977 |
| 1960 Function& target = Function::Handle(Z); | 1978 Function& target = Function::Handle(Z); |
| 1961 Class& cls = Class::Handle(Z); | 1979 Class& cls = Class::Handle(Z); |
| 1962 for (intptr_t i = 0; i < class_ids.length(); i++) { | 1980 for (intptr_t i = 0; i < class_ids.length(); i++) { |
| 1963 const intptr_t cid = class_ids[i]; | 1981 const intptr_t cid = class_ids[i]; |
| 1964 cls = isolate()->class_table()->At(cid); | 1982 cls = isolate()->class_table()->At(cid); |
| 1965 target = Resolver::ResolveDynamicForReceiverClass( | 1983 target = Resolver::ResolveDynamicForReceiverClass( |
| 1966 cls, instr->function_name(), args_desc); | 1984 cls, instr->function_name(), args_desc); |
| 1967 | 1985 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2025 | 2043 |
| 2026 // We have computed that there is only a single target for this call | 2044 // We have computed that there is only a single target for this call |
| 2027 // within the whole hierarchy. Replace InstanceCall with StaticCall. | 2045 // within the whole hierarchy. Replace InstanceCall with StaticCall. |
| 2028 ZoneGrowableArray<PushArgumentInstr*>* args = new (Z) | 2046 ZoneGrowableArray<PushArgumentInstr*>* args = new (Z) |
| 2029 ZoneGrowableArray<PushArgumentInstr*>(instr->ArgumentCount()); | 2047 ZoneGrowableArray<PushArgumentInstr*>(instr->ArgumentCount()); |
| 2030 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) { | 2048 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) { |
| 2031 args->Add(instr->PushArgumentAt(i)); | 2049 args->Add(instr->PushArgumentAt(i)); |
| 2032 } | 2050 } |
| 2033 StaticCallInstr* call = new (Z) StaticCallInstr( | 2051 StaticCallInstr* call = new (Z) StaticCallInstr( |
| 2034 instr->token_pos(), Function::ZoneHandle(Z, single_target.raw()), | 2052 instr->token_pos(), Function::ZoneHandle(Z, single_target.raw()), |
| 2035 instr->argument_names(), args, instr->deopt_id()); | 2053 instr->type_args_len(), instr->argument_names(), args, |
| 2054 instr->deopt_id()); | |
| 2036 instr->ReplaceWith(call, current_iterator()); | 2055 instr->ReplaceWith(call, current_iterator()); |
| 2037 return; | 2056 return; |
| 2038 } else if ((ic_data.raw() != ICData::null()) && | 2057 } else if ((ic_data.raw() != ICData::null()) && |
| 2039 !ic_data.NumberOfChecksIs(0)) { | 2058 !ic_data.NumberOfChecksIs(0)) { |
| 2040 CallTargets* targets = CallTargets::Create(Z, ic_data); | 2059 CallTargets* targets = CallTargets::Create(Z, ic_data); |
| 2041 PolymorphicInstanceCallInstr* call = | 2060 PolymorphicInstanceCallInstr* call = |
| 2042 new (Z) PolymorphicInstanceCallInstr(instr, *targets, | 2061 new (Z) PolymorphicInstanceCallInstr(instr, *targets, |
| 2043 /* with_checks = */ true, | 2062 /* with_checks = */ true, |
| 2044 /* complete = */ true); | 2063 /* complete = */ true); |
| 2045 instr->ReplaceWith(call, current_iterator()); | 2064 instr->ReplaceWith(call, current_iterator()); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 2067 | 2086 |
| 2068 void AotOptimizer::VisitPolymorphicInstanceCall( | 2087 void AotOptimizer::VisitPolymorphicInstanceCall( |
| 2069 PolymorphicInstanceCallInstr* call) { | 2088 PolymorphicInstanceCallInstr* call) { |
| 2070 if (call->with_checks()) { | 2089 if (call->with_checks()) { |
| 2071 const intptr_t receiver_cid = | 2090 const intptr_t receiver_cid = |
| 2072 call->PushArgumentAt(0)->value()->Type()->ToCid(); | 2091 call->PushArgumentAt(0)->value()->Type()->ToCid(); |
| 2073 if (receiver_cid != kDynamicCid) { | 2092 if (receiver_cid != kDynamicCid) { |
| 2074 const Class& receiver_class = | 2093 const Class& receiver_class = |
| 2075 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); | 2094 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); |
| 2076 | 2095 |
| 2096 const intptr_t type_args_len = call->instance_call()->type_args_len(); | |
| 2077 const Array& args_desc_array = Array::Handle( | 2097 const Array& args_desc_array = Array::Handle( |
| 2078 Z, ArgumentsDescriptor::New(call->ArgumentCount(), | 2098 Z, ArgumentsDescriptor::New( |
| 2079 call->instance_call()->argument_names())); | 2099 type_args_len, |
| 2100 call->ArgumentCount() - (type_args_len > 0 ? 1 : 0), | |
| 2101 call->instance_call()->argument_names())); | |
| 2080 ArgumentsDescriptor args_desc(args_desc_array); | 2102 ArgumentsDescriptor args_desc(args_desc_array); |
| 2081 const Function& function = Function::Handle( | 2103 const Function& function = Function::Handle( |
| 2082 Z, Resolver::ResolveDynamicForReceiverClass( | 2104 Z, Resolver::ResolveDynamicForReceiverClass( |
| 2083 receiver_class, call->instance_call()->function_name(), | 2105 receiver_class, call->instance_call()->function_name(), |
| 2084 args_desc)); | 2106 args_desc)); |
| 2085 if (!function.IsNull()) { | 2107 if (!function.IsNull()) { |
| 2086 call->set_with_checks(false); | 2108 call->set_with_checks(false); |
| 2087 } | 2109 } |
| 2088 } | 2110 } |
| 2089 } | 2111 } |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2255 FlowGraph::kEffect); | 2277 FlowGraph::kEffect); |
| 2256 current_iterator()->RemoveCurrentFromGraph(); | 2278 current_iterator()->RemoveCurrentFromGraph(); |
| 2257 } | 2279 } |
| 2258 } | 2280 } |
| 2259 } | 2281 } |
| 2260 } | 2282 } |
| 2261 | 2283 |
| 2262 #endif // DART_PRECOMPILER | 2284 #endif // DART_PRECOMPILER |
| 2263 | 2285 |
| 2264 } // namespace dart | 2286 } // namespace dart |
| OLD | NEW |