Revert "[vm, compiler] Prune dictionaries to only contain elements needed at runtime."

This reverts commit 6de162e014ebbfeb098620456de96bb729ac269d.

Reason for revert: Local testing of a large Flutter app with this change causes the app to crash on startup

Original change's description:
> [vm, compiler] Prune dictionaries to only contain elements needed at runtime.
>
> flutter_gallery
> Isolate(CodeSize): 2116400 -> 1981238 (-6.28%)
>   Total(CodeSize): 7217938 -> 7082600 (-1.87%)
>
> TEST=ci
> Bug: https://github.com/dart-lang/sdk/issues/48910
> Change-Id: I8cd285ddab3a611cd7a2a91d50414be402f8543a
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244303
> Reviewed-by: Siva Annamalai <asiva@google.com>
> Commit-Queue: Ryan Macnak <rmacnak@google.com>

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: https://github.com/dart-lang/sdk/issues/48910
Change-Id: Ie51f004e84970907fa1233e8e7c3ed63e2da1c4c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/246683
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index da71473..2b20b44 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -1873,12 +1873,12 @@
     // in the current loading unit).
     ObjectPoolPtr pool = code->untag()->object_pool_;
     if (s->kind() == Snapshot::kFullAOT) {
-      TracePool(s, pool, /*only_call_targets=*/is_deferred);
+      TracePool(s, pool, /*only_code=*/is_deferred);
     } else {
       if (s->InCurrentLoadingUnitOrRoot(pool)) {
         s->Push(pool);
       } else {
-        TracePool(s, pool, /*only_call_targets=*/true);
+        TracePool(s, pool, /*only_code=*/true);
       }
     }
 
@@ -1946,7 +1946,7 @@
 #endif
   }
 
-  void TracePool(Serializer* s, ObjectPoolPtr pool, bool only_call_targets) {
+  void TracePool(Serializer* s, ObjectPoolPtr pool, bool only_code) {
     if (pool == ObjectPool::null()) {
       return;
     }
@@ -1957,18 +1957,8 @@
       auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
       if (entry_type == ObjectPool::EntryType::kTaggedObject) {
         const ObjectPtr target = pool->untag()->data()[i].raw_obj_;
-        // A field is a call target because its initializer may be called
-        // indirectly by passing the field to the runtime. A const closure
-        // is a call target because its function may be called indirectly
-        // via a closure call.
-        if (!only_call_targets || target->IsCode() || target->IsFunction() ||
-            target->IsField() || target->IsClosure()) {
+        if (!only_code || target->IsCode()) {
           s->Push(target);
-        } else {
-          intptr_t cid = target->GetClassIdMayBeSmi();
-          if (cid >= kNumPredefinedCids) {
-            s->Push(s->isolate_group()->class_table()->At(cid));
-          }
         }
       }
     }
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 6c6a023..ee450a6 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -424,7 +424,6 @@
       typeparams_to_retain_(),
       consts_to_retain_(),
       seen_table_selectors_(),
-      api_uses_(),
       error_(Error::Handle()),
       get_runtime_type_is_unique_(false) {
   ASSERT(Precompiler::singleton_ == NULL);
@@ -663,8 +662,6 @@
       ProgramVisitor::Dedup(T);
     }
 
-    PruneDictionaries();
-
     if (retained_reasons_writer_ != nullptr) {
       reasons_writer.Write();
       retained_reasons_writer_ = nullptr;
@@ -755,7 +752,6 @@
     }
   }
   if (!main.IsNull()) {
-    AddApiUse(main);
     if (lib.LookupLocalFunction(name) == Function::null()) {
       retain_root_library_caches_ = true;
     }
@@ -1468,14 +1464,6 @@
   return seen_table_selectors_.HasKey(selector_id);
 }
 
-void Precompiler::AddApiUse(const Object& obj) {
-  api_uses_.Insert(&Object::ZoneHandle(Z, obj.ptr()));
-}
-
-bool Precompiler::HasApiUse(const Object& obj) {
-  return api_uses_.HasKey(&obj);
-}
-
 void Precompiler::AddInstantiatedClass(const Class& cls) {
   if (is_tracing()) {
     tracer_->WriteClassInstantiationRef(cls);
@@ -1535,7 +1523,6 @@
                                  &reusable_object_handle) ==
             EntryPointPragma::kAlways) {
           AddInstantiatedClass(cls);
-          AddApiUse(cls);
         }
       }
 
