Disable VMRuntime_preloadDexCaches

For compiled code, we have largely moved to using .bss, so the
DexCache just costs us unnecessary extra space and dirty pages.

For interpreted code, the hashtables are too small and will be
overridden many times over at run-time regardless.

Test: device boots
Change-Id: I32bff875f3784e8bc0c7350be9b02c59216d234b
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 2abdd98..39b8aab 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -362,274 +362,9 @@
   Runtime::Current()->GetHeap()->GetTaskProcessor()->RunAllTasks(ThreadForEnv(env));
 }
 
-using StringTable = std::map<std::string, ObjPtr<mirror::String>>;
-
-class PreloadDexCachesStringsVisitor : public SingleRootVisitor {
- public:
-  explicit PreloadDexCachesStringsVisitor(StringTable* table) : table_(table) { }
-
-  void VisitRoot(mirror::Object* root, const RootInfo& info ATTRIBUTE_UNUSED)
-      override REQUIRES_SHARED(Locks::mutator_lock_) {
-    ObjPtr<mirror::String> string = root->AsString();
-    table_->operator[](string->ToModifiedUtf8()) = string;
-  }
-
- private:
-  StringTable* const table_;
-};
-
-// Based on ClassLinker::ResolveString.
-static void PreloadDexCachesResolveString(
-    ObjPtr<mirror::DexCache> dex_cache, dex::StringIndex string_idx, StringTable& strings)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  uint32_t slot_idx = dex_cache->StringSlotIndex(string_idx);
-  auto pair = dex_cache->GetStrings()[slot_idx].load(std::memory_order_relaxed);
-  if (!pair.object.IsNull()) {
-    return;  // The entry already contains some String.
-  }
-  const DexFile* dex_file = dex_cache->GetDexFile();
-  const char* utf8 = dex_file->StringDataByIdx(string_idx);
-  ObjPtr<mirror::String> string = strings[utf8];
-  if (string == nullptr) {
-    return;
-  }
-  dex_cache->SetResolvedString(string_idx, string);
+static void VMRuntime_preloadDexCaches(JNIEnv* env ATTRIBUTE_UNUSED, jobject) {
 }
 
