diff options
author | Mathieu Chartier <mathieuc@google.com> | 2016-06-02 11:48:30 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2016-06-03 12:45:04 -0700 |
commit | d6d49e56c2b7b11f474acb80cb02bb1fe9b7861e (patch) | |
tree | b6df3e71798c9a547e56dcbe7d7b7a6f3dc003a2 /runtime/class_linker.cc | |
parent | b089eccf503646e6ed2d5bb20d973d9131166655 (diff) | |
download | android_art-d6d49e56c2b7b11f474acb80cb02bb1fe9b7861e.tar.gz android_art-d6d49e56c2b7b11f474acb80cb02bb1fe9b7861e.tar.bz2 android_art-d6d49e56c2b7b11f474acb80cb02bb1fe9b7861e.zip |
Hold dex caches live in class table
Prevents temporary dex caches being unloaded for the same dex file.
Usually this is OK, but if someone resolved a string in that dex
cache, it could leave stale pointers in BSS. Also it can use extra
memory in linear alloc if we allocate dex cache arrays multiple
times.
Bug: 29083330
(cherry picked from commit f284d448e3edd428b6ade473d0993028638b2064)
Change-Id: Ie1b0b0cf835a998e19227cbb90014011a6cd40c4
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index b369e10b41..abc51ca175 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2468,9 +2468,7 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, self->AssertPendingOOMException(); return nullptr; } - mirror::DexCache* dex_cache = RegisterDexFile( - dex_file, - GetOrCreateAllocatorForClassLoader(class_loader.Get())); + mirror::DexCache* dex_cache = RegisterDexFile(dex_file, class_loader.Get()); if (dex_cache == nullptr) { self->AssertPendingOOMException(); return nullptr; @@ -3229,7 +3227,8 @@ void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, dex_caches_.push_back(data); } -mirror::DexCache* ClassLinker::RegisterDexFile(const DexFile& dex_file, LinearAlloc* linear_alloc) { +mirror::DexCache* ClassLinker::RegisterDexFile(const DexFile& dex_file, + mirror::ClassLoader* class_loader) { Thread* self = Thread::Current(); { ReaderMutexLock mu(self, dex_lock_); @@ -3238,21 +3237,31 @@ mirror::DexCache* ClassLinker::RegisterDexFile(const DexFile& dex_file, LinearAl return dex_cache; } } + LinearAlloc* const linear_alloc = GetOrCreateAllocatorForClassLoader(class_loader); + DCHECK(linear_alloc != nullptr); + ClassTable* table; + { + WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); + table = InsertClassTableForClassLoader(class_loader); + } // Don't alloc while holding the lock, since allocation may need to // suspend all threads and another thread may need the dex_lock_ to // get to a suspend point. StackHandleScope<1> hs(self); Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(AllocDexCache(self, dex_file, linear_alloc))); - WriterMutexLock mu(self, dex_lock_); - mirror::DexCache* dex_cache = FindDexCacheLocked(self, dex_file, true); - if (dex_cache != nullptr) { - return dex_cache; - } - if (h_dex_cache.Get() == nullptr) { - self->AssertPendingOOMException(); - return nullptr; + { + WriterMutexLock mu(self, dex_lock_); + mirror::DexCache* dex_cache = FindDexCacheLocked(self, dex_file, true); + if (dex_cache != nullptr) { + return dex_cache; + } + if (h_dex_cache.Get() == nullptr) { + self->AssertPendingOOMException(); + return nullptr; + } + RegisterDexFileLocked(dex_file, h_dex_cache); } - RegisterDexFileLocked(dex_file, h_dex_cache); + table->InsertStrongRoot(h_dex_cache.Get()); return h_dex_cache.Get(); } @@ -7989,7 +7998,7 @@ void ClassLinker::InsertDexFileInToClassLoader(mirror::Object* dex_file, WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); ClassTable* const table = ClassTableForClassLoader(class_loader); DCHECK(table != nullptr); - if (table->InsertDexFile(dex_file) && class_loader != nullptr) { + if (table->InsertStrongRoot(dex_file) && class_loader != nullptr) { // It was not already inserted, perform the write barrier to let the GC know the class loader's // class table was modified. Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader); |