| 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 |