Revert "Verify InMemoryDexClassLoader classes in a background thread"

This reverts commit d592dbe1e2b09079382713220b2ff59f02db1859.

Reason for revert: art buildbots crashing

Change-Id: Ida6bb79cb498e708df5c535edc16e4fe9875442c
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index d1ea655..feaf619 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -340,26 +340,6 @@
   }
 }
 
-static void DexFile_verifyInBackgroundNative(JNIEnv* env,
-                                             jclass,
-                                             jobject cookie,
-                                             jobject class_loader) {
-  CHECK(cookie != nullptr);
-  CHECK(class_loader != nullptr);
-
-  // Extract list of dex files from the cookie.
-  std::vector<const DexFile*> dex_files;
-  const OatFile* oat_file;
-  if (!ConvertJavaArrayToDexFiles(env, cookie, dex_files, oat_file)) {
-    Thread::Current()->AssertPendingException();
-    return;
-  }
-  CHECK(oat_file == nullptr) << "Called verifyInBackground on a dex file backed by oat";
-
-  // Hand over to OatFileManager to spawn a verification thread.
-  Runtime::Current()->GetOatFileManager().RunBackgroundVerification(dex_files, class_loader);
-}
-
 static jboolean DexFile_closeDexFile(JNIEnv* env, jclass, jobject cookie) {
   std::vector<const DexFile*> dex_files;
   const OatFile* oat_file;
@@ -913,7 +893,6 @@
                 "[I"
                 "[I"
                 ")Ljava/lang/Object;"),
