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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 Iterate(); | 196 Iterate(); |
197 } | 197 } |
198 | 198 |
199 I->set_compilation_allowed(false); | 199 I->set_compilation_allowed(false); |
200 | 200 |
201 DropFunctions(); | 201 DropFunctions(); |
202 DropFields(); | 202 DropFields(); |
203 TraceTypesFromRetainedClasses(); | 203 TraceTypesFromRetainedClasses(); |
204 DropTypes(); | 204 DropTypes(); |
205 DropTypeArguments(); | 205 DropTypeArguments(); |
| 206 |
| 207 // Clear these before dropping classes as they may hold onto otherwise |
| 208 // dead instances of classes we will remove. |
| 209 I->object_store()->set_compile_time_constants(Array::null_array()); |
| 210 I->object_store()->set_unique_dynamic_targets(Array::null_array()); |
| 211 |
206 DropClasses(); | 212 DropClasses(); |
207 DropLibraries(); | 213 DropLibraries(); |
208 | 214 |
209 BindStaticCalls(); | 215 BindStaticCalls(); |
210 | 216 |
211 DedupStackmaps(); | 217 DedupStackmaps(); |
212 DedupStackmapLists(); | 218 DedupStackmapLists(); |
213 | 219 |
214 if (FLAG_dedup_instructions) { | 220 if (FLAG_dedup_instructions) { |
215 // Reduces binary size but obfuscates profiler results. | 221 // Reduces binary size but obfuscates profiler results. |
216 DedupInstructions(); | 222 DedupInstructions(); |
217 } | 223 } |
218 | 224 |
219 I->object_store()->set_compile_time_constants(Array::null_array()); | |
220 I->object_store()->set_unique_dynamic_targets(Array::null_array()); | |
221 | |
222 zone_ = NULL; | 225 zone_ = NULL; |
223 } | 226 } |
224 | 227 |
225 intptr_t dropped_symbols_count = Symbols::Compact(I); | 228 intptr_t dropped_symbols_count = Symbols::Compact(I); |
226 | 229 |
227 if (FLAG_trace_precompiler) { | 230 if (FLAG_trace_precompiler) { |
228 THR_Print("Precompiled %" Pd " functions,", function_count_); | 231 THR_Print("Precompiled %" Pd " functions,", function_count_); |
229 THR_Print(" %" Pd " dynamic types,", class_count_); | 232 THR_Print(" %" Pd " dynamic types,", class_count_); |
230 THR_Print(" %" Pd " dynamic selectors.\n", selector_count_); | 233 THR_Print(" %" Pd " dynamic selectors.\n", selector_count_); |
231 | 234 |
(...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1466 constant ^= constants.At(j); | 1469 constant ^= constants.At(j); |
1467 bool retain = consts_to_retain_.Lookup(&constant) != NULL; | 1470 bool retain = consts_to_retain_.Lookup(&constant) != NULL; |
1468 if (retain) { | 1471 if (retain) { |
1469 retained_constants.Add(constant); | 1472 retained_constants.Add(constant); |
1470 } | 1473 } |
1471 } | 1474 } |
1472 if (retained_constants.Length() > 0) { | 1475 if (retained_constants.Length() > 0) { |
1473 constants = Array::MakeArray(retained_constants); | 1476 constants = Array::MakeArray(retained_constants); |
1474 cls.set_constants(constants); | 1477 cls.set_constants(constants); |
1475 } else { | 1478 } else { |
| 1479 constants = Object::empty_array().raw(); |
1476 cls.set_constants(Object::empty_array()); | 1480 cls.set_constants(Object::empty_array()); |
1477 } | 1481 } |
1478 | 1482 |
1479 if (constants.Length() > 0) { | 1483 if (constants.Length() > 0) { |
1480 ASSERT(retain); // This shouldn't be the reason we keep a class. | 1484 ASSERT(retain); // This shouldn't be the reason we keep a class. |
1481 retain = true; | 1485 retain = true; |
1482 } | 1486 } |
1483 | 1487 |
1484 if (retain) { | 1488 if (retain) { |
1485 AddTypesOf(cls); | 1489 AddTypesOf(cls); |
1486 } | 1490 } |
1487 } | 1491 } |
1488 } | 1492 } |
1489 } | 1493 } |
1490 | 1494 |
1491 | 1495 |
1492 void Precompiler::DropClasses() { | 1496 void Precompiler::DropClasses() { |
1493 Library& lib = Library::Handle(Z); | 1497 Library& lib = Library::Handle(Z); |
1494 Class& cls = Class::Handle(Z); | 1498 Class& cls = Class::Handle(Z); |
1495 Array& members = Array::Handle(Z); | 1499 Array& constants = Array::Handle(Z); |
1496 String& name = String::Handle(Z); | 1500 String& name = String::Handle(Z); |
1497 | 1501 |
1498 #if defined(DEBUG) | 1502 #if defined(DEBUG) |
1499 { | 1503 // We are about to remove classes from the class table. For this to be safe, |
1500 // Force GC for allocation stats. | 1504 // there must be no instances of these classes on the heap, not even |
1501 I->heap()->CollectAllGarbage(); | 1505 // corpses because the class table entry may be used to find the size of |
1502 } | 1506 // corpses. Request a full GC and wait for the sweeper tasks to finish before |
| 1507 // we continue. |
| 1508 I->heap()->CollectAllGarbage(); |
| 1509 I->heap()->WaitForSweeperTasks(); |
1503 #endif | 1510 #endif |
1504 | 1511 |
1505 ClassTable* class_table = I->class_table(); | 1512 ClassTable* class_table = I->class_table(); |
1506 intptr_t num_cids = class_table->NumCids(); | 1513 intptr_t num_cids = class_table->NumCids(); |
1507 | 1514 |
1508 for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) { | 1515 for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) { |
1509 if (!class_table->IsValidIndex(cid)) continue; | 1516 if (!class_table->IsValidIndex(cid)) continue; |
1510 if (!class_table->HasValidClassAt(cid)) continue; | 1517 if (!class_table->HasValidClassAt(cid)) continue; |
1511 | 1518 |
1512 cls = class_table->At(cid); | 1519 cls = class_table->At(cid); |
1513 ASSERT(!cls.IsNull()); | 1520 ASSERT(!cls.IsNull()); |
1514 | 1521 |
1515 if (cls.IsTopLevel()) { | 1522 if (cls.IsTopLevel()) { |
1516 // Top-level classes are referenced directly from their library. They | 1523 // Top-level classes are referenced directly from their library. They |
1517 // will only be removed as a consequence of an entire library being | 1524 // will only be removed as a consequence of an entire library being |
1518 // removed. | 1525 // removed. |
1519 continue; | 1526 continue; |
1520 } | 1527 } |
1521 if (cls.is_enum_class()) { | |
1522 // Enum classes have live instances, so we cannot unregister | |
1523 // them. | |
1524 continue; | |
1525 } | |
1526 members = cls.constants(); | |
1527 if (members.Length() > 0) { | |
1528 // --compile_all? | |
1529 continue; | |
1530 } | |
1531 | 1528 |
1532 bool retain = classes_to_retain_.Lookup(&cls) != NULL; | 1529 bool retain = classes_to_retain_.Lookup(&cls) != NULL; |
1533 if (retain) { | 1530 if (retain) { |
1534 continue; | 1531 continue; |
1535 } | 1532 } |
1536 | 1533 |
| 1534 ASSERT(!cls.is_allocated()); |
| 1535 constants = cls.constants(); |
| 1536 ASSERT(constants.Length() == 0); |
| 1537 |
1537 #if defined(DEBUG) | 1538 #if defined(DEBUG) |
1538 intptr_t instances = | 1539 intptr_t instances = |
1539 class_table->StatsWithUpdatedSize(cid)->post_gc.new_count + | 1540 class_table->StatsWithUpdatedSize(cid)->post_gc.new_count + |
1540 class_table->StatsWithUpdatedSize(cid)->post_gc.old_count; | 1541 class_table->StatsWithUpdatedSize(cid)->post_gc.old_count; |
1541 if (instances != 0) { | 1542 if (instances != 0) { |
1542 FATAL2("Want to drop class %s, but it has %" Pd " instances\n", | 1543 FATAL2("Want to drop class %s, but it has %" Pd " instances\n", |
1543 cls.ToCString(), | 1544 cls.ToCString(), |
1544 instances); | 1545 instances); |
1545 } | 1546 } |
1546 #endif | 1547 #endif |
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2595 CompilationPipeline::New(thread->zone(), function); | 2596 CompilationPipeline::New(thread->zone(), function); |
2596 | 2597 |
2597 ASSERT(FLAG_precompiled_mode); | 2598 ASSERT(FLAG_precompiled_mode); |
2598 const bool optimized = function.IsOptimizable(); // False for natives. | 2599 const bool optimized = function.IsOptimizable(); // False for natives. |
2599 return PrecompileFunctionHelper(pipeline, function, optimized); | 2600 return PrecompileFunctionHelper(pipeline, function, optimized); |
2600 } | 2601 } |
2601 | 2602 |
2602 #endif // DART_PRECOMPILER | 2603 #endif // DART_PRECOMPILER |
2603 | 2604 |
2604 } // namespace dart | 2605 } // namespace dart |
OLD | NEW |