@@ -1554,7 +1541,6 @@
           if (pragma == EntryPointPragma::kNever) continue;
 
           AddField(field);
-          AddApiUse(field);
 
           if (!field.is_static()) {
             if (pragma != EntryPointPragma::kSetterOnly) {
@@ -1583,7 +1569,6 @@
               type == EntryPointPragma::kCallOnly) {
             functions_with_entry_point_pragmas_.Insert(function);
             AddFunction(function, RetainReasons::kEntryPointPragma);
-            AddApiUse(function);
           }
 
           if ((type == EntryPointPragma::kAlways ||
@@ -1593,16 +1578,10 @@
             function2 = function.ImplicitClosureFunction();
             functions_with_entry_point_pragmas_.Insert(function2);
             AddFunction(function2, RetainReasons::kEntryPointPragma);
-
-            // Not `function2`: Dart_GetField will lookup the regular function
-            // and get the implicit closure function from that.
-            AddApiUse(function);
           }
 
           if (function.IsGenerativeConstructor()) {
             AddInstantiatedClass(cls);
-            AddApiUse(function);
-            AddApiUse(cls);
           }
         }
         if (function.kind() == UntaggedFunction::kImplicitGetter &&
@@ -1612,7 +1591,6 @@
             if (function.accessor_field() == field.ptr()) {
               functions_with_entry_point_pragmas_.Insert(function);
               AddFunction(function, RetainReasons::kImplicitGetter);
-              AddApiUse(function);
             }
           }
         }
@@ -1623,7 +1601,6 @@
             if (function.accessor_field() == field.ptr()) {
               functions_with_entry_point_pragmas_.Insert(function);
               AddFunction(function, RetainReasons::kImplicitSetter);
-              AddApiUse(function);
             }
           }
         }
@@ -1634,15 +1611,9 @@
             if (function.accessor_field() == field.ptr()) {
               functions_with_entry_point_pragmas_.Insert(function);
               AddFunction(function, RetainReasons::kImplicitStaticGetter);
-              AddApiUse(function);
             }
           }
         }
-        if (function.is_native()) {
-          // The embedder will need to lookup this library to provide the native
-          // resolver, even if there are no embedder calls into the library.
-          AddApiUse(lib);
-        }
       }
 
       implicit_getters = GrowableObjectArray::null();
@@ -3098,166 +3069,6 @@
   }
 }
 
