Fix race between dex-file registration and class-loader deletion

We keep track of class-loaders by having a list with jweak references
to the dex-caches. When we register a new dex-file we check that the
dex-cache hasn't already been registered with a different
class-loader. We decoded the jweak and performed this check this
without any locks however meaning we could race with class-loader
cleanup. This could cause CHECK failures as we try to decode a deleted
jweak.

Bug: 147206162
Test: ./art/test/run-test --create-runner   --host --prebuild --compact-dex-level fast --optimizing --no-relocate --runtime-option -Xcheck:jni  2001-virtual-structural-multithread
      ./art/tools/parallel_run.py
Change-Id: Ibeb12ec3d42f7972d09b155b7c24743266897a54
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index f82a7c7..998f739 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -1055,19 +1055,15 @@
                              ObjPtr<mirror::ClassLoader> class_loader)
       REQUIRES(Locks::dex_lock_)
       REQUIRES_SHARED(Locks::mutator_lock_);
-  DexCacheData FindDexCacheDataLocked(const DexFile& dex_file)
+  const DexCacheData* FindDexCacheDataLocked(const DexFile& dex_file)
       REQUIRES(Locks::dex_lock_)
       REQUIRES_SHARED(Locks::mutator_lock_);
-  static ObjPtr<mirror::DexCache> DecodeDexCache(Thread* self, const DexCacheData& data)
-      REQUIRES_SHARED(Locks::mutator_lock_);
-  // Called to ensure that the dex cache has been registered with the same class loader.
-  // If yes, returns the dex cache, otherwise throws InternalError and returns null.
-  ObjPtr<mirror::DexCache> EnsureSameClassLoader(Thread* self,
-                                                 ObjPtr<mirror::DexCache> dex_cache,
-                                                 const DexCacheData& data,
-                                                 ObjPtr<mirror::ClassLoader> class_loader)
-      REQUIRES(!Locks::dex_lock_)
-      REQUIRES_SHARED(Locks::mutator_lock_);
+  static ObjPtr<mirror::DexCache> DecodeDexCacheLocked(Thread* self, const DexCacheData* data)
+      REQUIRES_SHARED(Locks::dex_lock_, Locks::mutator_lock_);
+  bool IsSameClassLoader(ObjPtr<mirror::DexCache> dex_cache,
+                         const DexCacheData* data,
+                         ObjPtr<mirror::ClassLoader> class_loader)
+      REQUIRES_SHARED(Locks::dex_lock_, Locks::mutator_lock_);
 
   bool InitializeDefaultInterfaceRecursive(Thread* self,
                                            Handle<mirror::Class> klass,