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