-void Precompiler::PruneDictionaries() {
-  // PRODUCT-only: pruning interferes with various uses of the service protocol,
-  // including heap analysis tools.
-#if defined(PRODUCT)
-  class PruneDictionariesVisitor {
-   public:
-    GrowableObjectArrayPtr PruneLibraries(
-        const GrowableObjectArray& libraries) {
-      for (intptr_t i = 0; i < libraries.Length(); i++) {
-        lib_ ^= libraries.At(i);
-        bool retain = PruneLibrary(lib_);
-        if (retain) {
-          lib_.set_index(retained_libraries_.Length());
-          retained_libraries_.Add(lib_);
-        } else {
-          lib_.set_index(-1);
-          lib_.set_private_key(null_string_);
-        }
-      }
-
-      Library::RegisterLibraries(Thread::Current(), retained_libraries_);
-      return retained_libraries_.ptr();
-    }
-
-    bool PruneLibrary(const Library& lib) {
-      dict_ = lib.dictionary();
-      intptr_t dict_size = dict_.Length() - 1;
-      intptr_t used = 0;
-      for (intptr_t i = 0; i < dict_size; i++) {
-        entry_ = dict_.At(i);
-        if (entry_.IsNull()) continue;
-
-        bool retain = false;
-        if (entry_.IsClass()) {
-          // dart:async: Fix async stack trace lookups in dart:async to annotate
-          // entry points or fail gracefully.
-          // dart:core, dart:collection, dart:typed_data: Isolate messaging
-          // between groups allows any class in these libraries.
-          retain = PruneClass(Class::Cast(entry_)) ||
-                   (lib.url() == Symbols::DartAsync().ptr()) ||
-                   (lib.url() == Symbols::DartCore().ptr()) ||
-                   (lib.url() == Symbols::DartCollection().ptr()) ||
-                   (lib.url() == Symbols::DartTypedData().ptr());
-        } else if (entry_.IsFunction() || entry_.IsField()) {
-          retain = precompiler_->HasApiUse(entry_);
-        } else {
-          FATAL("Unexpected library entry: %s", entry_.ToCString());
-        }
-        if (retain) {
-          used++;
-        } else {
-          dict_.SetAt(i, Object::null_object());
-        }
-      }
-      lib.RehashDictionary(dict_, used * 4 / 3 + 1);
-
-      bool retain = used > 0;
-      cls_ = lib.toplevel_class();
-      if (PruneClass(cls_)) {
-        retain = true;
-      }
-      if (lib.is_dart_scheme()) {
-        retain = true;
-      }
-      if (lib.ptr() == root_lib_.ptr()) {
-        retain = true;
-      }
-      if (precompiler_->HasApiUse(lib)) {
-        retain = true;
-      }
-      return retain;
-    }
-
-    bool PruneClass(const Class& cls) {
-      bool retain = precompiler_->HasApiUse(cls);
-
-      functions_ = cls.functions();
-      retained_functions_ = GrowableObjectArray::New();
-      for (intptr_t i = 0; i < functions_.Length(); i++) {
-        function_ ^= functions_.At(i);
-        if (precompiler_->HasApiUse(function_)) {
-          retained_functions_.Add(function_);
-          retain = true;
-        } else if (precompiler_->functions_called_dynamically_.ContainsKey(
-                       function_)) {
-          retained_functions_.Add(function_);
-          // No `retain = true`: the function must appear in the method
-          // dictionary for lookup, but the class may still be removed from the
-          // library.
-        }
-      }
-      if (retained_functions_.Length() > 0) {
-        functions_ = Array::MakeFixedLength(retained_functions_);
-        cls.SetFunctions(functions_);
-      } else {
-        cls.SetFunctions(Object::empty_array());
-      }
-
-      fields_ = cls.fields();
-      retained_fields_ = GrowableObjectArray::New();
-      for (intptr_t i = 0; i < fields_.Length(); i++) {
-        field_ ^= fields_.At(i);
-        if (precompiler_->HasApiUse(field_)) {
-          retained_fields_.Add(field_);
-          retain = true;
-        }
-      }
-      if (retained_fields_.Length() > 0) {
-        fields_ = Array::MakeFixedLength(retained_fields_);
-        cls.SetFields(fields_);
-      } else {
-        cls.SetFields(Object::empty_array());
-      }
-
-      return retain;
-    }
-
-    explicit PruneDictionariesVisitor(Precompiler* precompiler, Zone* zone)
-        : precompiler_(precompiler),
-          lib_(Library::Handle(zone)),
-          dict_(Array::Handle(zone)),
-          entry_(Object::Handle(zone)),
-          cls_(Class::Handle(zone)),
-          functions_(Array::Handle(zone)),
-          fields_(Array::Handle(zone)),
-          function_(Function::Handle(zone)),
-          field_(Field::Handle(zone)),
-          retained_functions_(GrowableObjectArray::Handle(zone)),
-          retained_fields_(GrowableObjectArray::Handle(zone)),
-          retained_libraries_(
-              GrowableObjectArray::Handle(zone, GrowableObjectArray::New())),
-          root_lib_(Library::Handle(
-              zone,
-              precompiler->isolate_group()->object_store()->root_library())),
-          null_string_(String::Handle(zone)) {}
-
-   private:
-    Precompiler* const precompiler_;
-    Library& lib_;
-    Array& dict_;
-    Object& entry_;
-    Class& cls_;
-    Array& functions_;
-    Array& fields_;
-    Function& function_;
-    Field& field_;
-    GrowableObjectArray& retained_functions_;
-    GrowableObjectArray& retained_fields_;
-    const GrowableObjectArray& retained_libraries_;
-    const Library& root_lib_;
-    const String& null_string_;
-  };
-
-  HANDLESCOPE(T);
-  SafepointWriteRwLocker ml(T, T->isolate_group()->program_lock());
-  PruneDictionariesVisitor visitor(this, Z);
-  libraries_ = visitor.PruneLibraries(libraries_);
-#endif  // defined(PRODUCT)
-}
-
 // Traits for the HashTable template.
 struct CodeKeyTraits {
   static uint32_t Hash(const Object& key) { return Code::Cast(key).Size(); }
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 50df9e7..4e0d211 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -210,37 +210,6 @@
 
 typedef DirectChainedHashMap<TypeArgumentsKeyValueTrait> TypeArgumentsSet;
 
-class ProgramElementKeyValueTrait {
- public:
-  // Typedefs needed for the DirectChainedHashMap template.
-  typedef const Object* Key;
-  typedef const Object* Value;
-  typedef const Object* Pair;
-
-  static Key KeyOf(Pair kv) { return kv; }
-
-  static Value ValueOf(Pair kv) { return kv; }
-
-  static inline uword Hash(Key key) {
-    if (key->IsFunction()) {
-      return Function::Cast(*key).Hash();
-    } else if (key->IsField()) {
-      return Field::Cast(*key).kernel_offset();
-    } else if (key->IsClass()) {
-      return Class::Cast(*key).kernel_offset();
-    } else if (key->IsLibrary()) {
-      return Library::Cast(*key).index();
-    }
-    FATAL("Unexpected type: %s\n", key->ToCString());
-  }
-
-  static inline bool IsKeyEqual(Pair pair, Key key) {
-    return pair->ptr() == key->ptr();
-  }
-};
-
-typedef DirectChainedHashMap<ProgramElementKeyValueTrait> ProgramElementSet;
-
 class InstanceKeyValueTrait {
  public:
   // Typedefs needed for the DirectChainedHashMap template.
@@ -352,8 +321,6 @@
   bool IsHitByTableSelector(const Function& function);
   // Returns the reason if the function must be retained, otherwise nullptr.
   const char* MustRetainFunction(const Function& function);
-  void AddApiUse(const Object& obj);
-  bool HasApiUse(const Object& obj);
 
   void ProcessFunction(const Function& function);
   void CheckForNewDynamicFunctions();
@@ -376,7 +343,6 @@
   void DropClasses();
   void DropLibraries();
   void DiscardCodeObjects();
-  void PruneDictionaries();
 
   DEBUG_ONLY(FunctionPtr FindUnvisitedRetainedFunction());
 
@@ -427,7 +393,6 @@
   TypeParameterSet typeparams_to_retain_;
   InstanceSet consts_to_retain_;
   TableSelectorSet seen_table_selectors_;
-  ProgramElementSet api_uses_;
   Error& error_;
 
   compiler::DispatchTableGenerator* dispatch_table_generator_;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 7dba48a..d52cc58 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1891,11 +1891,9 @@
   Zone* zone = thread->zone();
   intptr_t unit_count = helper_->ReadUInt();
   Array& loading_units = Array::Handle(zone, Array::New(unit_count + 1));
-  Array& loading_unit_uris = Array::Handle(zone, Array::New(unit_count + 1));
   LoadingUnit& unit = LoadingUnit::Handle(zone);
   LoadingUnit& parent = LoadingUnit::Handle(zone);
   Library& lib = Library::Handle(zone);
-  Array& uris = Array::Handle(zone);
 
   for (int i = 0; i < unit_count; i++) {
     intptr_t id = helper_->ReadUInt();
@@ -1909,7 +1907,6 @@
     unit.set_parent(parent);
 
     intptr_t library_count = helper_->ReadUInt();
-    uris = Array::New(library_count);
     for (intptr_t j = 0; j < library_count; j++) {
       const String& uri =
           translation_helper_.DartSymbolPlain(helper_->ReadStringReference());
@@ -1918,18 +1915,14 @@
         FATAL1("Missing library: %s\n", uri.ToCString());
       }
       lib.set_loading_unit(unit);
-      uris.SetAt(j, uri);
     }
 
     loading_units.SetAt(id, unit);
-    loading_unit_uris.SetAt(id, uris);
   }
 
   ObjectStore* object_store = IG->object_store();
   ASSERT(object_store->loading_units() == Array::null());
   object_store->set_loading_units(loading_units);
-  ASSERT(object_store->loading_unit_uris() == Array::null());
-  object_store->set_loading_unit_uris(loading_unit_uris);
 }
 
 CallSiteAttributesMetadataHelper::CallSiteAttributesMetadataHelper(
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index f8b05d2..4f03fb7a 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6728,12 +6728,24 @@
   DARTSCOPE(Thread::Current());
   API_TIMELINE_DURATION(T);
 
-  const Array& loading_units =
-      Array::Handle(Z, T->isolate_group()->object_store()->loading_unit_uris());
-  if (loading_unit_id >= 0 && loading_unit_id < loading_units.Length()) {
-    return Api::NewHandle(T, loading_units.At(loading_unit_id));
+  const GrowableObjectArray& result =
+      GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+  const GrowableObjectArray& libs = GrowableObjectArray::Handle(
+      Z, T->isolate_group()->object_store()->libraries());
+  Library& lib = Library::Handle(Z);
+  LoadingUnit& unit = LoadingUnit::Handle(Z);
+  String& uri = String::Handle(Z);
+  for (intptr_t i = 0; i < libs.Length(); i++) {
+    lib ^= libs.At(i);
+    unit = lib.loading_unit();
+    if (unit.IsNull() || (unit.id() != loading_unit_id)) {
+      continue;
+    }
+    uri = lib.url();
+    result.Add(uri);
   }
-  return Api::NewError("Invalid loading_unit_id");
+
+  return Api::NewHandle(T, Array::MakeFixedLength(result));
 #endif
 }
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 9e867c4..46d3e1b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -12448,12 +12448,8 @@
   untag()->set_name(name.ptr());
 }
 
