Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(425)

Side by Side Diff: runtime/vm/aot_optimizer.cc

Issue 2805903004: Working implementation of #29153 range check in as-casts. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698