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