| Index: runtime/vm/precompiler.cc
|
| diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
|
| index f7b46ed0a6d64fc531b86d3f467ea78c10f60023..fcd03921bda6c82ec9e66dbf2d9e6eeb9abd6527 100644
|
| --- a/runtime/vm/precompiler.cc
|
| +++ b/runtime/vm/precompiler.cc
|
| @@ -495,6 +495,7 @@ void Precompiler::DoCompileAll(
|
| I->object_store()->set_async_star_move_next_helper(null_function);
|
| I->object_store()->set_complete_on_async_return(null_function);
|
| I->object_store()->set_async_star_stream_controller(null_class);
|
| + DropLibraryEntries();
|
| }
|
| DropClasses();
|
| DropLibraries();
|
| @@ -1711,7 +1712,6 @@ void Precompiler::DropFunctions() {
|
| Function& function = Function::Handle(Z);
|
| GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z);
|
| GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
|
| - String& name = String::Handle(Z);
|
|
|
| for (intptr_t i = 0; i < libraries_.Length(); i++) {
|
| lib ^= libraries_.At(i);
|
| @@ -1731,15 +1731,6 @@ void Precompiler::DropFunctions() {
|
| if (retain) {
|
| retained_functions.Add(function);
|
| } else {
|
| - bool top_level = cls.IsTopLevel();
|
| - if (top_level &&
|
| - (function.kind() != RawFunction::kImplicitStaticFinalGetter)) {
|
| - // Implicit static final getters are not added to the library
|
| - // dictionary in the first place.
|
| - name = function.DictionaryName();
|
| - bool removed = lib.RemoveObject(function, name);
|
| - ASSERT(removed);
|
| - }
|
| dropped_function_count_++;
|
| if (FLAG_trace_precompiler) {
|
| THR_Print("Dropping function %s\n",
|
| @@ -1782,7 +1773,6 @@ void Precompiler::DropFields() {
|
| Array& fields = Array::Handle(Z);
|
| Field& field = Field::Handle(Z);
|
| GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z);
|
| - String& name = String::Handle(Z);
|
| AbstractType& type = AbstractType::Handle(Z);
|
|
|
| for (intptr_t i = 0; i < libraries_.Length(); i++) {
|
| @@ -1804,11 +1794,6 @@ void Precompiler::DropFields() {
|
| type = field.type();
|
| AddType(type);
|
| } else {
|
| - bool top_level = cls.IsTopLevel();
|
| - if (top_level) {
|
| - name = field.DictionaryName();
|
| - lib.RemoveObject(field, name);
|
| - }
|
| dropped_field_count_++;
|
| if (FLAG_trace_precompiler) {
|
| THR_Print("Dropping field %s\n", field.ToCString());
|
| @@ -1995,11 +1980,52 @@ void Precompiler::TraceTypesFromRetainedClasses() {
|
| }
|
|
|
|
|
| -void Precompiler::DropClasses() {
|
| +void Precompiler::DropLibraryEntries() {
|
| Library& lib = Library::Handle(Z);
|
| + Array& dict = Array::Handle(Z);
|
| + Object& entry = Object::Handle(Z);
|
| +
|
| + for (intptr_t i = 0; i < libraries_.Length(); i++) {
|
| + lib ^= libraries_.At(i);
|
| +
|
| + dict = lib.dictionary();
|
| + intptr_t dict_size = dict.Length() - 1;
|
| + intptr_t used = 0;
|
| + for (intptr_t j = 0; j < dict_size; j++) {
|
| + entry = dict.At(j);
|
| + if (entry.IsNull()) continue;
|
| +
|
| + if (entry.IsClass()) {
|
| + if (classes_to_retain_.HasKey(&Class::Cast(entry))) {
|
| + used++;
|
| + continue;
|
| + }
|
| + } else if (entry.IsFunction()) {
|
| + if (functions_to_retain_.HasKey(&Function::Cast(entry))) {
|
| + used++;
|
| + continue;
|
| + }
|
| + } else if (entry.IsField()) {
|
| + if (fields_to_retain_.HasKey(&Field::Cast(entry))) {
|
| + used++;
|
| + continue;
|
| + }
|
| + } else if (entry.IsLibraryPrefix()) {
|
| + // Always drop.
|
| + } else {
|
| + FATAL1("Unexpected library entry: %s", entry.ToCString());
|
| + }
|
| + dict.SetAt(j, Object::null_object());
|
| + }
|
| + lib.RehashDictionary(dict, used * 4 / 3 + 1);
|
| + lib.DropDependenciesAndCaches();
|
| + }
|
| +}
|
| +
|
| +
|
| +void Precompiler::DropClasses() {
|
| Class& cls = Class::Handle(Z);
|
| Array& constants = Array::Handle(Z);
|
| - String& name = String::Handle(Z);
|
|
|
| #if defined(DEBUG)
|
| // We are about to remove classes from the class table. For this to be safe,
|
| @@ -2056,10 +2082,6 @@ void Precompiler::DropClasses() {
|
| class_table->Unregister(cid);
|
| #endif
|
| cls.set_id(kIllegalCid); // We check this when serializing.
|
| -
|
| - lib = cls.library();
|
| - name = cls.DictionaryName();
|
| - lib.RemoveObject(cls, name);
|
| }
|
| }
|
|
|
| @@ -2070,15 +2092,15 @@ void Precompiler::DropLibraries() {
|
| const Library& root_lib =
|
| Library::Handle(Z, I->object_store()->root_library());
|
| Library& lib = Library::Handle(Z);
|
| + Class& toplevel_class = Class::Handle(Z);
|
|
|
| for (intptr_t i = 0; i < libraries_.Length(); i++) {
|
| lib ^= libraries_.At(i);
|
| - lib.DropDependencies();
|
| intptr_t entries = 0;
|
| DictionaryIterator it(lib);
|
| while (it.HasNext()) {
|
| - it.GetNext();
|
| entries++;
|
| + it.GetNext();
|
| }
|
| bool retain = false;
|
| if (entries > 0) {
|
| @@ -2094,8 +2116,8 @@ void Precompiler::DropLibraries() {
|
| } else {
|
| // A type for a top-level class may be referenced from an object pool as
|
| // part of an error message.
|
| - const Class& top = Class::Handle(Z, lib.toplevel_class());
|
| - if (classes_to_retain_.HasKey(&top)) {
|
| + toplevel_class = lib.toplevel_class();
|
| + if (classes_to_retain_.HasKey(&toplevel_class)) {
|
| retain = true;
|
| }
|
| }
|
| @@ -2104,6 +2126,12 @@ void Precompiler::DropLibraries() {
|
| lib.set_index(retained_libraries.Length());
|
| retained_libraries.Add(lib);
|
| } else {
|
| + toplevel_class = lib.toplevel_class();
|
| +#if defined(DEBUG)
|
| + I->class_table()->Unregister(toplevel_class.id());
|
| +#endif
|
| + toplevel_class.set_id(kIllegalCid); // We check this when serializing.
|
| +
|
| dropped_library_count_++;
|
| lib.set_index(-1);
|
| if (FLAG_trace_precompiler) {
|
|
|