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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 dropped_library_count_(0), | 141 dropped_library_count_(0), |
142 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())), | 142 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())), |
143 pending_functions_( | 143 pending_functions_( |
144 GrowableObjectArray::Handle(GrowableObjectArray::New())), | 144 GrowableObjectArray::Handle(GrowableObjectArray::New())), |
145 sent_selectors_(), | 145 sent_selectors_(), |
146 enqueued_functions_(), | 146 enqueued_functions_(), |
147 fields_to_retain_(), | 147 fields_to_retain_(), |
148 classes_to_retain_(), | 148 classes_to_retain_(), |
149 typeargs_to_retain_(), | 149 typeargs_to_retain_(), |
150 types_to_retain_(), | 150 types_to_retain_(), |
| 151 consts_to_retain_(), |
151 error_(Error::Handle()) { | 152 error_(Error::Handle()) { |
152 } | 153 } |
153 | 154 |
154 | 155 |
155 void Precompiler::DoCompileAll( | 156 void Precompiler::DoCompileAll( |
156 Dart_QualifiedFunctionName embedder_entry_points[]) { | 157 Dart_QualifiedFunctionName embedder_entry_points[]) { |
157 ASSERT(I->compilation_allowed()); | 158 ASSERT(I->compilation_allowed()); |
158 | 159 |
159 { | 160 { |
160 StackZone stack_zone(T); | 161 StackZone stack_zone(T); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 | 403 |
403 while (changed_) { | 404 while (changed_) { |
404 changed_ = false; | 405 changed_ = false; |
405 | 406 |
406 while (pending_functions_.Length() > 0) { | 407 while (pending_functions_.Length() > 0) { |
407 function ^= pending_functions_.RemoveLast(); | 408 function ^= pending_functions_.RemoveLast(); |
408 ProcessFunction(function); | 409 ProcessFunction(function); |
409 } | 410 } |
410 | 411 |
411 CheckForNewDynamicFunctions(); | 412 CheckForNewDynamicFunctions(); |
| 413 if (!changed_) { |
| 414 TraceConstFunctions(); |
| 415 } |
412 } | 416 } |
413 } | 417 } |
414 | 418 |
415 | 419 |
416 void Precompiler::ProcessFunction(const Function& function) { | 420 void Precompiler::ProcessFunction(const Function& function) { |
417 if (!function.HasCode()) { | 421 if (!function.HasCode()) { |
418 function_count_++; | 422 function_count_++; |
419 | 423 |
420 if (FLAG_trace_precompiler) { | 424 if (FLAG_trace_precompiler) { |
421 THR_Print("Precompiling %" Pd " %s (%s, %s)\n", | 425 THR_Print("Precompiling %" Pd " %s (%s, %s)\n", |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 return; | 673 return; |
670 } | 674 } |
671 | 675 |
672 // Can't ask immediate objects if they're canoncial. | 676 // Can't ask immediate objects if they're canoncial. |
673 if (instance.IsSmi()) return; | 677 if (instance.IsSmi()) return; |
674 | 678 |
675 // Some Instances in the ObjectPool aren't const objects, such as | 679 // Some Instances in the ObjectPool aren't const objects, such as |
676 // argument descriptors. | 680 // argument descriptors. |
677 if (!instance.IsCanonical()) return; | 681 if (!instance.IsCanonical()) return; |
678 | 682 |
| 683 consts_to_retain_.Insert(&Instance::ZoneHandle(Z, instance.raw())); |
| 684 |
679 if (cls.NumTypeArguments() > 0) { | 685 if (cls.NumTypeArguments() > 0) { |
680 AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments())); | 686 AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments())); |
681 } | 687 } |
682 | 688 |
683 class ConstObjectVisitor : public ObjectPointerVisitor { | 689 class ConstObjectVisitor : public ObjectPointerVisitor { |
684 public: | 690 public: |
685 ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) : | 691 ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) : |
686 ObjectPointerVisitor(isolate), | 692 ObjectPointerVisitor(isolate), |
687 precompiler_(precompiler), | 693 precompiler_(precompiler), |
688 subinstance_(Object::Handle()) {} | 694 subinstance_(Object::Handle()) {} |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1153 Object* function) { | 1159 Object* function) { |
1154 UniqueFunctionsSet functions_set( | 1160 UniqueFunctionsSet functions_set( |
1155 isolate->object_store()->unique_dynamic_targets()); | 1161 isolate->object_store()->unique_dynamic_targets()); |
1156 ASSERT(fname.IsSymbol()); | 1162 ASSERT(fname.IsSymbol()); |
1157 *function = functions_set.GetOrNull(fname); | 1163 *function = functions_set.GetOrNull(fname); |
1158 ASSERT(functions_set.Release().raw() == | 1164 ASSERT(functions_set.Release().raw() == |
1159 isolate->object_store()->unique_dynamic_targets()); | 1165 isolate->object_store()->unique_dynamic_targets()); |
1160 } | 1166 } |
1161 | 1167 |
1162 | 1168 |
| 1169 void Precompiler::TraceConstFunctions() { |
| 1170 // Compilation of const accessors happens outside of the treeshakers |
| 1171 // queue, so we haven't previously scanned its literal pool. |
| 1172 |
| 1173 Library& lib = Library::Handle(Z); |
| 1174 Class& cls = Class::Handle(Z); |
| 1175 Array& functions = Array::Handle(Z); |
| 1176 Function& function = Function::Handle(Z); |
| 1177 |
| 1178 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 1179 lib ^= libraries_.At(i); |
| 1180 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 1181 while (it.HasNext()) { |
| 1182 cls = it.GetNextClass(); |
| 1183 if (cls.IsDynamicClass()) { |
| 1184 continue; // class 'dynamic' is in the read-only VM isolate. |
| 1185 } |
| 1186 |
| 1187 functions = cls.functions(); |
| 1188 for (intptr_t j = 0; j < functions.Length(); j++) { |
| 1189 function ^= functions.At(j); |
| 1190 if (function.is_const() && function.HasCode()) { |
| 1191 AddCalleesOf(function); |
| 1192 } |
| 1193 } |
| 1194 } |
| 1195 } |
| 1196 } |
| 1197 |
| 1198 |
1163 void Precompiler::DropFunctions() { | 1199 void Precompiler::DropFunctions() { |
1164 Library& lib = Library::Handle(Z); | 1200 Library& lib = Library::Handle(Z); |
1165 Class& cls = Class::Handle(Z); | 1201 Class& cls = Class::Handle(Z); |
1166 Array& functions = Array::Handle(Z); | 1202 Array& functions = Array::Handle(Z); |
1167 Function& function = Function::Handle(Z); | 1203 Function& function = Function::Handle(Z); |
1168 Function& function2 = Function::Handle(Z); | 1204 Function& function2 = Function::Handle(Z); |
1169 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); | 1205 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); |
1170 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 1206 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); |
1171 String& name = String::Handle(Z); | 1207 String& name = String::Handle(Z); |
1172 | 1208 |
(...skipping 28 matching lines...) Expand all Loading... |
1201 if (top_level && | 1237 if (top_level && |
1202 (function.kind() != RawFunction::kImplicitStaticFinalGetter)) { | 1238 (function.kind() != RawFunction::kImplicitStaticFinalGetter)) { |
1203 // Implicit static final getters are not added to the library | 1239 // Implicit static final getters are not added to the library |
1204 // dictionary in the first place. | 1240 // dictionary in the first place. |
1205 name = function.DictionaryName(); | 1241 name = function.DictionaryName(); |
1206 bool removed = lib.RemoveObject(function, name); | 1242 bool removed = lib.RemoveObject(function, name); |
1207 ASSERT(removed); | 1243 ASSERT(removed); |
1208 } | 1244 } |
1209 dropped_function_count_++; | 1245 dropped_function_count_++; |
1210 if (FLAG_trace_precompiler) { | 1246 if (FLAG_trace_precompiler) { |
1211 THR_Print("Precompilation dropping %s\n", | 1247 THR_Print("Dropping function %s\n", |
1212 function.ToLibNamePrefixedQualifiedCString()); | 1248 function.ToLibNamePrefixedQualifiedCString()); |
1213 } | 1249 } |
1214 } | 1250 } |
1215 } | 1251 } |
1216 | 1252 |
1217 if (retained_functions.Length() > 0) { | 1253 if (retained_functions.Length() > 0) { |
1218 functions = Array::MakeArray(retained_functions); | 1254 functions = Array::MakeArray(retained_functions); |
1219 cls.SetFunctions(functions); | 1255 cls.SetFunctions(functions); |
1220 } else { | 1256 } else { |
1221 cls.SetFunctions(Object::empty_array()); | 1257 cls.SetFunctions(Object::empty_array()); |
1222 } | 1258 } |
1223 } | 1259 } |
1224 } | 1260 } |
1225 | 1261 |
1226 closures = isolate()->object_store()->closure_functions(); | 1262 closures = isolate()->object_store()->closure_functions(); |
1227 retained_functions = GrowableObjectArray::New(); | 1263 retained_functions = GrowableObjectArray::New(); |
1228 for (intptr_t j = 0; j < closures.Length(); j++) { | 1264 for (intptr_t j = 0; j < closures.Length(); j++) { |
1229 function ^= closures.At(j); | 1265 function ^= closures.At(j); |
1230 bool retain = function.HasCode(); | 1266 bool retain = function.HasCode(); |
1231 if (retain) { | 1267 if (retain) { |
1232 retained_functions.Add(function); | 1268 retained_functions.Add(function); |
1233 AddTypesOf(function); | 1269 AddTypesOf(function); |
1234 } else { | 1270 } else { |
1235 dropped_function_count_++; | 1271 dropped_function_count_++; |
1236 if (FLAG_trace_precompiler) { | 1272 if (FLAG_trace_precompiler) { |
1237 THR_Print("Precompilation dropping %s\n", | 1273 THR_Print("Dropping function %s\n", |
1238 function.ToLibNamePrefixedQualifiedCString()); | 1274 function.ToLibNamePrefixedQualifiedCString()); |
1239 } | 1275 } |
1240 } | 1276 } |
1241 } | 1277 } |
1242 isolate()->object_store()->set_closure_functions(retained_functions); | 1278 isolate()->object_store()->set_closure_functions(retained_functions); |
1243 } | 1279 } |
1244 | 1280 |
1245 | 1281 |
1246 void Precompiler::DropFields() { | 1282 void Precompiler::DropFields() { |
1247 Library& lib = Library::Handle(Z); | 1283 Library& lib = Library::Handle(Z); |
(...skipping 24 matching lines...) Expand all Loading... |
1272 AddType(type); | 1308 AddType(type); |
1273 } else { | 1309 } else { |
1274 bool top_level = cls.IsTopLevel(); | 1310 bool top_level = cls.IsTopLevel(); |
1275 if (top_level) { | 1311 if (top_level) { |
1276 name = field.DictionaryName(); | 1312 name = field.DictionaryName(); |
1277 bool removed = lib.RemoveObject(field, name); | 1313 bool removed = lib.RemoveObject(field, name); |
1278 ASSERT(removed); | 1314 ASSERT(removed); |
1279 } | 1315 } |
1280 dropped_field_count_++; | 1316 dropped_field_count_++; |
1281 if (FLAG_trace_precompiler) { | 1317 if (FLAG_trace_precompiler) { |
1282 THR_Print("Precompilation dropping %s\n", | 1318 THR_Print("Dropping field %s\n", |
1283 field.ToCString()); | 1319 field.ToCString()); |
1284 } | 1320 } |
1285 } | 1321 } |
1286 } | 1322 } |
1287 | 1323 |
1288 if (retained_fields.Length() > 0) { | 1324 if (retained_fields.Length() > 0) { |
1289 fields = Array::MakeArray(retained_fields); | 1325 fields = Array::MakeArray(retained_fields); |
1290 cls.SetFields(fields); | 1326 cls.SetFields(fields); |
1291 } else { | 1327 } else { |
1292 cls.SetFields(Object::empty_array()); | 1328 cls.SetFields(Object::empty_array()); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 new_table.SetAt(dict_size, used); | 1419 new_table.SetAt(dict_size, used); |
1384 | 1420 |
1385 I->object_store()->set_canonical_type_arguments(new_table); | 1421 I->object_store()->set_canonical_type_arguments(new_table); |
1386 } | 1422 } |
1387 | 1423 |
1388 | 1424 |
1389 void Precompiler::TraceTypesFromRetainedClasses() { | 1425 void Precompiler::TraceTypesFromRetainedClasses() { |
1390 Library& lib = Library::Handle(Z); | 1426 Library& lib = Library::Handle(Z); |
1391 Class& cls = Class::Handle(Z); | 1427 Class& cls = Class::Handle(Z); |
1392 Array& members = Array::Handle(Z); | 1428 Array& members = Array::Handle(Z); |
| 1429 Array& constants = Array::Handle(Z); |
| 1430 GrowableObjectArray& retained_constants = GrowableObjectArray::Handle(Z); |
| 1431 Instance& constant = Instance::Handle(Z); |
1393 | 1432 |
1394 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1433 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
1395 lib ^= libraries_.At(i); | 1434 lib ^= libraries_.At(i); |
1396 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 1435 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
1397 while (it.HasNext()) { | 1436 while (it.HasNext()) { |
1398 cls = it.GetNextClass(); | 1437 cls = it.GetNextClass(); |
1399 if (cls.IsDynamicClass()) { | 1438 if (cls.IsDynamicClass()) { |
1400 continue; // class 'dynamic' is in the read-only VM isolate. | 1439 continue; // class 'dynamic' is in the read-only VM isolate. |
1401 } | 1440 } |
1402 | 1441 |
(...skipping 10 matching lines...) Expand all Loading... |
1413 retain = true; | 1452 retain = true; |
1414 } | 1453 } |
1415 if (cls.is_allocated()) { | 1454 if (cls.is_allocated()) { |
1416 retain = true; | 1455 retain = true; |
1417 } | 1456 } |
1418 if (cls.is_enum_class()) { | 1457 if (cls.is_enum_class()) { |
1419 // Enum classes have live instances, so we cannot unregister | 1458 // Enum classes have live instances, so we cannot unregister |
1420 // them. | 1459 // them. |
1421 retain = true; | 1460 retain = true; |
1422 } | 1461 } |
1423 members = cls.constants(); | 1462 |
1424 if (members.Length() > 0) { | 1463 constants = cls.constants(); |
1425 // --compile_all? | 1464 retained_constants = GrowableObjectArray::New(); |
| 1465 for (intptr_t j = 0; j < constants.Length(); j++) { |
| 1466 constant ^= constants.At(j); |
| 1467 bool retain = consts_to_retain_.Lookup(&constant) != NULL; |
| 1468 if (retain) { |
| 1469 retained_constants.Add(constant); |
| 1470 } |
| 1471 } |
| 1472 if (retained_constants.Length() > 0) { |
| 1473 constants = Array::MakeArray(retained_constants); |
| 1474 cls.set_constants(constants); |
| 1475 } else { |
| 1476 cls.set_constants(Object::empty_array()); |
| 1477 } |
| 1478 |
| 1479 if (constants.Length() > 0) { |
| 1480 ASSERT(retain); // This shouldn't be the reason we keep a class. |
1426 retain = true; | 1481 retain = true; |
1427 } | 1482 } |
1428 | 1483 |
1429 if (retain) { | 1484 if (retain) { |
1430 AddTypesOf(cls); | 1485 AddTypesOf(cls); |
1431 } | 1486 } |
1432 } | 1487 } |
1433 } | 1488 } |
1434 } | 1489 } |
1435 | 1490 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1485 class_table->StatsWithUpdatedSize(cid)->post_gc.old_count; | 1540 class_table->StatsWithUpdatedSize(cid)->post_gc.old_count; |
1486 if (instances != 0) { | 1541 if (instances != 0) { |
1487 FATAL2("Want to drop class %s, but it has %" Pd " instances\n", | 1542 FATAL2("Want to drop class %s, but it has %" Pd " instances\n", |
1488 cls.ToCString(), | 1543 cls.ToCString(), |
1489 instances); | 1544 instances); |
1490 } | 1545 } |
1491 #endif | 1546 #endif |
1492 | 1547 |
1493 dropped_class_count_++; | 1548 dropped_class_count_++; |
1494 if (FLAG_trace_precompiler) { | 1549 if (FLAG_trace_precompiler) { |
1495 THR_Print("Precompilation dropping %" Pd " %s\n", cid, cls.ToCString()); | 1550 THR_Print("Dropping class %" Pd " %s\n", cid, cls.ToCString()); |
1496 } | 1551 } |
1497 | 1552 |
1498 #if defined(DEBUG) | 1553 #if defined(DEBUG) |
1499 class_table->Unregister(cid); | 1554 class_table->Unregister(cid); |
1500 #endif | 1555 #endif |
1501 cls.set_id(kIllegalCid); // We check this when serializing. | 1556 cls.set_id(kIllegalCid); // We check this when serializing. |
1502 | 1557 |
1503 lib = cls.library(); | 1558 lib = cls.library(); |
1504 name = cls.DictionaryName(); | 1559 name = cls.DictionaryName(); |
1505 lib.RemoveObject(cls, name); | 1560 lib.RemoveObject(cls, name); |
(...skipping 16 matching lines...) Expand all Loading... |
1522 entries++; | 1577 entries++; |
1523 } | 1578 } |
1524 bool retain = (entries > 0) || lib.is_dart_scheme(); | 1579 bool retain = (entries > 0) || lib.is_dart_scheme(); |
1525 if (retain) { | 1580 if (retain) { |
1526 lib.set_index(retained_libraries.Length()); | 1581 lib.set_index(retained_libraries.Length()); |
1527 retained_libraries.Add(lib); | 1582 retained_libraries.Add(lib); |
1528 } else { | 1583 } else { |
1529 dropped_library_count_++; | 1584 dropped_library_count_++; |
1530 lib.set_index(-1); | 1585 lib.set_index(-1); |
1531 if (FLAG_trace_precompiler) { | 1586 if (FLAG_trace_precompiler) { |
1532 THR_Print("Precompilation dropping %s\n", lib.ToCString()); | 1587 THR_Print("Dropping library %s\n", lib.ToCString()); |
1533 } | 1588 } |
1534 } | 1589 } |
1535 } | 1590 } |
1536 | 1591 |
1537 I->object_store()->set_libraries(retained_libraries); | 1592 I->object_store()->set_libraries(retained_libraries); |
1538 libraries_ = retained_libraries.raw(); | 1593 libraries_ = retained_libraries.raw(); |
1539 } | 1594 } |
1540 | 1595 |
1541 | 1596 |
1542 void Precompiler::BindStaticCalls() { | 1597 void Precompiler::BindStaticCalls() { |
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 CompilationPipeline::New(thread->zone(), function); | 2595 CompilationPipeline::New(thread->zone(), function); |
2541 | 2596 |
2542 ASSERT(FLAG_precompiled_mode); | 2597 ASSERT(FLAG_precompiled_mode); |
2543 const bool optimized = function.IsOptimizable(); // False for natives. | 2598 const bool optimized = function.IsOptimizable(); // False for natives. |
2544 return PrecompileFunctionHelper(pipeline, function, optimized); | 2599 return PrecompileFunctionHelper(pipeline, function, optimized); |
2545 } | 2600 } |
2546 | 2601 |
2547 #endif // DART_PRECOMPILER | 2602 #endif // DART_PRECOMPILER |
2548 | 2603 |
2549 } // namespace dart | 2604 } // namespace dart |
OLD | NEW |