From 4843bd5a0ba1d85e73f6e0ed7a24fa4a344cccb0 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Thu, 1 Oct 2015 17:08:44 -0700 Subject: [PATCH] Change DecodeWeakGlobal to DecodeJObject for class unloading DecodeWeakGlobal returns the sentinel object for cleared JNI weak globals. This was causing a memory leak since it wouldn't delete class tables and linear allocs due to never returning null. The bug was found by yamauchi. Bug: 22720414 Change-Id: Iff4681495232b9a9756dbdb51d10ea72691a85dd --- runtime/class_linker.cc | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index dbc5ceca0..b0590e25f 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2650,10 +2650,8 @@ mirror::DexCache* ClassLinker::FindDexCacheLocked(Thread* self, const DexFile& dex_file, bool allow_failure) { // Search assuming unique-ness of dex file. - JavaVMExt* const vm = self->GetJniEnv()->vm; for (jweak weak_root : dex_caches_) { - mirror::DexCache* dex_cache = down_cast( - vm->DecodeWeakGlobal(self, weak_root)); + mirror::DexCache* dex_cache = down_cast(self->DecodeJObject(weak_root)); if (dex_cache != nullptr && dex_cache->GetDexFile() == &dex_file) { return dex_cache; } @@ -6202,10 +6200,9 @@ void ClassLinker::DropFindArrayClassCache() { void ClassLinker::VisitClassLoaders(ClassLoaderVisitor* visitor) const { Thread* const self = Thread::Current(); - JavaVMExt* const vm = self->GetJniEnv()->vm; for (const ClassLoaderData& data : class_loaders_) { - auto* const class_loader = down_cast( - vm->DecodeWeakGlobal(self, data.weak_root)); + // Need to use DecodeJObject so that we get null for cleared JNI weak globals. + auto* const class_loader = down_cast(self->DecodeJObject(data.weak_root)); if (class_loader != nullptr) { visitor->Visit(class_loader); } @@ -6218,8 +6215,8 @@ void ClassLinker::CleanupClassLoaders() { JavaVMExt* const vm = Runtime::Current()->GetJavaVM(); for (auto it = class_loaders_.begin(); it != class_loaders_.end(); ) { const ClassLoaderData& data = *it; - auto* const class_loader = down_cast( - vm->DecodeWeakGlobal(self, data.weak_root)); + // Need to use DecodeJObject so that we get null for cleared JNI weak globals. + auto* const class_loader = down_cast(self->DecodeJObject(data.weak_root)); if (class_loader != nullptr) { ++it; } else { -- 2.11.0