Optimize FetchAndCacheResolvedClassesAndMethods

Moved FetchAndCacheResolvedClassesAndMethods to use a newly added
memory efficient DexReferenceCollection. This reduces RAM by
6+ bytes per sampled method during the process.

Changed profile logic to use bulk adding for each dex file instead
of looping through all of the ids and doing a string map comparison
for each one.

Also moved the vectors to use arena allocators to make sure the
pages get released after sampling is done.

Time in FetchAndCacheResolvedClassesAndMethods for Maps goes from
90.4ms to 47ms (average of 5 samples).

The motivation is to improve this call since it will be called more
often for sampling post startup methods.

Test: test-art-host
Test: manually look at -verbose:profiler output

Bug: 36457259

Change-Id: I3ed647ae15900c96d2180eb5c799f45393794dda
diff --git a/runtime/jit/profile_compilation_info.h b/runtime/jit/profile_compilation_info.h
index a9f2fb6..bd1b9d6 100644
--- a/runtime/jit/profile_compilation_info.h
+++ b/runtime/jit/profile_compilation_info.h
@@ -197,6 +197,10 @@
   bool AddMethodsAndClasses(const std::vector<ProfileMethodInfo>& methods,
                             const std::set<DexCacheResolvedClasses>& resolved_classes);
 
+  // Iterator is type for ids not class defs.
+  template <class Iterator>
+  bool AddClassesForDex(const DexFile* dex_file, Iterator index_begin, Iterator index_end);
+
   // Add a method index to the profile (without inline caches).
   bool AddMethodIndex(const std::string& dex_location,
                       uint32_t checksum,
@@ -207,13 +211,24 @@
   bool AddMethod(const ProfileMethodInfo& pmi);
 
   // Add methods that have samples but are are not necessarily hot. These are partitioned into two
-  // possibly interesecting sets startup and post startup.
-  bool AddSampledMethods(bool startup, std::vector<MethodReference>& methods);
+  // possibly intersecting sets startup and post startup.
   bool AddSampledMethod(bool startup,
                         const std::string& dex_location,
                         uint32_t checksum,
                         uint16_t method_idx,
                         uint32_t num_method_ids);
+  // Bulk add sampled methods for a single dex, fast since it only has one GetOrAddDexFileData call.
+  template <class Iterator>
+  bool AddSampledMethodsForDex(bool startup,
+                               const DexFile* dex_file,
+                               Iterator index_begin,
+                               Iterator index_end);
+
+  // Bulk add hot methods for a single dex, fast since it only has one GetOrAddDexFileData call.
+  template <class Iterator>
+  bool AddHotMethodsForDex(const DexFile* dex_file,
+                           Iterator index_begin,
+                           Iterator index_end);
 
   // Load profile information from the given file descriptor.
   // If the current profile is non-empty the load will fail.