summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Lokesh Gidra <lokeshgidra@google.com> 2023-09-08 21:46:57 +0000
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2023-09-12 08:25:52 +0000
commit82d1afc3d654823a4f0c6fbefc3da52575ac0370 (patch)
tree7529f16225593dca3076212de92332ab69c7adf5 /runtime/class_linker.cc
parent0be0fbc85ce7c099d90b1cb220c5ccff20b0f3a2 (diff)
Delete all allocators after deleting class loaders
As things are currently, we could have a situation wherein the interface of some class is on a different class-loader, and both loaders are being deleted. If the interface's loader is deleted first, then we get a NPE in ResetSingleImplementationInHierarchy() while accessing interface's art-methods. Bug: 298575095 Test: manual Change-Id: Ib14180bc92d18916fd0c44e0d6c59dfca2f28466
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc19
1 files changed, 13 insertions, 6 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a476ed67cc..1edb694a1d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2631,7 +2631,11 @@ ClassLinker::~ClassLinker() {
for (const ClassLoaderData& data : class_loaders_) {
// CHA unloading analysis is not needed. No negative consequences are expected because
// all the classloaders are deleted at the same time.
- DeleteClassLoader(self, data, /*cleanup_cha=*/ false);
+ PrepareToDeleteClassLoader(self, data, /*cleanup_cha=*/false);
+ }
+ for (const ClassLoaderData& data : class_loaders_) {
+ delete data.allocator;
+ delete data.class_table;
}
class_loaders_.clear();
while (!running_visibly_initialized_callbacks_.empty()) {
@@ -2641,7 +2645,9 @@ ClassLinker::~ClassLinker() {
}
}
-void ClassLinker::DeleteClassLoader(Thread* self, const ClassLoaderData& data, bool cleanup_cha) {
+void ClassLinker::PrepareToDeleteClassLoader(Thread* self,
+ const ClassLoaderData& data,
+ bool cleanup_cha) {
Runtime* const runtime = Runtime::Current();
JavaVMExt* const vm = runtime->GetJavaVM();
vm->DeleteWeakGlobalRef(self, data.weak_root);
@@ -2672,9 +2678,6 @@ void ClassLinker::DeleteClassLoader(Thread* self, const ClassLoaderData& data, b
}
}
}
-
- delete data.allocator;
- delete data.class_table;
}
ObjPtr<mirror::PointerArray> ClassLinker::AllocPointerArray(Thread* self, size_t length) {
@@ -10864,9 +10867,13 @@ void ClassLinker::CleanupClassLoaders() {
ScopedDebugDisallowReadBarriers sddrb(self);
for (ClassLoaderData& data : to_delete) {
// CHA unloading analysis and SingleImplementaion cleanups are required.
- DeleteClassLoader(self, data, /*cleanup_cha=*/ true);
+ PrepareToDeleteClassLoader(self, data, /*cleanup_cha=*/true);
}
}
+ for (const ClassLoaderData& data : to_delete) {
+ delete data.allocator;
+ delete data.class_table;
+ }
Runtime* runtime = Runtime::Current();
if (!unregistered_oat_files.empty()) {
for (const OatFile* oat_file : unregistered_oat_files) {