| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/hash_map.h" | 10 #include "vm/hash_map.h" |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 } | 679 } |
| 680 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) { | 680 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) { |
| 681 return; | 681 return; |
| 682 } | 682 } |
| 683 if ((op_kind == Token::kSET) && TryInlineInstanceSetter(instr)) { | 683 if ((op_kind == Token::kSET) && TryInlineInstanceSetter(instr)) { |
| 684 return; | 684 return; |
| 685 } | 685 } |
| 686 if (TryInlineInstanceMethod(instr)) { | 686 if (TryInlineInstanceMethod(instr)) { |
| 687 return; | 687 return; |
| 688 } | 688 } |
| 689 const ICData& unary_checks = |
| 690 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks()); |
| 691 if (FLAG_use_cha) { |
| 692 // Check if receiver can have only one target, in which case |
| 693 // we emit call without class checks. |
| 694 Definition* receiver = instr->ArgumentAt(0)->value()->definition(); |
| 695 ASSERT(receiver != NULL); |
| 696 const Function& function = flow_graph_->parsed_function().function(); |
| 697 if (function.IsDynamicFunction() && |
| 698 receiver->IsParameter() && |
| 699 (receiver->AsParameter()->index() == 0)) { |
| 700 intptr_t static_receiver_cid = Class::Handle(function.Owner()).id(); |
| 701 ZoneGrowableArray<intptr_t>* subclass_cids = |
| 702 CHA::GetSubclassIdsOf(static_receiver_cid); |
| 703 ZoneGrowableArray<Function*>* overriding_functions = |
| 704 CHA::GetNamedInstanceFunctionsOf(*subclass_cids, |
| 705 instr->function_name()); |
| 706 if (overriding_functions->is_empty()) { |
| 707 const bool call_with_checks = false; |
| 708 PolymorphicInstanceCallInstr* call = |
| 709 new PolymorphicInstanceCallInstr(instr, unary_checks, |
| 710 call_with_checks); |
| 711 instr->ReplaceWith(call, current_iterator()); |
| 712 return; |
| 713 } |
| 714 } |
| 715 } |
| 689 const intptr_t kMaxChecks = 4; | 716 const intptr_t kMaxChecks = 4; |
| 690 if (instr->ic_data()->NumberOfChecks() <= kMaxChecks) { | 717 if (instr->ic_data()->NumberOfChecks() <= kMaxChecks) { |
| 691 const ICData& unary_checks = | |
| 692 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks()); | |
| 693 bool call_with_checks; | 718 bool call_with_checks; |
| 694 // TODO(srdjan): Add check class instr for mixed smi/non-smi. | 719 // TODO(srdjan): Add check class instr for mixed smi/non-smi. |
| 695 if (HasOneTarget(unary_checks) && | 720 if (HasOneTarget(unary_checks) && |
| 696 (unary_checks.GetReceiverClassIdAt(0) != kSmiCid)) { | 721 (unary_checks.GetReceiverClassIdAt(0) != kSmiCid)) { |
| 697 // Type propagation has not run yet, we cannot eliminate the check. | 722 // Type propagation has not run yet, we cannot eliminate the check. |
| 698 AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy()); | 723 AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy()); |
| 699 // Call can still deoptimize, do not detach environment from instr. | 724 // Call can still deoptimize, do not detach environment from instr. |
| 700 call_with_checks = false; | 725 call_with_checks = false; |
| 701 } else { | 726 } else { |
| 702 call_with_checks = true; | 727 call_with_checks = true; |
| (...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. | 1327 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. |
| 1303 OptimizeRecursive(child, &child_map); | 1328 OptimizeRecursive(child, &child_map); |
| 1304 } else { | 1329 } else { |
| 1305 OptimizeRecursive(child, map); // Reuse map for the last child. | 1330 OptimizeRecursive(child, map); // Reuse map for the last child. |
| 1306 } | 1331 } |
| 1307 } | 1332 } |
| 1308 } | 1333 } |
| 1309 | 1334 |
| 1310 | 1335 |
| 1311 } // namespace dart | 1336 } // namespace dart |
| OLD | NEW |