summaryrefslogtreecommitdiff
path: root/runtime/class_linker.h
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2017-02-03 11:47:34 +0000
committer Vladimir Marko <vmarko@google.com> 2017-02-09 10:10:29 +0000
commitcd556b003adbb53739d4b3f43135e6a0ae69509a (patch)
treea30c9f03071d87e1f75a0d0b8c2961d113ea767d /runtime/class_linker.h
parent357dcb73934356239292c46d6fbedba734da5e00 (diff)
Fix dex cache resolved types and class table mismatch.
Record class table in ClassLinker::DexCacheData and use it in DexCache.setResolvedType() to store the type also in the initiating loader's class table if the dex file has been registered. Also throw InternalError when trying to register the same DexFile with multiple class loaders. (Different DexFile instances referencing the same file are OK.) Test: 155-java-set-resolved-type Test: m test-art-host Bug: 30627598 Bug: 34193123 Bug: 34839984 Change-Id: Ia48acb300337c45880ea1459d2d32789546d67f4
Diffstat (limited to 'runtime/class_linker.h')
-rw-r--r--runtime/class_linker.h51
1 files changed, 42 insertions, 9 deletions
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 5042fb7609..62d3c29a19 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -382,11 +382,11 @@ class ClassLinker {
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
- mirror::DexCache* RegisterDexFile(const DexFile& dex_file,
- ObjPtr<mirror::ClassLoader> class_loader)
+ ObjPtr<mirror::DexCache> RegisterDexFile(const DexFile& dex_file,
+ ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES(!Locks::dex_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- void RegisterDexFile(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache)
+ void RegisterBootClassPathDexFile(const DexFile& dex_file, ObjPtr<mirror::DexCache> dex_cache)
REQUIRES(!Locks::dex_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -413,9 +413,13 @@ class ClassLinker {
REQUIRES(!Locks::dex_lock_, !Locks::classlinker_classes_lock_, !Locks::trace_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::DexCache* FindDexCache(Thread* self,
- const DexFile& dex_file,
- bool allow_failure = false)
+ bool IsDexFileRegistered(Thread* self, const DexFile& dex_file)
+ REQUIRES(!Locks::dex_lock_)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::DexCache> FindDexCache(Thread* self, const DexFile& dex_file)
+ REQUIRES(!Locks::dex_lock_)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+ ClassTable* FindClassTable(Thread* self, ObjPtr<mirror::DexCache> dex_cache)
REQUIRES(!Locks::dex_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void FixupDexCaches(ArtMethod* resolution_method)
@@ -655,6 +659,18 @@ class ClassLinker {
REQUIRES(!Locks::dex_lock_);
struct DexCacheData {
+ // Construct an invalid data object.
+ DexCacheData()
+ : weak_root(nullptr),
+ dex_file(nullptr),
+ resolved_methods(nullptr),
+ class_table(nullptr) { }
+
+ // Check if the data is valid.
+ bool IsValid() const {
+ return dex_file != nullptr;
+ }
+
// Weak root to the DexCache. Note: Do not decode this unnecessarily or else class unloading may
// not work properly.
jweak weak_root;
@@ -663,6 +679,11 @@ class ClassLinker {
// class unloading.)
const DexFile* dex_file;
ArtMethod** resolved_methods;
+ // Identify the associated class loader's class table. This is used to make sure that
+ // the Java call to native DexCache.setResolvedType() inserts the resolved type in that
+ // class table. It is also used to make sure we don't register the same dex cache with
+ // multiple class loaders.
+ ClassTable* class_table;
};
private:
@@ -749,7 +770,7 @@ class ClassLinker {
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
- void AppendToBootClassPath(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache)
+ void AppendToBootClassPath(const DexFile& dex_file, ObjPtr<mirror::DexCache> dex_cache)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
@@ -810,12 +831,24 @@ class ClassLinker {
REQUIRES(!Locks::classlinker_classes_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- void RegisterDexFileLocked(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache)
+ void RegisterDexFileLocked(const DexFile& dex_file,
+ ObjPtr<mirror::DexCache> dex_cache,
+ ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES(Locks::dex_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- mirror::DexCache* FindDexCacheLocked(Thread* self, const DexFile& dex_file, bool allow_failure)
+ 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_);
bool InitializeClass(Thread* self,
Handle<mirror::Class> klass,