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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 dropped_class_count_(0), | 139 dropped_class_count_(0), |
140 dropped_typearg_count_(0), | 140 dropped_typearg_count_(0), |
141 dropped_type_count_(0), | 141 dropped_type_count_(0), |
142 dropped_library_count_(0), | 142 dropped_library_count_(0), |
143 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())), | 143 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())), |
144 pending_functions_( | 144 pending_functions_( |
145 GrowableObjectArray::Handle(GrowableObjectArray::New())), | 145 GrowableObjectArray::Handle(GrowableObjectArray::New())), |
146 sent_selectors_(), | 146 sent_selectors_(), |
147 enqueued_functions_(), | 147 enqueued_functions_(), |
148 fields_to_retain_(), | 148 fields_to_retain_(), |
| 149 functions_to_retain_(), |
149 classes_to_retain_(), | 150 classes_to_retain_(), |
150 typeargs_to_retain_(), | 151 typeargs_to_retain_(), |
151 types_to_retain_(), | 152 types_to_retain_(), |
152 consts_to_retain_(), | 153 consts_to_retain_(), |
153 error_(Error::Handle()) { | 154 error_(Error::Handle()) { |
154 } | 155 } |
155 | 156 |
156 | 157 |
157 void Precompiler::DoCompileAll( | 158 void Precompiler::DoCompileAll( |
158 Dart_QualifiedFunctionName embedder_entry_points[]) { | 159 Dart_QualifiedFunctionName embedder_entry_points[]) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 // Start with the allocations and invocations that happen from C++. | 193 // Start with the allocations and invocations that happen from C++. |
193 AddRoots(embedder_entry_points); | 194 AddRoots(embedder_entry_points); |
194 | 195 |
195 // Compile newly found targets and add their callees until we reach a | 196 // Compile newly found targets and add their callees until we reach a |
196 // fixed point. | 197 // fixed point. |
197 Iterate(); | 198 Iterate(); |
198 } | 199 } |
199 | 200 |
200 I->set_compilation_allowed(false); | 201 I->set_compilation_allowed(false); |
201 | 202 |
| 203 TraceForRetainedFunctions(); |
202 DropFunctions(); | 204 DropFunctions(); |
203 DropFields(); | 205 DropFields(); |
204 TraceTypesFromRetainedClasses(); | 206 TraceTypesFromRetainedClasses(); |
205 DropTypes(); | 207 DropTypes(); |
206 DropTypeArguments(); | 208 DropTypeArguments(); |
207 | 209 |
208 // Clear these before dropping classes as they may hold onto otherwise | 210 // Clear these before dropping classes as they may hold onto otherwise |
209 // dead instances of classes we will remove. | 211 // dead instances of classes we will remove. |
210 I->object_store()->set_compile_time_constants(Array::null_array()); | 212 I->object_store()->set_compile_time_constants(Array::null_array()); |
211 I->object_store()->set_unique_dynamic_targets(Array::null_array()); | 213 I->object_store()->set_unique_dynamic_targets(Array::null_array()); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 type = cls.mixin(); | 578 type = cls.mixin(); |
577 AddType(type); | 579 AddType(type); |
578 | 580 |
579 if (cls.IsTypedefClass()) { | 581 if (cls.IsTypedefClass()) { |
580 AddTypesOf(Function::Handle(Z, cls.signature_function())); | 582 AddTypesOf(Function::Handle(Z, cls.signature_function())); |
581 } | 583 } |
582 } | 584 } |
583 | 585 |
584 | 586 |
585 void Precompiler::AddTypesOf(const Function& function) { | 587 void Precompiler::AddTypesOf(const Function& function) { |
| 588 if (function.IsNull()) return; |
| 589 if (functions_to_retain_.Lookup(&function) != NULL) return; |
| 590 functions_to_retain_.Insert(&Function::ZoneHandle(Z, function.raw())); |
| 591 |
586 AbstractType& type = AbstractType::Handle(Z); | 592 AbstractType& type = AbstractType::Handle(Z); |
587 type = function.result_type(); | 593 type = function.result_type(); |
588 AddType(type); | 594 AddType(type); |
589 for (intptr_t i = 0; i < function.NumParameters(); i++) { | 595 for (intptr_t i = 0; i < function.NumParameters(); i++) { |
590 type = function.ParameterTypeAt(i); | 596 type = function.ParameterTypeAt(i); |
591 AddType(type); | 597 AddType(type); |
592 } | 598 } |
593 Code& code = Code::Handle(Z, function.CurrentCode()); | 599 Code& code = Code::Handle(Z, function.CurrentCode()); |
594 if (code.IsNull()) { | 600 if (code.IsNull()) { |
595 ASSERT(function.kind() == RawFunction::kSignatureFunction); | 601 ASSERT(function.kind() == RawFunction::kSignatureFunction); |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 function ^= functions.At(j); | 1209 function ^= functions.At(j); |
1204 if (function.is_const() && function.HasCode()) { | 1210 if (function.is_const() && function.HasCode()) { |
1205 AddCalleesOf(function); | 1211 AddCalleesOf(function); |
1206 } | 1212 } |
1207 } | 1213 } |
1208 } | 1214 } |
1209 } | 1215 } |
1210 } | 1216 } |
1211 | 1217 |
1212 | 1218 |
1213 void Precompiler::DropFunctions() { | 1219 void Precompiler::TraceForRetainedFunctions() { |
1214 Library& lib = Library::Handle(Z); | 1220 Library& lib = Library::Handle(Z); |
1215 Class& cls = Class::Handle(Z); | 1221 Class& cls = Class::Handle(Z); |
1216 Array& functions = Array::Handle(Z); | 1222 Array& functions = Array::Handle(Z); |
1217 Function& function = Function::Handle(Z); | 1223 Function& function = Function::Handle(Z); |
1218 Function& function2 = Function::Handle(Z); | 1224 Function& function2 = Function::Handle(Z); |
1219 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); | |
1220 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 1225 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); |
1221 String& name = String::Handle(Z); | |
1222 | 1226 |
1223 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1227 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
1224 lib ^= libraries_.At(i); | 1228 lib ^= libraries_.At(i); |
1225 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 1229 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
1226 while (it.HasNext()) { | 1230 while (it.HasNext()) { |
1227 cls = it.GetNextClass(); | 1231 cls = it.GetNextClass(); |
1228 if (cls.IsDynamicClass()) { | 1232 if (cls.IsDynamicClass()) { |
1229 continue; // class 'dynamic' is in the read-only VM isolate. | 1233 continue; // class 'dynamic' is in the read-only VM isolate. |
1230 } | 1234 } |
1231 | 1235 |
1232 functions = cls.functions(); | 1236 functions = cls.functions(); |
1233 retained_functions = GrowableObjectArray::New(); | |
1234 for (intptr_t j = 0; j < functions.Length(); j++) { | 1237 for (intptr_t j = 0; j < functions.Length(); j++) { |
1235 function ^= functions.At(j); | 1238 function ^= functions.At(j); |
1236 bool retain = function.HasCode(); | 1239 bool retain = function.HasCode(); |
1237 if (!retain && function.HasImplicitClosureFunction()) { | 1240 if (!retain && function.HasImplicitClosureFunction()) { |
1238 // It can happen that all uses of an implicit closure inline their | 1241 // It can happen that all uses of an implicit closure inline their |
1239 // target function, leaving the target function uncompiled. Keep | 1242 // target function, leaving the target function uncompiled. Keep |
1240 // the target function anyway so we can enumerate it to bind its | 1243 // the target function anyway so we can enumerate it to bind its |
1241 // static calls, etc. | 1244 // static calls, etc. |
1242 function2 = function.ImplicitClosureFunction(); | 1245 function2 = function.ImplicitClosureFunction(); |
1243 retain = function2.HasCode(); | 1246 retain = function2.HasCode(); |
1244 } | 1247 } |
1245 if (retain) { | 1248 if (retain) { |
1246 retained_functions.Add(function); | |
1247 function.DropUncompiledImplicitClosureFunction(); | 1249 function.DropUncompiledImplicitClosureFunction(); |
1248 AddTypesOf(function); | 1250 AddTypesOf(function); |
| 1251 } |
| 1252 } |
| 1253 } |
| 1254 } |
| 1255 |
| 1256 closures = isolate()->object_store()->closure_functions(); |
| 1257 for (intptr_t j = 0; j < closures.Length(); j++) { |
| 1258 function ^= closures.At(j); |
| 1259 bool retain = function.HasCode(); |
| 1260 if (retain) { |
| 1261 AddTypesOf(function); |
| 1262 |
| 1263 cls = function.Owner(); |
| 1264 AddTypesOf(cls); |
| 1265 |
| 1266 // It can happen that all uses of a function are inlined, leaving |
| 1267 // a compiled local function with an uncompiled parent. Retain such |
| 1268 // parents and their enclosing classes and libraries. |
| 1269 function = function.parent_function(); |
| 1270 while (!function.IsNull()) { |
| 1271 AddTypesOf(function); |
| 1272 function = function.parent_function(); |
| 1273 } |
| 1274 } |
| 1275 } |
| 1276 } |
| 1277 |
| 1278 |
| 1279 void Precompiler::DropFunctions() { |
| 1280 Library& lib = Library::Handle(Z); |
| 1281 Class& cls = Class::Handle(Z); |
| 1282 Array& functions = Array::Handle(Z); |
| 1283 Function& function = Function::Handle(Z); |
| 1284 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); |
| 1285 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); |
| 1286 String& name = String::Handle(Z); |
| 1287 |
| 1288 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 1289 lib ^= libraries_.At(i); |
| 1290 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 1291 while (it.HasNext()) { |
| 1292 cls = it.GetNextClass(); |
| 1293 if (cls.IsDynamicClass()) { |
| 1294 continue; // class 'dynamic' is in the read-only VM isolate. |
| 1295 } |
| 1296 |
| 1297 functions = cls.functions(); |
| 1298 retained_functions = GrowableObjectArray::New(); |
| 1299 for (intptr_t j = 0; j < functions.Length(); j++) { |
| 1300 function ^= functions.At(j); |
| 1301 bool retain = functions_to_retain_.Lookup(&function) != NULL; |
| 1302 function.DropUncompiledImplicitClosureFunction(); |
| 1303 if (retain) { |
| 1304 retained_functions.Add(function); |
1249 } else { | 1305 } else { |
1250 bool top_level = cls.IsTopLevel(); | 1306 bool top_level = cls.IsTopLevel(); |
1251 if (top_level && | 1307 if (top_level && |
1252 (function.kind() != RawFunction::kImplicitStaticFinalGetter)) { | 1308 (function.kind() != RawFunction::kImplicitStaticFinalGetter)) { |
1253 // Implicit static final getters are not added to the library | 1309 // Implicit static final getters are not added to the library |
1254 // dictionary in the first place. | 1310 // dictionary in the first place. |
1255 name = function.DictionaryName(); | 1311 name = function.DictionaryName(); |
1256 bool removed = lib.RemoveObject(function, name); | 1312 bool removed = lib.RemoveObject(function, name); |
1257 ASSERT(removed); | 1313 ASSERT(removed); |
1258 } | 1314 } |
(...skipping 11 matching lines...) Expand all Loading... |
1270 } else { | 1326 } else { |
1271 cls.SetFunctions(Object::empty_array()); | 1327 cls.SetFunctions(Object::empty_array()); |
1272 } | 1328 } |
1273 } | 1329 } |
1274 } | 1330 } |
1275 | 1331 |
1276 closures = isolate()->object_store()->closure_functions(); | 1332 closures = isolate()->object_store()->closure_functions(); |
1277 retained_functions = GrowableObjectArray::New(); | 1333 retained_functions = GrowableObjectArray::New(); |
1278 for (intptr_t j = 0; j < closures.Length(); j++) { | 1334 for (intptr_t j = 0; j < closures.Length(); j++) { |
1279 function ^= closures.At(j); | 1335 function ^= closures.At(j); |
1280 bool retain = function.HasCode(); | 1336 bool retain = functions_to_retain_.Lookup(&function) != NULL; |
1281 if (retain) { | 1337 if (retain) { |
1282 retained_functions.Add(function); | 1338 retained_functions.Add(function); |
1283 AddTypesOf(function); | |
1284 } else { | 1339 } else { |
1285 dropped_function_count_++; | 1340 dropped_function_count_++; |
1286 if (FLAG_trace_precompiler) { | 1341 if (FLAG_trace_precompiler) { |
1287 THR_Print("Dropping function %s\n", | 1342 THR_Print("Dropping function %s\n", |
1288 function.ToLibNamePrefixedQualifiedCString()); | 1343 function.ToLibNamePrefixedQualifiedCString()); |
1289 } | 1344 } |
1290 } | 1345 } |
1291 } | 1346 } |
1292 isolate()->object_store()->set_closure_functions(retained_functions); | 1347 isolate()->object_store()->set_closure_functions(retained_functions); |
1293 } | 1348 } |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1612 explicit BindStaticCallsVisitor(Zone* zone) : | 1667 explicit BindStaticCallsVisitor(Zone* zone) : |
1613 code_(Code::Handle(zone)), | 1668 code_(Code::Handle(zone)), |
1614 table_(Array::Handle(zone)), | 1669 table_(Array::Handle(zone)), |
1615 pc_offset_(Smi::Handle(zone)), | 1670 pc_offset_(Smi::Handle(zone)), |
1616 target_(Function::Handle(zone)), | 1671 target_(Function::Handle(zone)), |
1617 target_code_(Code::Handle(zone)) { | 1672 target_code_(Code::Handle(zone)) { |
1618 } | 1673 } |
1619 | 1674 |
1620 void VisitFunction(const Function& function) { | 1675 void VisitFunction(const Function& function) { |
1621 if (!function.HasCode()) { | 1676 if (!function.HasCode()) { |
1622 ASSERT(function.HasImplicitClosureFunction()); | |
1623 return; | 1677 return; |
1624 } | 1678 } |
1625 code_ = function.CurrentCode(); | 1679 code_ = function.CurrentCode(); |
1626 table_ = code_.static_calls_target_table(); | 1680 table_ = code_.static_calls_target_table(); |
1627 | 1681 |
1628 for (intptr_t i = 0; | 1682 for (intptr_t i = 0; |
1629 i < table_.Length(); | 1683 i < table_.Length(); |
1630 i += Code::kSCallTableEntryLength) { | 1684 i += Code::kSCallTableEntryLength) { |
1631 pc_offset_ ^= table_.At(i + Code::kSCallTableOffsetEntry); | 1685 pc_offset_ ^= table_.At(i + Code::kSCallTableOffsetEntry); |
1632 target_ ^= table_.At(i + Code::kSCallTableFunctionEntry); | 1686 target_ ^= table_.At(i + Code::kSCallTableFunctionEntry); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1681 pool_(ObjectPool::Handle(zone)), | 1735 pool_(ObjectPool::Handle(zone)), |
1682 entry_(Object::Handle(zone)), | 1736 entry_(Object::Handle(zone)), |
1683 ic_(ICData::Handle(zone)), | 1737 ic_(ICData::Handle(zone)), |
1684 target_(Function::Handle(zone)), | 1738 target_(Function::Handle(zone)), |
1685 target_code_(Code::Handle(zone)), | 1739 target_code_(Code::Handle(zone)), |
1686 entry_point_(Smi::Handle(zone)) { | 1740 entry_point_(Smi::Handle(zone)) { |
1687 } | 1741 } |
1688 | 1742 |
1689 void VisitFunction(const Function& function) { | 1743 void VisitFunction(const Function& function) { |
1690 if (!function.HasCode()) { | 1744 if (!function.HasCode()) { |
1691 ASSERT(function.HasImplicitClosureFunction()); | |
1692 return; | 1745 return; |
1693 } | 1746 } |
1694 | 1747 |
1695 code_ = function.CurrentCode(); | 1748 code_ = function.CurrentCode(); |
1696 pool_ = code_.object_pool(); | 1749 pool_ = code_.object_pool(); |
1697 for (intptr_t i = 0; i < pool_.Length(); i++) { | 1750 for (intptr_t i = 0; i < pool_.Length(); i++) { |
1698 if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue; | 1751 if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue; |
1699 entry_ = pool_.ObjectAt(i); | 1752 entry_ = pool_.ObjectAt(i); |
1700 if (entry_.IsICData()) { | 1753 if (entry_.IsICData()) { |
1701 ic_ ^= entry_.raw(); | 1754 ic_ ^= entry_.raw(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1750 explicit DedupStackmapsVisitor(Zone* zone) : | 1803 explicit DedupStackmapsVisitor(Zone* zone) : |
1751 zone_(zone), | 1804 zone_(zone), |
1752 canonical_stackmaps_(), | 1805 canonical_stackmaps_(), |
1753 code_(Code::Handle(zone)), | 1806 code_(Code::Handle(zone)), |
1754 stackmaps_(Array::Handle(zone)), | 1807 stackmaps_(Array::Handle(zone)), |
1755 stackmap_(Stackmap::Handle(zone)) { | 1808 stackmap_(Stackmap::Handle(zone)) { |
1756 } | 1809 } |
1757 | 1810 |
1758 void VisitFunction(const Function& function) { | 1811 void VisitFunction(const Function& function) { |
1759 if (!function.HasCode()) { | 1812 if (!function.HasCode()) { |
1760 ASSERT(function.HasImplicitClosureFunction()); | |
1761 return; | 1813 return; |
1762 } | 1814 } |
1763 code_ = function.CurrentCode(); | 1815 code_ = function.CurrentCode(); |
1764 stackmaps_ = code_.stackmaps(); | 1816 stackmaps_ = code_.stackmaps(); |
1765 if (stackmaps_.IsNull()) return; | 1817 if (stackmaps_.IsNull()) return; |
1766 for (intptr_t i = 0; i < stackmaps_.Length(); i++) { | 1818 for (intptr_t i = 0; i < stackmaps_.Length(); i++) { |
1767 stackmap_ ^= stackmaps_.At(i); | 1819 stackmap_ ^= stackmaps_.At(i); |
1768 stackmap_ = DedupStackmap(stackmap_); | 1820 stackmap_ = DedupStackmap(stackmap_); |
1769 stackmaps_.SetAt(i, stackmap_); | 1821 stackmaps_.SetAt(i, stackmap_); |
1770 } | 1822 } |
(...skipping 30 matching lines...) Expand all Loading... |
1801 explicit DedupStackmapListsVisitor(Zone* zone) : | 1853 explicit DedupStackmapListsVisitor(Zone* zone) : |
1802 zone_(zone), | 1854 zone_(zone), |
1803 canonical_stackmap_lists_(), | 1855 canonical_stackmap_lists_(), |
1804 code_(Code::Handle(zone)), | 1856 code_(Code::Handle(zone)), |
1805 stackmaps_(Array::Handle(zone)), | 1857 stackmaps_(Array::Handle(zone)), |
1806 stackmap_(Stackmap::Handle(zone)) { | 1858 stackmap_(Stackmap::Handle(zone)) { |
1807 } | 1859 } |
1808 | 1860 |
1809 void VisitFunction(const Function& function) { | 1861 void VisitFunction(const Function& function) { |
1810 if (!function.HasCode()) { | 1862 if (!function.HasCode()) { |
1811 ASSERT(function.HasImplicitClosureFunction()); | |
1812 return; | 1863 return; |
1813 } | 1864 } |
1814 code_ = function.CurrentCode(); | 1865 code_ = function.CurrentCode(); |
1815 stackmaps_ = code_.stackmaps(); | 1866 stackmaps_ = code_.stackmaps(); |
1816 if (stackmaps_.IsNull()) return; | 1867 if (stackmaps_.IsNull()) return; |
1817 | 1868 |
1818 stackmaps_ = DedupStackmapList(stackmaps_); | 1869 stackmaps_ = DedupStackmapList(stackmaps_); |
1819 code_.set_stackmaps(stackmaps_); | 1870 code_.set_stackmaps(stackmaps_); |
1820 } | 1871 } |
1821 | 1872 |
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2685 CompilationPipeline::New(thread->zone(), function); | 2736 CompilationPipeline::New(thread->zone(), function); |
2686 | 2737 |
2687 ASSERT(FLAG_precompiled_mode); | 2738 ASSERT(FLAG_precompiled_mode); |
2688 const bool optimized = function.IsOptimizable(); // False for natives. | 2739 const bool optimized = function.IsOptimizable(); // False for natives. |
2689 return PrecompileFunctionHelper(pipeline, function, optimized); | 2740 return PrecompileFunctionHelper(pipeline, function, optimized); |
2690 } | 2741 } |
2691 | 2742 |
2692 #endif // DART_PRECOMPILER | 2743 #endif // DART_PRECOMPILER |
2693 | 2744 |
2694 } // namespace dart | 2745 } // namespace dart |
OLD | NEW |