Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: runtime/vm/precompiler.cc

Issue 1893403002: Local closures may be the only survivors in a library. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/precompiler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/precompiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698