Add more read barriers to the class linker.
This change makes it possible to concurrently scan the remaining roots
in the class linker (the non-class-table roots that are visited by
ClassLinker::VisitRoots()) by adding read barriers.
Bug: 12687968
Change-Id: I66fecf7a303eee7537429e018f38da8270b18c67
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 16e0ec3..a40a2e4 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -41,7 +41,8 @@
inline mirror::Class* ClassLinker::FindArrayClass(Thread* self, 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.
- mirror::Class* array_class = find_array_class_cache_[i];
+ mirror::Class* array_class = ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>(
+ &find_array_class_cache_[i]);
if (array_class != nullptr && array_class->GetComponentType() == *element_class) {
return array_class;
}
@@ -205,11 +206,20 @@
inline mirror::Class* ClassLinker::GetClassRoot(ClassRoot class_root)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(class_roots_ != NULL);
- mirror::Class* klass = class_roots_->Get(class_root);
+ mirror::ObjectArray<mirror::Class>* class_roots =
+ ReadBarrier::BarrierForRoot<mirror::ObjectArray<mirror::Class>, kWithReadBarrier>(
+ &class_roots_);
+ mirror::Class* klass = class_roots->Get(class_root);
DCHECK(klass != NULL);
return klass;
}
+inline mirror::DexCache* ClassLinker::GetDexCache(size_t idx) {
+ dex_lock_.AssertSharedHeld(Thread::Current());
+ DCHECK(idx < dex_caches_.size());
+ return ReadBarrier::BarrierForRoot<mirror::DexCache, kWithReadBarrier>(&dex_caches_[idx]);
+}
+
} // namespace art
#endif // ART_RUNTIME_CLASS_LINKER_INL_H_