Merge "Revert "Unload oat files""
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 370ea5c..9349fe3 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -41,20 +41,25 @@
 #include "compiler_callbacks.h"
 #include "debugger.h"
 #include "dex_file-inl.h"
-#include "entrypoints/entrypoint_utils.h"
 #include "entrypoints/runtime_asm_entrypoints.h"
 #include "gc_root-inl.h"
 #include "gc/accounting/card_table-inl.h"
 #include "gc/accounting/heap_bitmap.h"
 #include "gc/heap.h"
 #include "gc/space/image_space.h"
-#include "handle_scope-inl.h"
+#include "handle_scope.h"
 #include "intern_table.h"
 #include "interpreter/interpreter.h"
 #include "jit/jit.h"
 #include "jit/jit_code_cache.h"
 #include "leb128.h"
 #include "linear_alloc.h"
+#include "oat.h"
+#include "oat_file.h"
+#include "oat_file-inl.h"
+#include "oat_file_assistant.h"
+#include "oat_file_manager.h"
+#include "object_lock.h"
 #include "mirror/class.h"
 #include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
@@ -68,17 +73,12 @@
 #include "mirror/reference-inl.h"
 #include "mirror/stack_trace_element.h"
 #include "mirror/string-inl.h"
-#include "native/dalvik_system_DexFile.h"
-#include "oat.h"
-#include "oat_file.h"
-#include "oat_file-inl.h"
-#include "oat_file_assistant.h"
-#include "oat_file_manager.h"
-#include "object_lock.h"
 #include "os.h"
 #include "runtime.h"
+#include "entrypoints/entrypoint_utils.h"
 #include "ScopedLocalRef.h"
 #include "scoped_thread_state_change.h"
+#include "handle_scope-inl.h"
 #include "thread-inl.h"
 #include "trace.h"
 #include "utils.h"
@@ -1429,18 +1429,13 @@
             break;
           }
           int32_t long_array_size = long_array->GetLength();
