Revert "Revert "Hold dex caches live in class table""
Bug: 29083330
This reverts commit f102faf1bcbdb2149e3e7bf27b1819f621b7894b.
(cherry picked from commit c9dbb1df3b5c06ba122cacaf35b17cb53c6be3c6)
Change-Id: Ib5d82bde2e4a031c1cab0ea6116925ef99d9f07f
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 9e144dd..0a5874b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2469,9 +2469,7 @@
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;
@@ -3230,7 +3228,8 @@
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_);
@@ -3239,21 +3238,31 @@
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;
+ {
+ 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);
}
- if (h_dex_cache.Get() == nullptr) {
- self->AssertPendingOOMException();
- return nullptr;
- }
- RegisterDexFileLocked(dex_file, h_dex_cache);
+ table->InsertStrongRoot(h_dex_cache.Get());
return h_dex_cache.Get();
}
@@ -7973,6 +7982,16 @@
find_array_class_cache_next_victim_ = 0;
}
+void ClassLinker::ClearClassTableStrongRoots() const {
+ Thread* const self = Thread::Current();
+ WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
+ for (const ClassLoaderData& data : class_loaders_) {
+ if (data.class_table != nullptr) {
+ data.class_table->ClearStrongRoots();
+ }
+ }
+}
+
void ClassLinker::VisitClassLoaders(ClassLoaderVisitor* visitor) const {
Thread* const self = Thread::Current();
for (const ClassLoaderData& data : class_loaders_) {
@@ -7991,7 +8010,7 @@
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);