-// Based on ClassLinker::ResolveType.
-static void PreloadDexCachesResolveType(Thread* self,
-                                        ObjPtr<mirror::DexCache> dex_cache,
-                                        dex::TypeIndex type_idx)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  uint32_t slot_idx = dex_cache->TypeSlotIndex(type_idx);
-  auto pair = dex_cache->GetResolvedTypes()[slot_idx].load(std::memory_order_relaxed);
-  if (!pair.object.IsNull()) {
-    return;  // The entry already contains some Class.
-  }
-  const DexFile* dex_file = dex_cache->GetDexFile();
-  const char* class_name = dex_file->StringByTypeIdx(type_idx);
-  ClassLinker* linker = Runtime::Current()->GetClassLinker();
-  ObjPtr<mirror::Class> klass = (class_name[1] == '\0')
-      ? linker->LookupPrimitiveClass(class_name[0])
-      : linker->LookupClass(self, class_name, nullptr);
-  if (klass == nullptr || !klass->IsResolved()) {
-    return;
-  }
-  dex_cache->SetResolvedType(type_idx, klass);
-}
-
-// Based on ClassLinker::ResolveField.
-static void PreloadDexCachesResolveField(ObjPtr<mirror::DexCache> dex_cache,
-                                         uint32_t field_idx,
-                                         bool is_static)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  uint32_t slot_idx = dex_cache->FieldSlotIndex(field_idx);
-  auto pair = mirror::DexCache::GetNativePairPtrSize(dex_cache->GetResolvedFields(),
-                                                     slot_idx,
-                                                     kRuntimePointerSize);
-  if (pair.object != nullptr) {
-    return;  // The entry already contains some ArtField.
-  }
-  const DexFile* dex_file = dex_cache->GetDexFile();
-  const dex::FieldId& field_id = dex_file->GetFieldId(field_idx);
-  ObjPtr<mirror::Class> klass = Runtime::Current()->GetClassLinker()->LookupResolvedType(
-      field_id.class_idx_, dex_cache, /* class_loader= */ nullptr);
-  if (klass == nullptr) {
-    return;
-  }
-  ArtField* field = is_static
-      ? mirror::Class::FindStaticField(Thread::Current(), klass, dex_cache, field_idx)
-      : klass->FindInstanceField(dex_cache, field_idx);
-  if (field == nullptr) {
-    return;
-  }
-  dex_cache->SetResolvedField(field_idx, field, kRuntimePointerSize);
-}
-
-// Based on ClassLinker::ResolveMethod.
-static void PreloadDexCachesResolveMethod(ObjPtr<mirror::DexCache> dex_cache, uint32_t method_idx)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  uint32_t slot_idx = dex_cache->MethodSlotIndex(method_idx);
-  auto pair = mirror::DexCache::GetNativePairPtrSize(dex_cache->GetResolvedMethods(),
-                                                     slot_idx,
-                                                     kRuntimePointerSize);
-  if (pair.object != nullptr) {
-    return;  // The entry already contains some ArtMethod.
-  }
-  const DexFile* dex_file = dex_cache->GetDexFile();
-  const dex::MethodId& method_id = dex_file->GetMethodId(method_idx);
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-
-  ObjPtr<mirror::Class> klass = class_linker->LookupResolvedType(
-      method_id.class_idx_, dex_cache, /* class_loader= */ nullptr);
-  if (klass == nullptr) {
-    return;
-  }
-  // Call FindResolvedMethod to populate the dex cache.
-  class_linker->FindResolvedMethod(klass, dex_cache, /* class_loader= */ nullptr, method_idx);
-}
-
-struct DexCacheStats {
-    uint32_t num_strings;
-    uint32_t num_types;
-    uint32_t num_fields;
-    uint32_t num_methods;
-    DexCacheStats() : num_strings(0),
-                      num_types(0),
-                      num_fields(0),
-                      num_methods(0) {}
-};
-
-static const bool kPreloadDexCachesEnabled = true;
-
-// Disabled because it takes a long time (extra half second) but
-// gives almost no benefit in terms of saving private dirty pages.
-static const bool kPreloadDexCachesStrings = false;
-
-static const bool kPreloadDexCachesTypes = true;
-static const bool kPreloadDexCachesFieldsAndMethods = true;
-
-static const bool kPreloadDexCachesCollectStats = true;
-
-static void PreloadDexCachesStatsTotal(DexCacheStats* total) {
-  if (!kPreloadDexCachesCollectStats) {
-    return;
-  }
-
-  ClassLinker* linker = Runtime::Current()->GetClassLinker();
-  const std::vector<const DexFile*>& boot_class_path = linker->GetBootClassPath();
-  for (size_t i = 0; i< boot_class_path.size(); i++) {
-    const DexFile* dex_file = boot_class_path[i];
-    CHECK(dex_file != nullptr);
-    total->num_strings += dex_file->NumStringIds();
-    total->num_fields += dex_file->NumFieldIds();
-    total->num_methods += dex_file->NumMethodIds();
-    total->num_types += dex_file->NumTypeIds();
-  }
-}
-
-static void PreloadDexCachesStatsFilled(DexCacheStats* filled)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  if (!kPreloadDexCachesCollectStats) {
-    return;
-  }
-  // TODO: Update for hash-based DexCache arrays.
-  ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
-  Thread* const self = Thread::Current();
-  for (const DexFile* dex_file : class_linker->GetBootClassPath()) {
-    CHECK(dex_file != nullptr);
-    // In fallback mode, not all boot classpath components might be registered, yet.
-    if (!class_linker->IsDexFileRegistered(self, *dex_file)) {
-      continue;
-    }
-    const ObjPtr<mirror::DexCache> dex_cache = class_linker->FindDexCache(self, *dex_file);
-    DCHECK(dex_cache != nullptr);  // Boot class path dex caches are never unloaded.
-    for (size_t j = 0, num_strings = dex_cache->NumStrings(); j < num_strings; ++j) {
-      auto pair = dex_cache->GetStrings()[j].load(std::memory_order_relaxed);
-      if (!pair.object.IsNull()) {
-        filled->num_strings++;
-      }
-    }
-    for (size_t j = 0, num_types = dex_cache->NumResolvedTypes(); j < num_types; ++j) {
-      auto pair = dex_cache->GetResolvedTypes()[j].load(std::memory_order_relaxed);
-      if (!pair.object.IsNull()) {
-        filled->num_types++;
-      }
-    }
-    for (size_t j = 0, num_fields = dex_cache->NumResolvedFields(); j < num_fields; ++j) {
-      auto pair = mirror::DexCache::GetNativePairPtrSize(dex_cache->GetResolvedFields(),
-                                                         j,
-                                                         kRuntimePointerSize);
-      if (pair.object != nullptr) {
-        filled->num_fields++;
-      }
-    }
-    for (size_t j = 0, num_methods = dex_cache->NumResolvedMethods(); j < num_methods; ++j) {
-      auto pair = mirror::DexCache::GetNativePairPtrSize(dex_cache->GetResolvedMethods(),
-                                                         j,
-                                                         kRuntimePointerSize);
-      if (pair.object != nullptr) {
-        filled->num_methods++;
-      }
-    }
-  }
-}
-
-// TODO: http://b/11309598 This code was ported over based on the
-// Dalvik version. However, ART has similar code in other places such
-// as the CompilerDriver. This code could probably be refactored to
-// serve both uses.
-static void VMRuntime_preloadDexCaches(JNIEnv* env, jobject) {
-  if (!kPreloadDexCachesEnabled) {
-    return;
-  }
-
-  ScopedObjectAccess soa(env);
-
-  DexCacheStats total;
-  DexCacheStats before;
-  if (kPreloadDexCachesCollectStats) {
-    LOG(INFO) << "VMRuntime.preloadDexCaches starting";
-    PreloadDexCachesStatsTotal(&total);
-    PreloadDexCachesStatsFilled(&before);
-  }
-
-  Runtime* runtime = Runtime::Current();
-  ClassLinker* linker = runtime->GetClassLinker();
-
-  // We use a std::map to avoid heap allocating StringObjects to lookup in gDvm.literalStrings
-  StringTable strings;
-  if (kPreloadDexCachesStrings) {
-    PreloadDexCachesStringsVisitor visitor(&strings);
-    runtime->GetInternTable()->VisitRoots(&visitor, kVisitRootFlagAllRoots);
-  }
-
-  const std::vector<const DexFile*>& boot_class_path = linker->GetBootClassPath();
-  for (size_t i = 0; i < boot_class_path.size(); i++) {
-    const DexFile* dex_file = boot_class_path[i];
-    CHECK(dex_file != nullptr);
-    ObjPtr<mirror::DexCache> dex_cache = linker->RegisterDexFile(*dex_file, nullptr);
-    CHECK(dex_cache != nullptr);  // Boot class path dex caches are never unloaded.
-    if (kPreloadDexCachesStrings) {
-      for (size_t j = 0; j < dex_cache->NumStrings(); j++) {
-        PreloadDexCachesResolveString(dex_cache, dex::StringIndex(j), strings);
-      }
-    }
-
-    if (kPreloadDexCachesTypes) {
-      for (size_t j = 0; j < dex_cache->NumResolvedTypes(); j++) {
-        PreloadDexCachesResolveType(soa.Self(), dex_cache, dex::TypeIndex(j));
-      }
-    }
-
-    if (kPreloadDexCachesFieldsAndMethods) {
-      for (ClassAccessor accessor : dex_file->GetClasses()) {
-        for (const ClassAccessor::Field& field : accessor.GetFields()) {
-          PreloadDexCachesResolveField(dex_cache, field.GetIndex(), field.IsStatic());
-        }
-        for (const ClassAccessor::Method& method : accessor.GetMethods()) {
-          PreloadDexCachesResolveMethod(dex_cache, method.GetIndex());
-        }
-      }
-    }
-  }
-
-  if (kPreloadDexCachesCollectStats) {
-    DexCacheStats after;
-    PreloadDexCachesStatsFilled(&after);
-    LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches strings total=%d before=%d after=%d",
-                              total.num_strings, before.num_strings, after.num_strings);
-    LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches types total=%d before=%d after=%d",
-                              total.num_types, before.num_types, after.num_types);
-    LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches fields total=%d before=%d after=%d",
-                              total.num_fields, before.num_fields, after.num_fields);
-    LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches methods total=%d before=%d after=%d",
-                              total.num_methods, before.num_methods, after.num_methods);
-    LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches finished");
-  }
-}
-
-
 /*
  * This is called by the framework when it knows the application directory and
  * process name.