-          // First element is the oat file.
-          for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
+          for (int32_t j = 0; j < long_array_size; ++j) {
             const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
                 long_array->GetWithoutChecks(j)));
             const DexFile::ClassDef* dex_class_def = cp_dex_file->FindClassDef(descriptor, hash);
             if (dex_class_def != nullptr) {
-              mirror::Class* klass = DefineClass(self,
-                                                 descriptor,
-                                                 hash,
-                                                 class_loader,
-                                                 *cp_dex_file,
-                                                 *dex_class_def);
+              mirror::Class* klass = DefineClass(self, descriptor, hash, class_loader,
+                                                 *cp_dex_file, *dex_class_def);
               if (klass == nullptr) {
                 CHECK(self->IsExceptionPending()) << descriptor;
                 self->ClearException();
@@ -5799,13 +5794,9 @@
   for (const DexFile* dex_file : dex_files) {
     StackHandleScope<3> hs2(self);
 
-    // CreatePathClassLoader is only used by gtests. Index 0 of h_long_array is supposed to be the
-    // oat file but we can leave it null.
-    Handle<mirror::LongArray> h_long_array = hs2.NewHandle(mirror::LongArray::Alloc(
-        self,
-        kDexFileIndexStart + 1));
+    Handle<mirror::LongArray> h_long_array = hs2.NewHandle(mirror::LongArray::Alloc(self, 1));
     DCHECK(h_long_array.Get() != nullptr);
-    h_long_array->Set(kDexFileIndexStart, reinterpret_cast<intptr_t>(dex_file));
+    h_long_array->Set(0, reinterpret_cast<intptr_t>(dex_file));
 
     Handle<mirror::Object> h_dex_file = hs2.NewHandle(
         cookie_field->GetDeclaringClass()->AllocObject(self));
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index b6b5141..56c5d1a 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -42,7 +42,6 @@
 #include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
 #include "mem_map.h"
-#include "native/dalvik_system_DexFile.h"
 #include "noop_compiler_callbacks.h"
 #include "os.h"
 #include "primitive.h"
@@ -517,7 +516,7 @@
           mirror::LongArray* long_array = cookie_field->GetObject(dex_file)->AsLongArray();
           DCHECK(long_array != nullptr);
           int32_t long_array_size = long_array->GetLength();
-          for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
+          for (int32_t j = 0; j < long_array_size; ++j) {
             const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
                 long_array->GetWithoutChecks(j)));
             if (cp_dex_file == nullptr) {
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 1a6bead..4850b6f 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -40,16 +40,13 @@
 
 namespace art {
 
-static bool ConvertJavaArrayToDexFiles(
-    JNIEnv* env,
-    jobject arrayObject,
-    /*out*/ std::vector<const DexFile*>& dex_files,
-    /*out*/ const OatFile*& oat_file) {
+static std::unique_ptr<std::vector<const DexFile*>>
+ConvertJavaArrayToNative(JNIEnv* env, jobject arrayObject) {
   jarray array = reinterpret_cast<jarray>(arrayObject);
 
   jsize array_size = env->GetArrayLength(array);
   if (env->ExceptionCheck() == JNI_TRUE) {
-    return false;
+    return std::unique_ptr<std::vector<const DexFile*>>();
   }
 
   // TODO: Optimize. On 32bit we can use an int array.
@@ -57,24 +54,27 @@
   jlong* long_data = env->GetLongArrayElements(reinterpret_cast<jlongArray>(array),
                                                &is_long_data_copied);
   if (env->ExceptionCheck() == JNI_TRUE) {
-    return false;
+    return std::unique_ptr<std::vector<const DexFile*>>();
   }
 
-  oat_file = reinterpret_cast<const OatFile*>(static_cast<uintptr_t>(long_data[kOatFileIndex]));
-  dex_files.reserve(array_size - 1);
-  for (jsize i = kDexFileIndexStart; i < array_size; ++i) {
-    dex_files.push_back(reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(long_data[i])));
+  std::unique_ptr<std::vector<const DexFile*>> ret(new std::vector<const DexFile*>());
+  ret->reserve(array_size);
+  for (jsize i = 0; i < array_size; ++i) {
+    ret->push_back(reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(*(long_data + i))));
   }
 
   env->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array), long_data, JNI_ABORT);
-  return env->ExceptionCheck() != JNI_TRUE;
+  if (env->ExceptionCheck() == JNI_TRUE) {
+    return std::unique_ptr<std::vector<const DexFile*>>();
+  }
+
+  return ret;
 }
 
-static jlongArray ConvertDexFilesToJavaArray(JNIEnv* env,
-                                             const OatFile* oat_file,
-                                             std::vector<std::unique_ptr<const DexFile>>& vec) {
-  // Add one for the oat file.
-  jlongArray long_array = env->NewLongArray(static_cast<jsize>(1u + vec.size()));
+static jlongArray ConvertNativeToJavaArray(JNIEnv* env,
+                                           std::vector<std::unique_ptr<const DexFile>>& vec) {
+  size_t vec_size = vec.size();
+  jlongArray long_array = env->NewLongArray(static_cast<jsize>(vec_size));
   if (env->ExceptionCheck() == JNI_TRUE) {
     return nullptr;
   }
@@ -85,9 +85,10 @@
     return nullptr;
   }
 
-  long_data[kOatFileIndex] = reinterpret_cast<uintptr_t>(oat_file);
-  for (size_t i = 0; i < vec.size(); ++i) {
-    long_data[kDexFileIndexStart + i] = reinterpret_cast<uintptr_t>(vec[i].get());
+  jlong* tmp = long_data;
+  for (auto& dex_file : vec) {
+    *tmp = reinterpret_cast<uintptr_t>(dex_file.get());
+    tmp++;
   }
 
   env->ReleaseLongArrayElements(long_array, long_data, 0);
@@ -164,15 +165,13 @@
   ClassLinker* linker = runtime->GetClassLinker();
   std::vector<std::unique_ptr<const DexFile>> dex_files;
   std::vector<std::string> error_msgs;
-  const OatFile* oat_file = nullptr;
 
   dex_files = runtime->GetOatFileManager().OpenDexFilesFromOat(sourceName.c_str(),
                                                                outputName.c_str(),
-                                                               /*out*/ &oat_file,
-                                                               /*out*/ &error_msgs);
+                                                               &error_msgs);
 
   if (!dex_files.empty()) {
-    jlongArray array = ConvertDexFilesToJavaArray(env, oat_file, dex_files);
+    jlongArray array = ConvertNativeToJavaArray(env, dex_files);
     if (array == nullptr) {
       ScopedObjectAccess soa(env);
       for (auto& dex_file : dex_files) {
@@ -198,54 +197,43 @@
 }
 
 static jboolean DexFile_closeDexFile(JNIEnv* env, jclass, jobject cookie) {
-  std::vector<const DexFile*> dex_files;
-  const OatFile* oat_file;
-  if (!ConvertJavaArrayToDexFiles(env, cookie, dex_files, oat_file)) {
-    Thread::Current()->AssertPendingException();
+  ScopedObjectAccess soa(env);
+  mirror::Object* dex_files_object = soa.Decode<mirror::Object*>(cookie);
+  if (dex_files_object == nullptr) {
+    ThrowNullPointerException("cookie == null");
     return JNI_FALSE;
   }
-  Runtime* const runtime = Runtime::Current();
+  mirror::LongArray* dex_files = dex_files_object->AsLongArray();
+
+  // Delete dex files associated with this dalvik.system.DexFile since there should not be running
+  // code using it. dex_files is a vector due to multidex.
+  ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
   bool all_deleted = true;
-  {
-    ScopedObjectAccess soa(env);
-    mirror::Object* dex_files_object = soa.Decode<mirror::Object*>(cookie);
-    mirror::LongArray* long_dex_files = dex_files_object->AsLongArray();
-    // Delete dex files associated with this dalvik.system.DexFile since there should not be running
-    // code using it. dex_files is a vector due to multidex.
-    ClassLinker* const class_linker = runtime->GetClassLinker();
-    int32_t i = kDexFileIndexStart;  // Oat file is at index 0.
-    for (const DexFile* dex_file : dex_files) {
-      if (dex_file != nullptr) {
-        // Only delete the dex file if the dex cache is not found to prevent runtime crashes if there
-        // are calls to DexFile.close while the ART DexFile is still in use.
-        if (class_linker->FindDexCache(soa.Self(), *dex_file, true) == nullptr) {
-          // Clear the element in the array so that we can call close again.
-          long_dex_files->Set(i, 0);
-          delete dex_file;
-        } else {
-          all_deleted = false;
-        }
-      }
-      ++i;
+  for (int32_t i = 0, count = dex_files->GetLength(); i < count; ++i) {
+    auto* dex_file = reinterpret_cast<DexFile*>(dex_files->Get(i));
+    if (dex_file == nullptr) {
+      continue;
+    }
+    // Only delete the dex file if the dex cache is not found to prevent runtime crashes if there
+    // are calls to DexFile.close while the ART DexFile is still in use.
+    if (class_linker->FindDexCache(soa.Self(), *dex_file, true) == nullptr) {
+      // Clear the element in the array so that we can call close again.
+      dex_files->Set(i, 0);
+      delete dex_file;
+    } else {
+      all_deleted = false;
     }
   }
 
-  if (all_deleted) {
-    // If all of the dex files are no longer in use we can unmap the corresponding oat file.
-    VLOG(class_linker) << "Unregistering " << oat_file;
-    runtime->GetOatFileManager().UnRegisterAndDeleteOatFile(oat_file);
-  }
+  // TODO: Also unmap the OatFile for this dalvik.system.DexFile.
+
   return all_deleted ? JNI_TRUE : JNI_FALSE;
 }
 
-static jclass DexFile_defineClassNative(JNIEnv* env,
-                                        jclass,
-                                        jstring javaName,
-                                        jobject javaLoader,
+static jclass DexFile_defineClassNative(JNIEnv* env, jclass, jstring javaName, jobject javaLoader,
                                         jobject cookie) {
-  std::vector<const DexFile*> dex_files;
-  const OatFile* oat_file;
-  if (!ConvertJavaArrayToDexFiles(env, cookie, /*out*/ dex_files, /*out*/ oat_file)) {
+  std::unique_ptr<std::vector<const DexFile*>> dex_files = ConvertJavaArrayToNative(env, cookie);
+  if (dex_files.get() == nullptr) {
     VLOG(class_linker) << "Failed to find dex_file";
     DCHECK(env->ExceptionCheck());
     return nullptr;
@@ -258,7 +246,7 @@
   }
   const std::string descriptor(DotToDescriptor(class_name.c_str()));
   const size_t hash(ComputeModifiedUtf8Hash(descriptor.c_str()));
-  for (auto& dex_file : dex_files) {
+  for (auto& dex_file : *dex_files) {
     const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor.c_str(), hash);
     if (dex_class_def != nullptr) {
       ScopedObjectAccess soa(env);
@@ -267,12 +255,8 @@
       StackHandleScope<1> hs(soa.Self());
       Handle<mirror::ClassLoader> class_loader(
           hs.NewHandle(soa.Decode<mirror::ClassLoader*>(javaLoader)));
-      mirror::Class* result = class_linker->DefineClass(soa.Self(),
-                                                        descriptor.c_str(),
-                                                        hash,
-                                                        class_loader,
-                                                        *dex_file,
-                                                        *dex_class_def);
+      mirror::Class* result = class_linker->DefineClass(soa.Self(), descriptor.c_str(), hash,
+                                                        class_loader, *dex_file, *dex_class_def);
       if (result != nullptr) {
         VLOG(class_linker) << "DexFile_defineClassNative returning " << result
                            << " for " << class_name.c_str();
@@ -293,9 +277,8 @@
 
 // Note: this can be an expensive call, as we sort out duplicates in MultiDex files.
 static jobjectArray DexFile_getClassNameList(JNIEnv* env, jclass, jobject cookie) {
-  const OatFile* oat_file = nullptr;
-  std::vector<const DexFile*> dex_files;
-  if (!ConvertJavaArrayToDexFiles(env, cookie, /*out */ dex_files, /* out */ oat_file)) {
+  std::unique_ptr<std::vector<const DexFile*>> dex_files = ConvertJavaArrayToNative(env, cookie);
+  if (dex_files.get() == nullptr) {
     DCHECK(env->ExceptionCheck());
     return nullptr;
   }
@@ -303,7 +286,7 @@
   // Push all class descriptors into a set. Use set instead of unordered_set as we want to
   // retrieve all in the end.
   std::set<const char*, CharPointerComparator> descriptors;
-  for (auto& dex_file : dex_files) {
+  for (auto& dex_file : *dex_files) {
     for (size_t i = 0; i < dex_file->NumClassDefs(); ++i) {
       const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
       const char* descriptor = dex_file->GetClassDescriptor(class_def);
@@ -312,8 +295,7 @@
   }
 
   // Now create output array and copy the set into it.
-  jobjectArray result = env->NewObjectArray(descriptors.size(),
-                                            WellKnownClasses::java_lang_String,
+  jobjectArray result = env->NewObjectArray(descriptors.size(), WellKnownClasses::java_lang_String,
                                             nullptr);
   if (result != nullptr) {
     auto it = descriptors.begin();
@@ -331,11 +313,9 @@
   return result;
 }
 
-static jint GetDexOptNeeded(JNIEnv* env,
-                            const char* filename,
-                            const char* pkgname,
-                            const char* instruction_set,
-                            const jboolean defer) {
+static jint GetDexOptNeeded(JNIEnv* env, const char* filename,
+    const char* pkgname, const char* instruction_set, const jboolean defer) {
+
   if ((filename == nullptr) || !OS::FileExists(filename)) {
     LOG(ERROR) << "DexFile_getDexOptNeeded file '" << filename << "' does not exist";
     ScopedLocalRef<jclass> fnfe(env, env->FindClass("java/io/FileNotFoundException"));
@@ -385,12 +365,8 @@
   return oat_file_assistant.GetDexOptNeeded();
 }
 
-static jint DexFile_getDexOptNeeded(JNIEnv* env,
-                                    jclass,
-                                    jstring javaFilename,
-                                    jstring javaPkgname,
-                                    jstring javaInstructionSet,
-                                    jboolean defer) {
+static jint DexFile_getDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename,
+    jstring javaPkgname, jstring javaInstructionSet, jboolean defer) {
   ScopedUtfChars filename(env, javaFilename);
   if (env->ExceptionCheck()) {
     return 0;
@@ -403,11 +379,8 @@
     return 0;
   }
 
-  return GetDexOptNeeded(env,
-                         filename.c_str(),
-                         pkgname.c_str(),
-                         instruction_set.c_str(),
-                         defer);
+  return GetDexOptNeeded(env, filename.c_str(), pkgname.c_str(),
+                         instruction_set.c_str(), defer);
 }
 
 // public API, null pkgname
diff --git a/runtime/native/dalvik_system_DexFile.h b/runtime/native/dalvik_system_DexFile.h
index 77d219d..7585ab9 100644
--- a/runtime/native/dalvik_system_DexFile.h
+++ b/runtime/native/dalvik_system_DexFile.h
@@ -18,13 +18,9 @@
 #define ART_RUNTIME_NATIVE_DALVIK_SYSTEM_DEXFILE_H_
 
 #include <jni.h>
-#include <unistd.h>
 
 namespace art {
 
-constexpr size_t kOatFileIndex = 0;
-constexpr size_t kDexFileIndexStart = 1;
-
 class DexFile;
 
 void register_dalvik_system_DexFile(JNIEnv* env);
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index cef8702..de4e8ec 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -961,16 +961,13 @@
     // we can verify only one oat file was loaded for the dex location.
     std::vector<std::unique_ptr<const DexFile>> dex_files;
     std::vector<std::string> error_msgs;
-    const OatFile* oat_file = nullptr;
     dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
         dex_location_.c_str(),
         oat_location_.c_str(),
-        &oat_file,
         &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();
-    CHECK_EQ(loaded_oat_file_, oat_file);
   }
 
   const OatFile* GetLoadedOatFile() const {
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index f7a2943..73b065f 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -33,10 +33,9 @@
 static constexpr bool kDuplicateClassesCheck = false;
 
 const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) {
-  WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
+  ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
   DCHECK(oat_file != nullptr);
   if (kIsDebugBuild) {
-    CHECK(oat_files_.find(oat_file) == oat_files_.end());
     for (const std::unique_ptr<const OatFile>& existing : oat_files_) {
       CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation();
       // Check that we don't have an oat file with the same address. Copies of the same oat file
@@ -45,19 +44,8 @@
     }
   }
   have_non_pic_oat_file_ = have_non_pic_oat_file_ || !oat_file->IsPic();
-  const OatFile* ret = oat_file.get();
-  oat_files_.insert(std::move(oat_file));
-  return ret;
-}
-
-void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) {
-  WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
-  DCHECK(oat_file != nullptr);
-  std::unique_ptr<const OatFile> compare(oat_file);
-  auto it = oat_files_.find(compare);
-  CHECK(it != oat_files_.end());
-  oat_files_.erase(it);
-  compare.release();
+  oat_files_.push_back(std::move(oat_file));
+  return oat_files_.back().get();
 }
 
 const OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location)
@@ -107,9 +95,17 @@
        current_class_index_(current_class_index),
        from_loaded_oat_(from_loaded_oat) {}
 
-  DexFileAndClassPair(DexFileAndClassPair&& rhs) = default;
+  DexFileAndClassPair(DexFileAndClassPair&& rhs) {
+    *this = std::move(rhs);
+  }
 
-  DexFileAndClassPair& operator=(DexFileAndClassPair&& rhs) = default;
+  DexFileAndClassPair& operator=(DexFileAndClassPair&& rhs) {
+    cached_descriptor_ = rhs.cached_descriptor_;
+    dex_file_ = std::move(rhs.dex_file_);
+    current_class_index_ = rhs.current_class_index_;
+    from_loaded_oat_ = rhs.from_loaded_oat_;
+    return *this;
+  }
 
   const char* GetCachedDescriptor() const {
     return cached_descriptor_;
@@ -131,7 +127,6 @@
 
   void Next() {
     ++current_class_index_;
-    cached_descriptor_ = nullptr;
   }
 
   size_t GetCurrentClassIndex() const {
@@ -258,7 +253,6 @@
 std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
     const char* dex_location,
     const char* oat_location,
-    const OatFile** out_oat_file,
     std::vector<std::string>* error_msgs) {
   CHECK(dex_location != nullptr);
   CHECK(error_msgs != nullptr);
@@ -317,7 +311,6 @@
     if (accept_oat_file) {
       VLOG(class_linker) << "Registering " << oat_file->GetLocation();
       source_oat_file = RegisterOatFile(std::move(oat_file));
-      *out_oat_file = source_oat_file;
     }
   }
 
diff --git a/runtime/oat_file_manager.h b/runtime/oat_file_manager.h
index 0e4912b..3059cb5 100644
--- a/runtime/oat_file_manager.h
+++ b/runtime/oat_file_manager.h
@@ -18,7 +18,6 @@
 #define ART_RUNTIME_OAT_FILE_MANAGER_H_
 
 #include <memory>
-#include <set>
 #include <string>
 #include <vector>
 
@@ -50,9 +49,6 @@
   const OatFile* RegisterOatFile(std::unique_ptr<const OatFile> oat_file)
       REQUIRES(!Locks::oat_file_manager_lock_);
 
-  void UnRegisterAndDeleteOatFile(const OatFile* oat_file)
-      REQUIRES(!Locks::oat_file_manager_lock_);
-
   // Find the first opened oat file with the same location, returns null if there are none.
   const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location) const
       REQUIRES(!Locks::oat_file_manager_lock_);
@@ -90,8 +86,7 @@
   std::vector<std::unique_ptr<const DexFile>> OpenDexFilesFromOat(
       const char* dex_location,
       const char* oat_location,
-      /*out*/ const OatFile** out_oat_file,
-      /*out*/ std::vector<std::string>* error_msgs)
+      /*out*/std::vector<std::string>* error_msgs)
       REQUIRES(!Locks::oat_file_manager_lock_, !Locks::mutator_lock_);
 
  private:
@@ -100,7 +95,7 @@
   bool HasCollisions(const OatFile* oat_file, /*out*/std::string* error_msg) const
       REQUIRES(!Locks::oat_file_manager_lock_);
 
-  std::set<std::unique_ptr<const OatFile>> oat_files_ GUARDED_BY(Locks::oat_file_manager_lock_);
+  std::vector<std::unique_ptr<const OatFile>> oat_files_ GUARDED_BY(Locks::oat_file_manager_lock_);
   bool have_non_pic_oat_file_;
   DISALLOW_COPY_AND_ASSIGN(OatFileManager);
 };
diff --git a/test/141-class-unload/expected.txt b/test/141-class-unload/expected.txt
index 11de660..53d7abe 100644
--- a/test/141-class-unload/expected.txt
+++ b/test/141-class-unload/expected.txt
@@ -21,4 +21,3 @@
 JNI_OnLoad called
 class null false test
 JNI_OnUnload called
-Number of loaded unload-ex maps 0
diff --git a/test/141-class-unload/src/Main.java b/test/141-class-unload/src/Main.java
index 0640b36..3cc43ac 100644
--- a/test/141-class-unload/src/Main.java
+++ b/test/141-class-unload/src/Main.java
@@ -14,9 +14,6 @@
  * limitations under the License.
  */
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -46,28 +43,11 @@
             testStackTrace(constructor);
             // Stress test to make sure we dont leak memory.
             stressTest(constructor);
-            // Test that the oat files are unloaded.
-            testOatFilesUnloaded(getPid());
         } catch (Exception e) {
             System.out.println(e);
         }
     }
 
-    private static void testOatFilesUnloaded(int pid) throws Exception {
-        BufferedReader reader = new BufferedReader(new FileReader ("/proc/" + pid + "/maps"));
-        String line;
-        int count = 0;
-        Runtime.getRuntime().gc();
-        System.runFinalization();
-        while ((line = reader.readLine()) != null) {
-            if (line.contains("@141-class-unload-ex.jar")) {
-                System.out.println(line);
-                ++count;
-            }
-        }
-        System.out.println("Number of loaded unload-ex maps " + count);
-    }
-
     private static void stressTest(Constructor constructor) throws Exception {
         for (int i = 0; i <= 100; ++i) {
             setUpUnloadLoader(constructor, false);
@@ -183,8 +163,4 @@
         loadLibrary.invoke(intHolder, nativeLibraryName);
         return new WeakReference(loader);
     }
-
-    private static int getPid() throws Exception {
-      return Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
-    }
 }