diff options
author | 2023-09-08 21:46:57 +0000 | |
---|---|---|
committer | 2023-09-12 08:25:52 +0000 | |
commit | 82d1afc3d654823a4f0c6fbefc3da52575ac0370 (patch) | |
tree | 7529f16225593dca3076212de92332ab69c7adf5 /runtime/class_linker.cc | |
parent | 0be0fbc85ce7c099d90b1cb220c5ccff20b0f3a2 (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.cc | 19 |
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) { |