diff options
| -rw-r--r-- | runtime/cha.cc | 14 | ||||
| -rw-r--r-- | runtime/cha.h | 6 | ||||
| -rw-r--r-- | runtime/class_linker.cc | 5 |
3 files changed, 25 insertions, 0 deletions
diff --git a/runtime/cha.cc b/runtime/cha.cc index 8eeebf30ed..6c011e8e39 100644 --- a/runtime/cha.cc +++ b/runtime/cha.cc @@ -19,6 +19,7 @@ #include "art_method-inl.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" +#include "linear_alloc.h" #include "runtime.h" #include "scoped_thread_state_change-inl.h" #include "stack.h" @@ -581,4 +582,17 @@ void ClassHierarchyAnalysis::InvalidateSingleImplementationMethods( } } +void ClassHierarchyAnalysis::RemoveDependenciesForLinearAlloc(const LinearAlloc* linear_alloc) { + MutexLock mu(Thread::Current(), *Locks::cha_lock_); + for (auto it = cha_dependency_map_.begin(); it != cha_dependency_map_.end(); ) { + // Use unsafe to avoid locking since the allocator is going to be deleted. + if (linear_alloc->ContainsUnsafe(it->first)) { + // About to delete the ArtMethod, erase the entry from the map. + it = cha_dependency_map_.erase(it); + } else { + ++it; + } + } +} + } // namespace art diff --git a/runtime/cha.h b/runtime/cha.h index 99224e052b..40999dd15b 100644 --- a/runtime/cha.h +++ b/runtime/cha.h @@ -29,6 +29,7 @@ namespace art { class ArtMethod; +class LinearAlloc; /** * Class Hierarchy Analysis (CHA) tries to devirtualize virtual calls into @@ -112,6 +113,11 @@ class ClassHierarchyAnalysis { // Update CHA info for methods that `klass` overrides, after loading `klass`. void UpdateAfterLoadingOf(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); + // Remove all of the dependencies for a linear allocator. This is called when dex cache unloading + // occurs. + void RemoveDependenciesForLinearAlloc(const LinearAlloc* linear_alloc) + REQUIRES(!Locks::cha_lock_); + private: void InitSingleImplementationFlag(Handle<mirror::Class> klass, ArtMethod* method, diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index c5e11f134e..74c04d19b6 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2315,11 +2315,16 @@ void ClassLinker::DeleteClassLoader(Thread* self, const ClassLoaderData& data) { JavaVMExt* const vm = runtime->GetJavaVM(); vm->DeleteWeakGlobalRef(self, data.weak_root); // Notify the JIT that we need to remove the methods and/or profiling info. + ClassHierarchyAnalysis* const cha = runtime->GetClassHierarchyAnalysis(); if (runtime->GetJit() != nullptr) { jit::JitCodeCache* code_cache = runtime->GetJit()->GetCodeCache(); if (code_cache != nullptr) { + // For the JIT case, RemoveMethodsIn removes the CHA dependencies. code_cache->RemoveMethodsIn(self, *data.allocator); } + } else { + // If we don't have a JIT, we need to manually remove the CHA dependencies manually. + cha->RemoveDependenciesForLinearAlloc(data.allocator); } delete data.allocator; delete data.class_table; |