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