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 #ifndef DART_PRECOMPILED_RUNTIME | 4 #ifndef DART_PRECOMPILED_RUNTIME |
| 5 #include "vm/jit_optimizer.h" | 5 #include "vm/jit_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 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1542 } | 1542 } |
| 1543 | 1543 |
| 1544 if (Token::IsTypeCastOperator(op_kind)) { | 1544 if (Token::IsTypeCastOperator(op_kind)) { |
| 1545 ReplaceWithTypeCast(instr); | 1545 ReplaceWithTypeCast(instr); |
| 1546 return; | 1546 return; |
| 1547 } | 1547 } |
| 1548 | 1548 |
| 1549 const ICData& unary_checks = | 1549 const ICData& unary_checks = |
| 1550 ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks()); | 1550 ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks()); |
| 1551 | 1551 |
| 1552 const bool is_dense = CheckClassInstr::IsDenseCidRange(unary_checks); | |
| 1553 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); | |
| 1554 if (op_kind == Token::kEQ && | |
| 1555 number_of_checks > FLAG_max_equality_polymorphic_checks && !is_dense && | |
| 1556 flow_graph()->InstanceCallNeedsClassCheck( | |
| 1557 instr, RawFunction::kRegularFunction)) { | |
| 1558 // Too many checks, it will be megamorphic which needs unary checks. | |
| 1559 instr->set_ic_data(&unary_checks); | |
| 1560 return; | |
| 1561 } | |
| 1562 | |
| 1563 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) { | 1552 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) { |
| 1564 return; | 1553 return; |
| 1565 } | 1554 } |
| 1566 if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) { | 1555 if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) { |
| 1567 return; | 1556 return; |
| 1568 } | 1557 } |
| 1569 | 1558 |
| 1570 if (op_kind == Token::kEQ && TryReplaceWithEqualityOp(instr, op_kind)) { | 1559 if (op_kind == Token::kEQ && TryReplaceWithEqualityOp(instr, op_kind)) { |
| 1571 return; | 1560 return; |
| 1572 } | 1561 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1622 PolymorphicInstanceCallInstr* call = | 1611 PolymorphicInstanceCallInstr* call = |
| 1623 new (Z) PolymorphicInstanceCallInstr(instr, unary_checks, | 1612 new (Z) PolymorphicInstanceCallInstr(instr, unary_checks, |
| 1624 /* call_with_checks = */ false, | 1613 /* call_with_checks = */ false, |
| 1625 /* complete = */ false); | 1614 /* complete = */ false); |
| 1626 instr->ReplaceWith(call, current_iterator()); | 1615 instr->ReplaceWith(call, current_iterator()); |
| 1627 return; | 1616 return; |
| 1628 } | 1617 } |
| 1629 } | 1618 } |
| 1630 | 1619 |
| 1631 bool call_with_checks; | 1620 bool call_with_checks; |
| 1632 if (has_one_target && FLAG_polymorphic_with_deopt) { | 1621 const int max_cids = (op_kind == Token::kEQ) |
|
Vyacheslav Egorov (Google)
2017/04/19 08:24:00
It might be good to put the reasoning here to info
erikcorry
2017/04/19 13:15:41
Done.
| |
| 1622 ? FLAG_max_equality_polymorphic_checks | |
| 1623 : FLAG_max_polymorphic_checks; | |
| 1624 if (has_one_target && FLAG_polymorphic_with_deopt && | |
| 1625 unary_checks.NumberOfChecks() <= max_cids) { | |
| 1633 // Type propagation has not run yet, we cannot eliminate the check. | 1626 // Type propagation has not run yet, we cannot eliminate the check. |
| 1634 AddReceiverCheck(instr); | 1627 AddReceiverCheck(instr); |
| 1635 // Call can still deoptimize, do not detach environment from instr. | 1628 // Call can still deoptimize, do not detach environment from instr. |
| 1636 call_with_checks = false; | 1629 call_with_checks = false; |
| 1637 } else { | 1630 } else { |
| 1638 call_with_checks = true; | 1631 call_with_checks = true; |
| 1639 } | 1632 } |
| 1640 PolymorphicInstanceCallInstr* call = new (Z) | 1633 PolymorphicInstanceCallInstr* call = new (Z) |
| 1641 PolymorphicInstanceCallInstr(instr, unary_checks, call_with_checks, | 1634 PolymorphicInstanceCallInstr(instr, unary_checks, call_with_checks, |
| 1642 /* complete = */ false); | 1635 /* complete = */ false); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1887 // Discard the environment from the original instruction because the store | 1880 // Discard the environment from the original instruction because the store |
| 1888 // can't deoptimize. | 1881 // can't deoptimize. |
| 1889 instr->RemoveEnvironment(); | 1882 instr->RemoveEnvironment(); |
| 1890 ReplaceCall(instr, store); | 1883 ReplaceCall(instr, store); |
| 1891 return true; | 1884 return true; |
| 1892 } | 1885 } |
| 1893 | 1886 |
| 1894 | 1887 |
| 1895 } // namespace dart | 1888 } // namespace dart |
| 1896 #endif // DART_PRECOMPILED_RUNTIME | 1889 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |