summaryrefslogtreecommitdiff
path: root/runtime/class_linker-inl.h
diff options
context:
space:
mode:
author Mythri Alle <mythria@google.com> 2024-06-25 09:53:44 +0000
committer Mythri Alle <mythria@google.com> 2024-07-10 08:48:50 +0000
commit894751180d273b68487f12f3532f24a219deb580 (patch)
treeb6e10df8f23bff068335098d248ae21cb0dc3dbe /runtime/class_linker-inl.h
parentd668220ac5d2fc06b7dce283a25da57c4227a95c (diff)
Use atomics for find_array_class_cache_
find_array_class_cache_ is used to cache the array classes. This is accessed concurrently by mutator threads that are looking for an array class. These threads both read entries and update the cache with the new array class if it wasn't found in the cache. GC also accesses this cache to clear it when visiting the roots of class linker. GC uses std::fill_n to clear the cache. Under ideal circumstances these operations could work as expected and the updates to each entry could be atomic. Though some valid compiler optimizations could break this and it is possible we see a partially initialized / cleared entry. To prevent these we use atomics to make it safe to access concurrently. Bug: 330843930 Test: art/test.py Change-Id: I493e0b0d47bf03603a4970855608cbe82a87c1a4
Diffstat (limited to 'runtime/class_linker-inl.h')
-rw-r--r--runtime/class_linker-inl.h6
1 files changed, 4 insertions, 2 deletions
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 6951e35791..6461f54f5f 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -43,7 +43,8 @@ inline ObjPtr<mirror::Class> ClassLinker::FindArrayClass(Thread* self,
ObjPtr<mirror::Class> element_class) {
for (size_t i = 0; i < kFindArrayCacheSize; ++i) {
// Read the cached array class once to avoid races with other threads setting it.
- ObjPtr<mirror::Class> array_class = find_array_class_cache_[i].Read();
+ ObjPtr<mirror::Class> array_class =
+ find_array_class_cache_[i].load(std::memory_order_acquire).Read();
if (array_class != nullptr && array_class->GetComponentType() == element_class) {
return array_class;
}
@@ -57,7 +58,8 @@ inline ObjPtr<mirror::Class> ClassLinker::FindArrayClass(Thread* self,
if (array_class != nullptr) {
// Benign races in storing array class and incrementing index.
size_t victim_index = find_array_class_cache_next_victim_;
- find_array_class_cache_[victim_index] = GcRoot<mirror::Class>(array_class);
+ find_array_class_cache_[victim_index].store(GcRoot<mirror::Class>(array_class),
+ std::memory_order_release);
find_array_class_cache_next_victim_ = (victim_index + 1) % kFindArrayCacheSize;
} else {
// We should have a NoClassDefFoundError.