Add OatFileManager

Takes over a large amount of functionality from the class linker.

Changed OatFile to loading the same OatFile multiple times. This is
required for unloading OatFiles and moving dex caches to BSS since
these require a different OatFile for each dex cache and class
loader.

Bug: 22720414

Change-Id: I0321096723a294dc72949f21e66da82727b512fc
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 20347a9..de4e8ec 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -31,6 +31,7 @@
 #include "compiler_callbacks.h"
 #include "gc/space/image_space.h"
 #include "mem_map.h"
+#include "oat_file_manager.h"
 #include "os.h"
 #include "scoped_thread_state_change.h"
 #include "thread-inl.h"
@@ -958,10 +959,12 @@
 
     // Load the dex files, and save a pointer to the loaded oat file, so that
     // we can verify only one oat file was loaded for the dex location.
-    ClassLinker* linker = Runtime::Current()->GetClassLinker();
     std::vector<std::unique_ptr<const DexFile>> dex_files;
     std::vector<std::string> error_msgs;
-    dex_files = linker->OpenDexFilesFromOat(dex_location_.c_str(), oat_location_.c_str(), &error_msgs);
+    dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
+        dex_location_.c_str(),
+        oat_location_.c_str(),
+        &error_msgs);
     CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
     CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
     loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
@@ -980,8 +983,9 @@
 // Test the case where multiple processes race to generate an oat file.
 // This simulates multiple processes using multiple threads.
 //
-// We want only one Oat file to be loaded when there is a race to load, to
-// avoid using up the virtual memory address space.
+// We want unique Oat files to be loaded even when there is a race to load.
+// TODO: The test case no longer tests locking the way it was intended since we now get multiple
+// copies of the same Oat files mapped at different locations.
 TEST_F(OatFileAssistantTest, RaceToGenerate) {
   std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
   std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
@@ -1002,10 +1006,12 @@
   thread_pool.StartWorkers(self);
   thread_pool.Wait(self, true, false);
 
-  // Verify every task got the same pointer.
-  const OatFile* expected = tasks[0]->GetLoadedOatFile();
+  // Verify every task got a unique oat file.
+  std::set<const OatFile*> oat_files;
   for (auto& task : tasks) {
-    EXPECT_EQ(expected, task->GetLoadedOatFile());
+    const OatFile* oat_file = task->GetLoadedOatFile();
+    EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
+    oat_files.insert(oat_file);
   }
 }