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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 } | 93 } |
94 } | 94 } |
95 | 95 |
96 | 96 |
97 // Optimize instance calls using ICData. | 97 // Optimize instance calls using ICData. |
98 void AotOptimizer::ApplyICData() { | 98 void AotOptimizer::ApplyICData() { |
99 VisitBlocks(); | 99 VisitBlocks(); |
100 } | 100 } |
101 | 101 |
102 | 102 |
| 103 void AotOptimizer::PopulateWithICData() { |
| 104 ASSERT(current_iterator_ == NULL); |
| 105 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator(); |
| 106 !block_it.Done(); block_it.Advance()) { |
| 107 ForwardInstructionIterator it(block_it.Current()); |
| 108 for (; !it.Done(); it.Advance()) { |
| 109 Instruction* instr = it.Current(); |
| 110 if (instr->IsInstanceCall()) { |
| 111 InstanceCallInstr* call = instr->AsInstanceCall(); |
| 112 if (!call->HasICData()) { |
| 113 const Array& arguments_descriptor = Array::Handle( |
| 114 zone(), ArgumentsDescriptor::New(call->ArgumentCount(), |
| 115 call->argument_names())); |
| 116 const ICData& ic_data = ICData::ZoneHandle( |
| 117 zone(), ICData::New(function(), call->function_name(), |
| 118 arguments_descriptor, call->deopt_id(), |
| 119 call->checked_argument_count(), false)); |
| 120 call->set_ic_data(&ic_data); |
| 121 } |
| 122 } |
| 123 } |
| 124 current_iterator_ = NULL; |
| 125 } |
| 126 } |
| 127 |
| 128 |
103 bool AotOptimizer::RecognizeRuntimeTypeGetter(InstanceCallInstr* call) { | 129 bool AotOptimizer::RecognizeRuntimeTypeGetter(InstanceCallInstr* call) { |
104 if ((precompiler_ == NULL) || !precompiler_->get_runtime_type_is_unique()) { | 130 if ((precompiler_ == NULL) || !precompiler_->get_runtime_type_is_unique()) { |
105 return false; | 131 return false; |
106 } | 132 } |
107 | 133 |
108 if (call->function_name().raw() != Symbols::GetRuntimeType().raw()) { | 134 if (call->function_name().raw() != Symbols::GetRuntimeType().raw()) { |
109 return false; | 135 return false; |
110 } | 136 } |
111 | 137 |
112 // There is only a single function Object.get:runtimeType that can be invoked | 138 // There is only a single function Object.get:runtimeType that can be invoked |
(...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid))); | 1543 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid))); |
1518 | 1544 |
1519 StrictCompareInstr* check_cid = new (Z) StrictCompareInstr( | 1545 StrictCompareInstr* check_cid = new (Z) StrictCompareInstr( |
1520 call->token_pos(), negate ? Token::kNE_STRICT : Token::kEQ_STRICT, | 1546 call->token_pos(), negate ? Token::kNE_STRICT : Token::kEQ_STRICT, |
1521 new (Z) Value(left_cid), new (Z) Value(cid), | 1547 new (Z) Value(left_cid), new (Z) Value(cid), |
1522 false); // No number check. | 1548 false); // No number check. |
1523 ReplaceCall(call, check_cid); | 1549 ReplaceCall(call, check_cid); |
1524 return; | 1550 return; |
1525 } | 1551 } |
1526 | 1552 |
1527 if (precompiler_ != NULL) { | 1553 TypeRangeCache* cache = thread()->type_range_cache(); |
1528 TypeRangeCache* cache = precompiler_->type_range_cache(); | 1554 intptr_t lower_limit, upper_limit; |
1529 intptr_t lower_limit, upper_limit; | 1555 if (cache != NULL && |
1530 if (cache != NULL && | 1556 cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) { |
1531 cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) { | 1557 // left.instanceof(type) => |
1532 // left.instanceof(type) => | 1558 // _classRangeCheck(left.cid, lower_limit, upper_limit) |
1533 // _classRangeCheck(left.cid, lower_limit, upper_limit) | |
1534 | 1559 |
1535 LoadClassIdInstr* left_cid = | 1560 LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left)); |
1536 new (Z) LoadClassIdInstr(new (Z) Value(left)); | 1561 InsertBefore(call, left_cid, NULL, FlowGraph::kValue); |
1537 InsertBefore(call, left_cid, NULL, FlowGraph::kValue); | 1562 ConstantInstr* lower_cid = |
1538 ConstantInstr* lower_cid = | 1563 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(lower_limit))); |
1539 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(lower_limit))); | 1564 ConstantInstr* upper_cid = |
1540 ConstantInstr* upper_cid = | 1565 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(upper_limit))); |
1541 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(upper_limit))); | |
1542 | 1566 |
1543 ZoneGrowableArray<PushArgumentInstr*>* args = | 1567 ZoneGrowableArray<PushArgumentInstr*>* args = |
1544 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); | 1568 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); |
1545 PushArgumentInstr* arg = | 1569 PushArgumentInstr* arg = new (Z) PushArgumentInstr(new (Z) Value(left_cid)); |
1546 new (Z) PushArgumentInstr(new (Z) Value(left_cid)); | 1570 InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
1547 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | 1571 args->Add(arg); |
1548 args->Add(arg); | 1572 arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid)); |
1549 arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid)); | 1573 InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
1550 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | 1574 args->Add(arg); |
1551 args->Add(arg); | 1575 arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid)); |
1552 arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid)); | 1576 InsertBefore(call, arg, NULL, FlowGraph::kEffect); |
1553 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | 1577 args->Add(arg); |
1554 args->Add(arg); | |
1555 | 1578 |
1556 const Library& dart_internal = | 1579 const Library& dart_internal = |
1557 Library::Handle(Z, Library::InternalLibrary()); | 1580 Library::Handle(Z, Library::InternalLibrary()); |
1558 const String& target_name = negate ? Symbols::_classRangeCheckNegative() | 1581 const String& target_name = negate ? Symbols::_classRangeCheckNegative() |
1559 : Symbols::_classRangeCheck(); | 1582 : Symbols::_classRangeCheck(); |
1560 const Function& target = Function::ZoneHandle( | 1583 const Function& target = Function::ZoneHandle( |
1561 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); | 1584 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); |
1562 ASSERT(!target.IsNull()); | 1585 ASSERT(!target.IsNull()); |
1563 ASSERT(target.IsRecognized() && target.always_inline()); | 1586 ASSERT(target.IsRecognized() && target.always_inline()); |
1564 | 1587 |
1565 StaticCallInstr* new_call = | 1588 StaticCallInstr* new_call = |
1566 new (Z) StaticCallInstr(call->token_pos(), target, | 1589 new (Z) StaticCallInstr(call->token_pos(), target, |
1567 Object::null_array(), // argument_names | 1590 Object::null_array(), // argument_names |
1568 args, call->deopt_id()); | 1591 args, call->deopt_id()); |
1569 ReplaceCall(call, new_call); | 1592 ReplaceCall(call, new_call); |
1570 return; | 1593 return; |
1571 } | |
1572 } | 1594 } |
1573 | 1595 |
1574 const ICData& unary_checks = | 1596 const ICData& unary_checks = |
1575 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); | 1597 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); |
1576 if ((unary_checks.NumberOfChecks() > 0) && | 1598 if ((unary_checks.NumberOfChecks() > 0) && |
1577 (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) { | 1599 (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) { |
1578 ZoneGrowableArray<intptr_t>* results = | 1600 ZoneGrowableArray<intptr_t>* results = |
1579 new (Z) ZoneGrowableArray<intptr_t>(unary_checks.NumberOfChecks() * 2); | 1601 new (Z) ZoneGrowableArray<intptr_t>(unary_checks.NumberOfChecks() * 2); |
1580 InstanceOfAsBool(unary_checks, type, results); | 1602 InstanceOfAsBool(unary_checks, type, results); |
1581 if (results->length() == unary_checks.NumberOfChecks() * 2) { | 1603 if (results->length() == unary_checks.NumberOfChecks() * 2) { |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2163 FlowGraph::kEffect); | 2185 FlowGraph::kEffect); |
2164 current_iterator()->RemoveCurrentFromGraph(); | 2186 current_iterator()->RemoveCurrentFromGraph(); |
2165 } | 2187 } |
2166 } | 2188 } |
2167 } | 2189 } |
2168 } | 2190 } |
2169 | 2191 |
2170 #endif // DART_PRECOMPILER | 2192 #endif // DART_PRECOMPILER |
2171 | 2193 |
2172 } // namespace dart | 2194 } // namespace dart |
OLD | NEW |