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 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1558 | 1558 |
| 1559 | 1559 |
| 1560 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids). | 1560 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids). |
| 1561 void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { | 1561 void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
| 1562 ASSERT(Token::IsTypeCastOperator(call->token_kind())); | 1562 ASSERT(Token::IsTypeCastOperator(call->token_kind())); |
| 1563 Definition* left = call->ArgumentAt(0); | 1563 Definition* left = call->ArgumentAt(0); |
| 1564 Definition* type_args = call->ArgumentAt(1); | 1564 Definition* type_args = call->ArgumentAt(1); |
| 1565 const AbstractType& type = | 1565 const AbstractType& type = |
| 1566 AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()); | 1566 AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()); |
| 1567 ASSERT(!type.IsMalformedOrMalbounded()); | 1567 ASSERT(!type.IsMalformedOrMalbounded()); |
| 1568 | |
| 1569 if (TypeCheckAsClassEquality(type)) { | |
| 1570 LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left)); | |
| 1571 InsertBefore(call, left_cid, NULL, FlowGraph::kValue); | |
| 1572 const intptr_t type_cid = Class::Handle(Z, type.type_class()).id(); | |
| 1573 ConstantInstr* cid = | |
| 1574 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid))); | |
|
rmacnak
2017/04/10 21:07:24
ZoneHandle
| |
| 1575 ConstantInstr* pos = flow_graph()->GetConstant( | |
| 1576 Smi::Handle(Z, Smi::New(call->token_pos().Pos()))); | |
|
rmacnak
2017/04/10 21:07:24
ZoneHandle
| |
| 1577 | |
| 1578 ZoneGrowableArray<PushArgumentInstr*>* args = | |
| 1579 new (Z) ZoneGrowableArray<PushArgumentInstr*>(6); | |
| 1580 PushArgumentInstr* arg = new (Z) PushArgumentInstr(new (Z) Value(pos)); | |
| 1581 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1582 args->Add(arg); | |
| 1583 arg = new (Z) PushArgumentInstr(new (Z) Value(flow_graph()->GetConstant( | |
| 1584 String::Handle(Z, Symbols::InTypeCast().raw())))); | |
|
rmacnak
2017/04/10 21:07:23
In general, this should be String::ZoneHandle. Zon
| |
| 1585 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1586 args->Add(arg); | |
| 1587 arg = new (Z) PushArgumentInstr(new (Z) Value(left)); | |
| 1588 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1589 args->Add(arg); | |
| 1590 arg = new (Z) | |
| 1591 PushArgumentInstr(new (Z) Value(flow_graph()->GetConstant(type))); | |
| 1592 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1593 args->Add(arg); | |
| 1594 arg = new (Z) PushArgumentInstr(new (Z) Value(left_cid)); | |
| 1595 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1596 args->Add(arg); | |
| 1597 arg = new (Z) PushArgumentInstr(new (Z) Value(cid)); | |
| 1598 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1599 args->Add(arg); | |
| 1600 | |
| 1601 const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); | |
| 1602 const String& target_name = Symbols::_classIdEqualsAssert(); | |
| 1603 const Function& target = Function::ZoneHandle( | |
| 1604 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); | |
| 1605 ASSERT(!target.IsNull()); | |
| 1606 ASSERT(target.IsRecognized()); | |
| 1607 ASSERT(target.always_inline()); | |
| 1608 | |
| 1609 StaticCallInstr* new_call = | |
| 1610 new (Z) StaticCallInstr(call->token_pos(), target, | |
| 1611 Object::null_array(), // argument_names | |
| 1612 args, call->deopt_id()); | |
| 1613 Environment* copy = | |
| 1614 call->env()->DeepCopy(Z, call->env()->Length() - call->ArgumentCount()); | |
| 1615 for (intptr_t i = 0; i < args->length(); ++i) { | |
| 1616 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); | |
| 1617 } | |
| 1618 call->RemoveEnvironment(); | |
| 1619 ReplaceCall(call, new_call); | |
| 1620 copy->DeepCopyTo(Z, new_call); | |
| 1621 return; | |
| 1622 } | |
| 1623 | |
| 1624 if (precompiler_ != NULL) { | |
| 1625 TypeRangeCache* cache = precompiler_->type_range_cache(); | |
| 1626 intptr_t lower_limit, upper_limit; | |
| 1627 if (cache != NULL && | |
| 1628 cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) { | |
| 1629 // left.instanceof(type) => | |
| 1630 // _classRangeCheck(left.cid, lower_limit, upper_limit) | |
| 1631 | |
| 1632 LoadClassIdInstr* left_cid = | |
| 1633 new (Z) LoadClassIdInstr(new (Z) Value(left)); | |
| 1634 InsertBefore(call, left_cid, NULL, FlowGraph::kValue); | |
| 1635 ConstantInstr* lower_cid = | |
| 1636 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(lower_limit))); | |
|
rmacnak
2017/04/10 21:07:23
ZoneHandle
| |
| 1637 ConstantInstr* upper_cid = | |
| 1638 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(upper_limit))); | |
|
rmacnak
2017/04/10 21:07:23
ZoneHandle
| |
| 1639 ConstantInstr* pos = flow_graph()->GetConstant( | |
| 1640 Smi::Handle(Z, Smi::New(call->token_pos().Pos()))); | |
| 1641 | |
| 1642 ZoneGrowableArray<PushArgumentInstr*>* args = | |
| 1643 new (Z) ZoneGrowableArray<PushArgumentInstr*>(7); | |
| 1644 PushArgumentInstr* arg = new (Z) PushArgumentInstr(new (Z) Value(pos)); | |
| 1645 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1646 args->Add(arg); | |
| 1647 arg = new (Z) PushArgumentInstr(new (Z) Value(flow_graph()->GetConstant( | |
| 1648 String::Handle(Z, Symbols::InTypeCast().raw())))); | |
|
rmacnak
2017/04/10 21:07:23
ditto
| |
| 1649 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1650 args->Add(arg); | |
| 1651 arg = new (Z) PushArgumentInstr(new (Z) Value(left)); | |
| 1652 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1653 args->Add(arg); | |
| 1654 arg = new (Z) | |
| 1655 PushArgumentInstr(new (Z) Value(flow_graph()->GetConstant(type))); | |
| 1656 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1657 args->Add(arg); | |
| 1658 arg = new (Z) PushArgumentInstr(new (Z) Value(left_cid)); | |
| 1659 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1660 args->Add(arg); | |
| 1661 arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid)); | |
| 1662 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1663 args->Add(arg); | |
| 1664 arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid)); | |
| 1665 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1666 args->Add(arg); | |
| 1667 | |
| 1668 const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); | |
| 1669 const String& target_name = Symbols::_classRangeAssert(); | |
| 1670 const Function& target = Function::ZoneHandle( | |
| 1671 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); | |
| 1672 ASSERT(!target.IsNull()); | |
| 1673 ASSERT(target.IsRecognized()); | |
| 1674 ASSERT(target.always_inline()); | |
| 1675 | |
| 1676 StaticCallInstr* new_call = | |
| 1677 new (Z) StaticCallInstr(call->token_pos(), target, | |
| 1678 Object::null_array(), // argument_names | |
| 1679 args, call->deopt_id()); | |
| 1680 Environment* copy = call->env()->DeepCopy( | |
| 1681 Z, call->env()->Length() - call->ArgumentCount()); | |
| 1682 for (intptr_t i = 0; i < args->length(); ++i) { | |
| 1683 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); | |
| 1684 } | |
| 1685 call->RemoveEnvironment(); | |
| 1686 ReplaceCall(call, new_call); | |
| 1687 copy->DeepCopyTo(Z, new_call); | |
| 1688 return; | |
| 1689 } | |
| 1690 } | |
| 1691 | |
| 1568 const ICData& unary_checks = | 1692 const ICData& unary_checks = |
| 1569 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); | 1693 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); |
| 1570 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); | 1694 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); |
| 1571 if (number_of_checks > 0 && number_of_checks <= FLAG_max_polymorphic_checks) { | 1695 if (number_of_checks > 0 && number_of_checks <= FLAG_max_polymorphic_checks) { |
| 1572 ZoneGrowableArray<intptr_t>* results = | 1696 ZoneGrowableArray<intptr_t>* results = |
| 1573 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2); | 1697 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2); |
| 1574 const Bool& as_bool = | 1698 const Bool& as_bool = |
| 1575 Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results)); | 1699 Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results)); |
| 1576 if (as_bool.raw() == Bool::True().raw()) { | 1700 if (as_bool.raw() == Bool::True().raw()) { |
| 1577 // Guard against repeated speculative inlining. | 1701 // Guard against repeated speculative inlining. |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2132 FlowGraph::kEffect); | 2256 FlowGraph::kEffect); |
| 2133 current_iterator()->RemoveCurrentFromGraph(); | 2257 current_iterator()->RemoveCurrentFromGraph(); |
| 2134 } | 2258 } |
| 2135 } | 2259 } |
| 2136 } | 2260 } |
| 2137 } | 2261 } |
| 2138 | 2262 |
| 2139 #endif // DART_PRECOMPILER | 2263 #endif // DART_PRECOMPILER |
| 2140 | 2264 |
| 2141 } // namespace dart | 2265 } // namespace dart |
| OLD | NEW |