-void Library::set_url(const String& url) const {
-  untag()->set_url(url.ptr());
-}
-
-void Library::set_private_key(const String& key) const {
-  untag()->set_private_key(key.ptr());
+void Library::set_url(const String& name) const {
+  untag()->set_url(name.ptr());
 }
 
 void Library::set_kernel_data(const ExternalTypedData& data) const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index dd1699a..6f226c3 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -5109,7 +5109,6 @@
   // the name and url.
   void set_name(const String& name) const;
   void set_url(const String& url) const;
-  void set_private_key(const String& key) const;
 
   void set_num_imports(intptr_t value) const;
   void set_flags(uint8_t flags) const;
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 718e61d..674d1b4 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -261,7 +261,6 @@
   RW(Array, dispatch_table_code_entries)                                       \
   RW(GrowableObjectArray, instructions_tables)                                 \
   RW(Array, obfuscation_map)                                                   \
-  RW(Array, loading_unit_uris)                                                 \
   RW(GrowableObjectArray, ffi_callback_functions)                              \
   RW(Class, ffi_pointer_class)                                                 \
   RW(Class, ffi_native_type_class)                                             \
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index a70896e..d0bddf8 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -2543,7 +2543,6 @@
 }
 
 @patch
-@pragma("vm:entry-point")
 class ResourceHandle {
   factory ResourceHandle.fromFile(RandomAccessFile file) {
     int fd = (file as _RandomAccessFile).fd;