-  NATIVE_METHOD(DexFile, verifyInBackgroundNative, "(Ljava/lang/Object;Ljava/lang/ClassLoader;)V"),
   NATIVE_METHOD(DexFile, isValidCompilerFilter, "(Ljava/lang/String;)Z"),
   NATIVE_METHOD(DexFile, isProfileGuidedCompilerFilter, "(Ljava/lang/String;)Z"),
   NATIVE_METHOD(DexFile,
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index 47a6f99..b03551b 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -39,7 +39,6 @@
 #include "gc/scoped_gc_critical_section.h"
 #include "gc/space/image_space.h"
 #include "handle_scope-inl.h"
-#include "jni/java_vm_ext.h"
 #include "jni/jni_internal.h"
 #include "mirror/class_loader.h"
 #include "mirror/object-inl.h"
@@ -49,7 +48,6 @@
 #include "scoped_thread_state_change-inl.h"
 #include "thread-current-inl.h"
 #include "thread_list.h"
-#include "thread_pool.h"
 #include "well_known_classes.h"
 
 namespace art {
@@ -644,113 +642,6 @@
   return dex_files;
 }
 
-class BackgroundVerificationTask final : public Task {
- public:
-  BackgroundVerificationTask(const std::vector<const DexFile*>& dex_files, jobject class_loader)
-      : dex_files_(dex_files) {
-    Thread* const self = Thread::Current();
-    ScopedObjectAccess soa(self);
-    // Create a global ref for `class_loader` because it will be accessed from a different thread.
-    class_loader_ = soa.Vm()->AddGlobalRef(self, soa.Decode<mirror::ClassLoader>(class_loader));
-    CHECK(class_loader_ != nullptr);
-  }
-
-  ~BackgroundVerificationTask() {
-    Thread* const self = Thread::Current();
-    ScopedObjectAccess soa(self);
-    soa.Vm()->DeleteGlobalRef(self, class_loader_);
-  }
-
-  void Run(Thread* self) override {
-    ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
-
-    // Iterate over all classes and verify them.
-    for (const DexFile* dex_file : dex_files_) {
-      for (uint32_t cdef_idx = 0; cdef_idx < dex_file->NumClassDefs(); cdef_idx++) {
-        // Take handles inside the loop. The background verification is low priority
-        // and we want to minimize the risk of blocking anyone else.
-        ScopedObjectAccess soa(self);
-        StackHandleScope<2> hs(self);
-        Handle<mirror::ClassLoader> h_loader(hs.NewHandle(
-            soa.Decode<mirror::ClassLoader>(class_loader_)));
-        Handle<mirror::Class> h_class(hs.NewHandle<mirror::Class>(class_linker->FindClass(
-            self,
-            dex_file->GetClassDescriptor(dex_file->GetClassDef(cdef_idx)),
-            h_loader)));
-
-        if (h_class == nullptr) {
-          CHECK(self->IsExceptionPending());
-          self->ClearException();
-          continue;
-        }
-
-        if (&h_class->GetDexFile() != dex_file) {
-          // There is a different class in the class path or a parent class loader
-          // with the same descriptor. This `h_class` is not resolvable, skip it.
-          continue;
-        }
-
-        CHECK(h_class->IsResolved()) << h_class->PrettyDescriptor();
-        class_linker->VerifyClass(self, h_class);
-        if (h_class->IsErroneous()) {
-          // ClassLinker::VerifyClass throws, which isn't useful here.
-          CHECK(soa.Self()->IsExceptionPending());
-          soa.Self()->ClearException();
-        }
-
-        CHECK(h_class->IsVerified() || h_class->IsErroneous())
-            << h_class->PrettyDescriptor() << ": state=" << h_class->GetStatus();
-      }
-    }
-  }
-
-  void Finalize() override {
-    delete this;
-  }
-
- private:
-  const std::vector<const DexFile*> dex_files_;
-  jobject class_loader_;
-
-  DISALLOW_COPY_AND_ASSIGN(BackgroundVerificationTask);
-};
-
-void OatFileManager::RunBackgroundVerification(const std::vector<const DexFile*>& dex_files,
-                                               jobject class_loader) {
-  Thread* const self = Thread::Current();
-  if (Runtime::Current()->IsShuttingDown(self)) {
-    // Not allowed to create new threads during runtime shutdown.
-    return;
-  }
-
-  if (verification_thread_pool_ == nullptr) {
-    verification_thread_pool_.reset(new ThreadPool("Verification thread pool",
-                                                   /* num_threads= */ 1));
-    verification_thread_pool_->StartWorkers(self);
-  }
-
-  verification_thread_pool_->AddTask(self, new BackgroundVerificationTask(dex_files, class_loader));
-}
-
-void OatFileManager::WaitForWorkersToBeCreated() {
-  DCHECK(!Runtime::Current()->IsShuttingDown(Thread::Current()))
-      << "Cannot create new threads during runtime shutdown";
-  if (verification_thread_pool_ != nullptr) {
-    verification_thread_pool_->WaitForWorkersToBeCreated();
-  }
-}
-
-void OatFileManager::DeleteThreadPool() {
-  verification_thread_pool_.reset(nullptr);
-}
-
-void OatFileManager::WaitForBackgroundVerificationTasks() {
-  Thread* const self = Thread::Current();
-  if (verification_thread_pool_ != nullptr) {
-    verification_thread_pool_->Wait(self, /* do_work= */ true, /* may_hold_locks= */ false);
-  }
-}
-
 void OatFileManager::SetOnlyUseSystemOatFiles(bool assert_no_files_loaded) {
   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
   if (assert_no_files_loaded) {
diff --git a/runtime/oat_file_manager.h b/runtime/oat_file_manager.h
index 24d8e42..9c6c04b 100644
--- a/runtime/oat_file_manager.h
+++ b/runtime/oat_file_manager.h
@@ -38,7 +38,6 @@
 class ClassLoaderContext;
 class DexFile;
 class OatFile;
-class ThreadPool;
 
 // Class for dealing with oat file management.
 //
@@ -104,20 +103,6 @@
 
   void SetOnlyUseSystemOatFiles(bool assert_no_files_loaded);
 
-  // Spawn a background thread which verifies all classes in the given dex files.
-  void RunBackgroundVerification(const std::vector<const DexFile*>& dex_files,
-                                 jobject class_loader);
-
-  // Wait for thread pool workers to be created. This is used during shutdown as
-  // threads are not allowed to attach while runtime is in shutdown lock.
-  void WaitForWorkersToBeCreated();
-
-  // If allocated, delete a thread pool of background verification threads.
-  void DeleteThreadPool();
-
-  // Wait for all background verification tasks to finish. This is only used by tests.
-  void WaitForBackgroundVerificationTasks();
-
  private:
   enum class CheckCollisionResult {
     kSkippedUnsupportedClassLoader,
@@ -158,9 +143,6 @@
   // is not on /system, don't load it "executable".
   bool only_use_system_oat_files_;
 
-  // Single-thread pool used to run the verifier in the background.
-  std::unique_ptr<ThreadPool> verification_thread_pool_;
-
   DISALLOW_COPY_AND_ASSIGN(OatFileManager);
 };
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index c4e4b61..c978b83 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -364,19 +364,17 @@
         << "\n";
   }
 
-  // Wait for the workers of thread pools to be created since there can't be any
-  // threads attaching during shutdown.
   WaitForThreadPoolWorkersToStart();
+
   if (jit_ != nullptr) {
+    // Wait for the workers to be created since there can't be any threads attaching during
+    // shutdown.
     jit_->WaitForWorkersToBeCreated();
     // Stop the profile saver thread before marking the runtime as shutting down.
     // The saver will try to dump the profiles before being sopped and that
     // requires holding the mutator lock.
     jit_->StopProfileSaver();
   }
-  if (oat_file_manager_ != nullptr) {
-    oat_file_manager_->WaitForWorkersToBeCreated();
-  }
 
   {
     ScopedTrace trace2("Wait for shutdown cond");
@@ -421,9 +419,6 @@
     // JIT compiler threads.
     jit_->DeleteThreadPool();
   }
-  if (oat_file_manager_ != nullptr) {
-    oat_file_manager_->DeleteThreadPool();
-  }
   DeleteThreadPool();
   CHECK(thread_pool_ == nullptr);
 
diff --git a/test/674-hiddenapi/src-art/Main.java b/test/674-hiddenapi/src-art/Main.java
index c92d352..d6a8c6d 100644
--- a/test/674-hiddenapi/src-art/Main.java
+++ b/test/674-hiddenapi/src-art/Main.java
@@ -14,12 +14,18 @@
  * limitations under the License.
  */
 
+import dalvik.system.InMemoryDexClassLoader;
 import dalvik.system.PathClassLoader;
+import dalvik.system.VMRuntime;
 import java.io.File;
+import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
 import java.nio.file.Files;
 import java.util.Arrays;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
 
 public class Main {
   // This needs to be kept in sync with DexDomain in ChildClass.
@@ -46,9 +52,6 @@
     // As a side effect, we also cannot test Platform->Platform and later
     // Platform->CorePlatform as the former succeeds in verifying linkage usages
     // that should fail in the latter.
-    // We also cannot use InMemoryDexClassLoader because it runs verification in
-    // a background thread and being able to dynamically change the configuration
-    // (like list of exemptions) would require proper thread synchronization.
 
     // Run test with both parent and child dex files loaded with class loaders.
     // The expectation is that hidden members in parent should be visible to
@@ -101,7 +104,7 @@
     // Load child dex if it is not in boot class path.
     ClassLoader childLoader = null;
     if (childDomain == DexDomain.Application) {
-      childLoader = new PathClassLoader(DEX_CHILD, parentLoader);
+      childLoader = new InMemoryDexClassLoader(readDexFile(DEX_CHILD), parentLoader);
     } else {
       if (parentLoader != BOOT_CLASS_LOADER) {
         throw new IllegalStateException(
@@ -147,6 +150,22 @@
     }
   }
 
+  // Helper to read dex file into memory.
+  private static ByteBuffer readDexFile(String jarFileName) throws Exception {
+    ZipFile zip = new ZipFile(new File(jarFileName));
+    ZipEntry entry = zip.getEntry("classes.dex");
+    InputStream is = zip.getInputStream(entry);
+    int offset = 0;
+    int size = (int) entry.getSize();
+    ByteBuffer buffer = ByteBuffer.allocate(size);
+    while (is.available() > 0) {
+      is.read(buffer.array(), offset, size - offset);
+    }
+    is.close();
+    zip.close();
+    return buffer;
+  }
+
   // Copy native library to a new file with a unique name so it does not
   // conflict with other loaded instance of the same binary file.
   private static String createNativeLibCopy(DexDomain parentDomain, DexDomain childDomain,
diff --git a/test/692-vdex-inmem-loader/expected.txt b/test/692-vdex-inmem-loader/expected.txt
deleted file mode 100644
index 0990d72..0000000
--- a/test/692-vdex-inmem-loader/expected.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-JNI_OnLoad called
-Hello
-Hello
diff --git a/test/692-vdex-inmem-loader/info.txt b/test/692-vdex-inmem-loader/info.txt
deleted file mode 100644
index 435b9c5..0000000
--- a/test/692-vdex-inmem-loader/info.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Test that dex files loaded with InMemoryDexClassLoader get verified and the verification results
-cached in a vdex file in the app's data folder. Subsequent loads should initialize an instance of
-OatFile using the data in the vdex.
\ No newline at end of file
diff --git a/test/692-vdex-inmem-loader/src-ex/DummyClass.java b/test/692-vdex-inmem-loader/src-ex/DummyClass.java
deleted file mode 100644
index 443d1fe..0000000
--- a/test/692-vdex-inmem-loader/src-ex/DummyClass.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public class DummyClass {
-}
diff --git a/test/692-vdex-inmem-loader/src-secondary/art/ClassA.java b/test/692-vdex-inmem-loader/src-secondary/art/ClassA.java
deleted file mode 100644
index 2b2bc5d..0000000
--- a/test/692-vdex-inmem-loader/src-secondary/art/ClassA.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package art;
-
-public class ClassA {
-  public static String getHello() {
-    return "Hello";
-  }
-}
diff --git a/test/692-vdex-inmem-loader/src-secondary/art/ClassB.java b/test/692-vdex-inmem-loader/src-secondary/art/ClassB.java
deleted file mode 100644
index 45c450e..0000000
--- a/test/692-vdex-inmem-loader/src-secondary/art/ClassB.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package art;
-
-public class ClassB {
-  public static void printHello() {
-    System.out.println(ClassA.getHello());
-  }
-}
diff --git a/test/692-vdex-inmem-loader/src-secondary/gen.sh b/test/692-vdex-inmem-loader/src-secondary/gen.sh
deleted file mode 100755
index 67df40e..0000000
--- a/test/692-vdex-inmem-loader/src-secondary/gen.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -e
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-TMP=`mktemp -d`
-
-CLASS_A="art/ClassA"
-CLASS_B="art/ClassB"
-
-(cd "$TMP" && \
-    javac -d "${TMP}" "$DIR/${CLASS_A}.java" "$DIR/${CLASS_B}.java" && \
-    d8 --output . "$TMP/${CLASS_A}.class" &&
-    mv "$TMP/classes.dex" "$TMP/classesA.dex" &&
-    d8 --output . "$TMP/${CLASS_B}.class" &&
-    mv "$TMP/classes.dex" "$TMP/classesB.dex")
-
-echo '  private static final byte[] DEX_BYTES_A = Base64.getDecoder().decode('
-base64 "${TMP}/classesA.dex" | sed -E 's/^/    "/' | sed ':a;N;$!ba;s/\n/" +\n/g' | sed -E '$ s/$/");/'
-
-echo '  private static final byte[] DEX_BYTES_B = Base64.getDecoder().decode('
-base64 "${TMP}/classesB.dex" | sed -E 's/^/    "/' | sed ':a;N;$!ba;s/\n/" +\n/g' | sed -E '$ s/$/");/'
-
-rm -rf "$TMP"
diff --git a/test/692-vdex-inmem-loader/src/Main.java b/test/692-vdex-inmem-loader/src/Main.java
deleted file mode 100644
index bfdf16a..0000000
--- a/test/692-vdex-inmem-loader/src/Main.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-import dalvik.system.InMemoryDexClassLoader;
-import java.lang.reflect.Method;
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.Base64;
-
-public class Main {
-  private static void check(boolean expected, boolean actual, String message) {
-    if (expected != actual) {
-      System.err.println(
-          "ERROR: " + message + " (expected=" + expected + ", actual=" + actual + ")");
-    }
-  }
-
-  private static ClassLoader singleLoader() {
-    return new InMemoryDexClassLoader(
-        new ByteBuffer[] { ByteBuffer.wrap(DEX_BYTES_A), ByteBuffer.wrap(DEX_BYTES_B) },
-        /*parent*/null);
-  }
-
-  private static ClassLoader[] multiLoader() {
-    ClassLoader clA = new InMemoryDexClassLoader(ByteBuffer.wrap(DEX_BYTES_A), /*parent*/ null);
-    ClassLoader clB = new InMemoryDexClassLoader(ByteBuffer.wrap(DEX_BYTES_B), /*parent*/ clA);
-    return new ClassLoader[] { clA, clB };
-  }
-
-  private static void test(ClassLoader loader, boolean invokeMethod) throws Exception {
-    waitForVerifier();
-    check(true, areClassesVerified(loader), "areClassesVerified");
-
-    if (invokeMethod) {
-      loader.loadClass("art.ClassB").getDeclaredMethod("printHello").invoke(null);
-    }
-  }
-
-  public static void main(String[] args) throws Exception {
-    System.loadLibrary(args[0]);
-    ClassLoader[] loaders = null;
-
-    // Test loading both dex files in a single class loader.
-    // Background verification task should verify all their classes.
-    test(singleLoader(), /*invokeMethod*/true);
-
-    // Test loading the two dex files with separate class loaders.
-    // Background verification task should still verify all classes.
-    loaders = multiLoader();
-    test(loaders[0], /*invokeMethod*/false);
-    test(loaders[1], /*invokeMethod*/true);
-  }
-
-  private static native void waitForVerifier();
-  private static native boolean areClassesVerified(ClassLoader loader);
-
-  // Defined in 674-hiddenapi.
-  private static native void appendToBootClassLoader(String dexPath, boolean isCorePlatform);
-
-  private static final String DEX_LOCATION = System.getenv("DEX_LOCATION");
-  private static final String DEX_EXTRA =
-      new File(DEX_LOCATION, "692-vdex-inmem-loader-ex.jar").getAbsolutePath();
-
-  private static final byte[] DEX_BYTES_A = Base64.getDecoder().decode(
-    "ZGV4CjAzNQBxYu/tdPfiHaRPYr5yaT6ko9V/xMinr1OwAgAAcAAAAHhWNBIAAAAAAAAAABwCAAAK" +
-    "AAAAcAAAAAQAAACYAAAAAgAAAKgAAAAAAAAAAAAAAAMAAADAAAAAAQAAANgAAAC4AQAA+AAAADAB" +
-    "AAA4AQAARQEAAEwBAABPAQAAXQEAAHEBAACFAQAAiAEAAJIBAAAEAAAABQAAAAYAAAAHAAAAAwAA" +
-    "AAIAAAAAAAAABwAAAAMAAAAAAAAAAAABAAAAAAAAAAAACAAAAAEAAQAAAAAAAAAAAAEAAAABAAAA" +
-    "AAAAAAEAAAAAAAAACQIAAAAAAAABAAAAAAAAACwBAAADAAAAGgACABEAAAABAAEAAQAAACgBAAAE" +
-    "AAAAcBACAAAADgATAA4AFQAOAAY8aW5pdD4AC0NsYXNzQS5qYXZhAAVIZWxsbwABTAAMTGFydC9D" +
-    "bGFzc0E7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwABVgAIZ2V0SGVs" +
-    "bG8AdX5+RDh7ImNvbXBpbGF0aW9uLW1vZGUiOiJkZWJ1ZyIsIm1pbi1hcGkiOjEsInNoYS0xIjoi" +
-    "OTY2MDhmZDdiYmNjZGQyMjc2Y2Y4OTI4M2QyYjgwY2JmYzRmYzgxYyIsInZlcnNpb24iOiIxLjUu" +
-    "NC1kZXYifQAAAAIAAIGABJACAQn4AQAAAAAADAAAAAAAAAABAAAAAAAAAAEAAAAKAAAAcAAAAAIA" +
-    "AAAEAAAAmAAAAAMAAAACAAAAqAAAAAUAAAADAAAAwAAAAAYAAAABAAAA2AAAAAEgAAACAAAA+AAA" +
-    "AAMgAAACAAAAKAEAAAIgAAAKAAAAMAEAAAAgAAABAAAACQIAAAMQAAABAAAAGAIAAAAQAAABAAAA" +
-    "HAIAAA==");
-  private static final byte[] DEX_BYTES_B = Base64.getDecoder().decode(
-    "ZGV4CjAzNQB+hWvce73hXt7ZVNgp9RAyMLSwQzsWUjV4AwAAcAAAAHhWNBIAAAAAAAAAAMwCAAAQ" +
-    "AAAAcAAAAAcAAACwAAAAAwAAAMwAAAABAAAA8AAAAAUAAAD4AAAAAQAAACABAAA4AgAAQAEAAI4B" +
-    "AACWAQAAowEAAKYBAAC0AQAAwgEAANkBAADtAQAAAQIAABUCAAAYAgAAHAIAACYCAAArAgAANwIA" +
-    "AEACAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAAAgAAAAQAAAAAAAAACQAAAAYAAAAAAAAA" +
-    "CgAAAAYAAACIAQAABQACAAwAAAAAAAAACwAAAAEAAQAAAAAAAQABAA0AAAACAAIADgAAAAMAAQAA" +
-    "AAAAAQAAAAEAAAADAAAAAAAAAAEAAAAAAAAAtwIAAAAAAAABAAEAAQAAAHwBAAAEAAAAcBAEAAAA" +
-    "DgACAAAAAgAAAIABAAAKAAAAYgAAAHEAAAAAAAwBbiADABAADgATAA4AFQAOlgAAAAABAAAABAAG" +
-    "PGluaXQ+AAtDbGFzc0IuamF2YQABTAAMTGFydC9DbGFzc0E7AAxMYXJ0L0NsYXNzQjsAFUxqYXZh" +
-    "L2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsA" +
-    "EkxqYXZhL2xhbmcvU3lzdGVtOwABVgACVkwACGdldEhlbGxvAANvdXQACnByaW50SGVsbG8AB3By" +
-    "aW50bG4AdX5+RDh7ImNvbXBpbGF0aW9uLW1vZGUiOiJkZWJ1ZyIsIm1pbi1hcGkiOjEsInNoYS0x" +
-    "IjoiOTY2MDhmZDdiYmNjZGQyMjc2Y2Y4OTI4M2QyYjgwY2JmYzRmYzgxYyIsInZlcnNpb24iOiIx" +
-    "LjUuNC1kZXYifQAAAAIAAYGABMACAQnYAgAAAAAAAAAOAAAAAAAAAAEAAAAAAAAAAQAAABAAAABw" +
-    "AAAAAgAAAAcAAACwAAAAAwAAAAMAAADMAAAABAAAAAEAAADwAAAABQAAAAUAAAD4AAAABgAAAAEA" +
-    "AAAgAQAAASAAAAIAAABAAQAAAyAAAAIAAAB8AQAAARAAAAEAAACIAQAAAiAAABAAAACOAQAAACAA" +
-    "AAEAAAC3AgAAAxAAAAEAAADIAgAAABAAAAEAAADMAgAA");
-}
diff --git a/test/692-vdex-inmem-loader/vdex_inmem_loader.cc b/test/692-vdex-inmem-loader/vdex_inmem_loader.cc
deleted file mode 100644
index f064953..0000000
--- a/test/692-vdex-inmem-loader/vdex_inmem_loader.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "class_loader_utils.h"
-#include "jni.h"
-#include "nativehelper/scoped_utf_chars.h"
-#include "oat_file_assistant.h"
-#include "oat_file_manager.h"
-#include "scoped_thread_state_change-inl.h"
-#include "thread.h"
-
-namespace art {
-namespace Test692VdexInmemLoader {
-
-extern "C" JNIEXPORT void JNICALL Java_Main_waitForVerifier(JNIEnv*, jclass) {
-  Runtime::Current()->GetOatFileManager().WaitForBackgroundVerificationTasks();
-}
-
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_areClassesVerified(JNIEnv*,
-                                                                   jclass,
-                                                                   jobject loader) {
-  ScopedObjectAccess soa(Thread::Current());
-  StackHandleScope<2> hs(soa.Self());
-  Handle<mirror::ClassLoader> h_loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(loader)));
-
-  std::vector<const DexFile*> dex_files;
-  VisitClassLoaderDexFiles(
-      soa,
-      h_loader,
-      [&](const DexFile* dex_file) {
-        dex_files.push_back(dex_file);
-        return true;
-      });
-
-  MutableHandle<mirror::Class> h_class(hs.NewHandle<mirror::Class>(nullptr));
-  ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
-
-  bool is_first = true;
-  bool all_verified = false;
-  for (const DexFile* dex_file : dex_files) {
-    for (uint16_t cdef_idx = 0; cdef_idx < dex_file->NumClassDefs(); ++cdef_idx) {
-      const char* desc = dex_file->GetClassDescriptor(dex_file->GetClassDef(cdef_idx));
-      h_class.Assign(class_linker->FindClass(soa.Self(), desc, h_loader));
-      CHECK(h_class != nullptr) << "Could not find class " << desc;
-      bool is_verified = h_class->IsVerified();
-      if (is_first) {
-        all_verified = is_verified;
-        is_first = false;
-      } else if (all_verified != is_verified) {
-        // Classes should either all or none be verified.
-        LOG(ERROR) << "areClassesVerified is inconsistent";
-      }
-    }
-  }
-  return all_verified ? JNI_TRUE : JNI_FALSE;
-}
-
-}  // namespace Test692VdexInmemLoader
-}  // namespace art
diff --git a/test/Android.bp b/test/Android.bp
index 3e56442..5460b3a 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -492,7 +492,6 @@
         "664-aget-verifier/aget-verifier.cc",
         "667-jit-jni-stub/jit_jni_stub_test.cc",
         "674-hiddenapi/hiddenapi.cc",
-        "692-vdex-inmem-loader/vdex_inmem_loader.cc",
         "708-jit-cache-churn/jit.cc",
         "800-smali/jni.cc",
         "909-attach-agent/disallow_debugging.cc",
diff --git a/test/knownfailures.json b/test/knownfailures.json
index f77999b..e78e002 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -559,7 +559,6 @@
             "674-hiddenapi",
             "690-hiddenapi-same-name-methods",
             "691-hiddenapi-proxy",
-            "692-vdex-inmem-loader",
             "944-transform-classloaders",
             "999-redefine-hiddenapi"
         ],
@@ -1095,7 +1094,6 @@
                   "688-shared-library",
                   "690-hiddenapi-same-name-methods",
                   "691-hiddenapi-proxy",
-                  "692-vdex-inmem-loader",
                   "999-redefine-hiddenapi",
                   "1000-non-moving-space-stress",
                   "1001-app-image-regions",