Chromium Code Reviews| Index: runtime/vm/precompiler.cc |
| diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
| index b8bfc1898fab8195d08277bfe8bb93f404c7b67d..2bda728bafe5a3ebad5de30ae0dfae785a8a3563 100644 |
| --- a/runtime/vm/precompiler.cc |
| +++ b/runtime/vm/precompiler.cc |
| @@ -203,6 +203,12 @@ void Precompiler::DoCompileAll( |
| TraceTypesFromRetainedClasses(); |
| DropTypes(); |
| DropTypeArguments(); |
| + |
| + // Clear these before dropping classes as they may hold onto otherwise |
| + // dead instances of classes we will remove. |
| + I->object_store()->set_compile_time_constants(Array::null_array()); |
| + I->object_store()->set_unique_dynamic_targets(Array::null_array()); |
| + |
| DropClasses(); |
| DropLibraries(); |
| @@ -216,9 +222,6 @@ void Precompiler::DoCompileAll( |
| DedupInstructions(); |
| } |
| - I->object_store()->set_compile_time_constants(Array::null_array()); |
| - I->object_store()->set_unique_dynamic_targets(Array::null_array()); |
| - |
| zone_ = NULL; |
| } |
| @@ -1473,6 +1476,7 @@ void Precompiler::TraceTypesFromRetainedClasses() { |
| constants = Array::MakeArray(retained_constants); |
| cls.set_constants(constants); |
| } else { |
| + constants = Object::empty_array().raw(); |
| cls.set_constants(Object::empty_array()); |
| } |
| @@ -1492,14 +1496,17 @@ void Precompiler::TraceTypesFromRetainedClasses() { |
| void Precompiler::DropClasses() { |
| Library& lib = Library::Handle(Z); |
| Class& cls = Class::Handle(Z); |
| - Array& members = Array::Handle(Z); |
| + Array& constants = Array::Handle(Z); |
| String& name = String::Handle(Z); |
| #if defined(DEBUG) |
| - { |
| - // Force GC for allocation stats. |
| - I->heap()->CollectAllGarbage(); |
| - } |
| + // We are about to remove classes from the class table. For this to be safe, |
| + // there must be no instances of these classes on the heap, not even |
| + // corpses because the class table entry may be used to find the size of |
| + // corpses. Request a GC twice so we are sure the sweep tasks of the first |
| + // have completed before we continue. |
| + I->heap()->CollectAllGarbage(); |
| + I->heap()->CollectAllGarbage(); |
|
rmacnak
2016/03/08 23:57:27
Is there a better way to wait?
siva
2016/03/09 07:03:33
You could add a method in heap.h called WaitForSwe
rmacnak
2016/03/09 20:09:41
Added as debug-only.
|
| #endif |
| ClassTable* class_table = I->class_table(); |
| @@ -1518,22 +1525,16 @@ void Precompiler::DropClasses() { |
| // removed. |
| continue; |
| } |
| - if (cls.is_enum_class()) { |
| - // Enum classes have live instances, so we cannot unregister |
| - // them. |
| - continue; |
| - } |
| - members = cls.constants(); |
| - if (members.Length() > 0) { |
| - // --compile_all? |
| - continue; |
| - } |
| bool retain = classes_to_retain_.Lookup(&cls) != NULL; |
| if (retain) { |
| continue; |
| } |
| + ASSERT(!cls.is_allocated()); |
| + constants = cls.constants(); |
| + ASSERT(constants.Length() == 0); |
| + |
| #if defined(DEBUG) |
| intptr_t instances = |
| class_table->StatsWithUpdatedSize(cid)->post_gc.new_count + |