OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/precompiler.h" | 5 #include "vm/precompiler.h" |
6 | 6 |
7 #include "vm/aot_optimizer.h" | 7 #include "vm/aot_optimizer.h" |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
10 #include "vm/branch_optimizer.h" | 10 #include "vm/branch_optimizer.h" |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 | 206 |
207 // Clear these before dropping classes as they may hold onto otherwise | 207 // Clear these before dropping classes as they may hold onto otherwise |
208 // dead instances of classes we will remove. | 208 // dead instances of classes we will remove. |
209 I->object_store()->set_compile_time_constants(Array::null_array()); | 209 I->object_store()->set_compile_time_constants(Array::null_array()); |
210 I->object_store()->set_unique_dynamic_targets(Array::null_array()); | 210 I->object_store()->set_unique_dynamic_targets(Array::null_array()); |
211 | 211 |
212 DropClasses(); | 212 DropClasses(); |
213 DropLibraries(); | 213 DropLibraries(); |
214 | 214 |
215 BindStaticCalls(); | 215 BindStaticCalls(); |
| 216 SwitchICCalls(); |
216 | 217 |
217 DedupStackmaps(); | 218 DedupStackmaps(); |
218 DedupStackmapLists(); | 219 DedupStackmapLists(); |
219 | 220 |
220 if (FLAG_dedup_instructions) { | 221 if (FLAG_dedup_instructions) { |
221 // Reduces binary size but obfuscates profiler results. | 222 // Reduces binary size but obfuscates profiler results. |
222 DedupInstructions(); | 223 DedupInstructions(); |
223 } | 224 } |
224 | 225 |
225 zone_ = NULL; | 226 zone_ = NULL; |
(...skipping 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1648 Smi& pc_offset_; | 1649 Smi& pc_offset_; |
1649 Function& target_; | 1650 Function& target_; |
1650 Code& target_code_; | 1651 Code& target_code_; |
1651 }; | 1652 }; |
1652 | 1653 |
1653 BindStaticCallsVisitor visitor(Z); | 1654 BindStaticCallsVisitor visitor(Z); |
1654 VisitFunctions(&visitor); | 1655 VisitFunctions(&visitor); |
1655 } | 1656 } |
1656 | 1657 |
1657 | 1658 |
| 1659 void Precompiler::SwitchICCalls() { |
| 1660 // Now that all functions have been compiled, we can switch to an instance |
| 1661 // call sequence that loads the Code object and entry point directly from |
| 1662 // the ic data array instead indirectly through a Function in the ic data |
| 1663 // array. Iterate all the object pools and rewrite the ic data from |
| 1664 // (cid, target function, count) to (cid, target code, entry point), and |
| 1665 // replace the ICLookupThroughFunction stub with ICLookupThroughCode. |
| 1666 |
| 1667 class SwitchICCallsVisitor : public FunctionVisitor { |
| 1668 public: |
| 1669 explicit SwitchICCallsVisitor(Zone* zone) : |
| 1670 code_(Code::Handle(zone)), |
| 1671 pool_(ObjectPool::Handle(zone)), |
| 1672 entry_(Object::Handle(zone)), |
| 1673 ic_(ICData::Handle(zone)), |
| 1674 target_(Function::Handle(zone)), |
| 1675 target_code_(Code::Handle(zone)), |
| 1676 entry_point_(Smi::Handle(zone)) { |
| 1677 } |
| 1678 |
| 1679 void VisitFunction(const Function& function) { |
| 1680 if (!function.HasCode()) { |
| 1681 ASSERT(function.HasImplicitClosureFunction()); |
| 1682 return; |
| 1683 } |
| 1684 |
| 1685 code_ = function.CurrentCode(); |
| 1686 pool_ = code_.object_pool(); |
| 1687 for (intptr_t i = 0; i < pool_.Length(); i++) { |
| 1688 if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue; |
| 1689 entry_ = pool_.ObjectAt(i); |
| 1690 if (entry_.IsICData()) { |
| 1691 ic_ ^= entry_.raw(); |
| 1692 |
| 1693 // Only single check ICs are SwitchableCalls that use the ICLookup |
| 1694 // stubs. Some operators like + have ICData that check the types of |
| 1695 // arguments in addition to the receiver and use special stubs |
| 1696 // with fast paths for Smi operations. |
| 1697 if (ic_.NumArgsTested() != 1) continue; |
| 1698 |
| 1699 for (intptr_t j = 0; j < ic_.NumberOfChecks(); j++) { |
| 1700 entry_ = ic_.GetTargetOrCodeAt(j); |
| 1701 if (entry_.IsFunction()) { |
| 1702 target_ ^= entry_.raw(); |
| 1703 ASSERT(target_.HasCode()); |
| 1704 target_code_ = target_.CurrentCode(); |
| 1705 entry_point_ = Smi::FromAlignedAddress(target_code_.EntryPoint()); |
| 1706 ic_.SetCodeAt(j, target_code_); |
| 1707 ic_.SetEntryPointAt(j, entry_point_); |
| 1708 } else { |
| 1709 // We've already seen and switched this ICData. |
| 1710 ASSERT(entry_.IsCode()); |
| 1711 } |
| 1712 } |
| 1713 } else if (entry_.raw() == |
| 1714 StubCode::ICLookupThroughFunction_entry()->code()) { |
| 1715 target_code_ = StubCode::ICLookupThroughCode_entry()->code(); |
| 1716 pool_.SetObjectAt(i, target_code_); |
| 1717 } |
| 1718 } |
| 1719 } |
| 1720 |
| 1721 private: |
| 1722 Code& code_; |
| 1723 ObjectPool& pool_; |
| 1724 Object& entry_; |
| 1725 ICData& ic_; |
| 1726 Function& target_; |
| 1727 Code& target_code_; |
| 1728 Smi& entry_point_; |
| 1729 }; |
| 1730 |
| 1731 ASSERT(!I->compilation_allowed()); |
| 1732 SwitchICCallsVisitor visitor(Z); |
| 1733 VisitFunctions(&visitor); |
| 1734 } |
| 1735 |
| 1736 |
1658 void Precompiler::DedupStackmaps() { | 1737 void Precompiler::DedupStackmaps() { |
1659 class DedupStackmapsVisitor : public FunctionVisitor { | 1738 class DedupStackmapsVisitor : public FunctionVisitor { |
1660 public: | 1739 public: |
1661 explicit DedupStackmapsVisitor(Zone* zone) : | 1740 explicit DedupStackmapsVisitor(Zone* zone) : |
1662 zone_(zone), | 1741 zone_(zone), |
1663 canonical_stackmaps_(), | 1742 canonical_stackmaps_(), |
1664 code_(Code::Handle(zone)), | 1743 code_(Code::Handle(zone)), |
1665 stackmaps_(Array::Handle(zone)), | 1744 stackmaps_(Array::Handle(zone)), |
1666 stackmap_(Stackmap::Handle(zone)) { | 1745 stackmap_(Stackmap::Handle(zone)) { |
1667 } | 1746 } |
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2596 CompilationPipeline::New(thread->zone(), function); | 2675 CompilationPipeline::New(thread->zone(), function); |
2597 | 2676 |
2598 ASSERT(FLAG_precompiled_mode); | 2677 ASSERT(FLAG_precompiled_mode); |
2599 const bool optimized = function.IsOptimizable(); // False for natives. | 2678 const bool optimized = function.IsOptimizable(); // False for natives. |
2600 return PrecompileFunctionHelper(pipeline, function, optimized); | 2679 return PrecompileFunctionHelper(pipeline, function, optimized); |
2601 } | 2680 } |
2602 | 2681 |
2603 #endif // DART_PRECOMPILER | 2682 #endif // DART_PRECOMPILER |
2604 | 2683 |
2605 } // namespace dart | 2684 } // namespace dart |
OLD | NEW |