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