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