summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-10-09 01:26:12 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-10-09 01:26:12 +0000
commitf3baa36fe2cc9d4942e5f84f25ef737d06994501 (patch)
tree8a360fd8ca85f2809f9a018c26ee575302afbdcc
parent1c2f38b9795138b4afb6736003558a989e433b03 (diff)
parent22e0ce3a73760757e509032a324bbbb9a1a93f5e (diff)
downloadart-f3baa36fe2cc9d4942e5f84f25ef737d06994501.tar.gz
art-f3baa36fe2cc9d4942e5f84f25ef737d06994501.tar.bz2
art-f3baa36fe2cc9d4942e5f84f25ef737d06994501.zip
am 22e0ce3a: DO NOT MERGE Add locking to prevent races between setting class methods and marking
* commit '22e0ce3a73760757e509032a324bbbb9a1a93f5e': DO NOT MERGE Add locking to prevent races between setting class methods and marking
-rw-r--r--runtime/class_linker.cc37
1 files changed, 25 insertions, 12 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 9ca6492fb1..d0e8e6828f 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2334,15 +2334,22 @@ void ClassLinker::LoadClassMembers(Thread* self, const DexFile& dex_file,
klass->SetIFields(ifields);
klass->SetNumInstanceFields(num_ifields);
DCHECK_EQ(klass->NumInstanceFields(), num_ifields);
- // Load methods.
- if (it.NumDirectMethods() != 0) {
- klass->SetDirectMethodsPtr(AllocArtMethodArray(self, it.NumDirectMethods()));
- }
- klass->SetNumDirectMethods(it.NumDirectMethods());
- if (it.NumVirtualMethods() != 0) {
- klass->SetVirtualMethodsPtr(AllocArtMethodArray(self, it.NumVirtualMethods()));
+ ArtMethod* const direct_methods = (it.NumDirectMethods() != 0)
+ ? AllocArtMethodArray(self, it.NumDirectMethods())
+ : nullptr;
+ ArtMethod* const virtual_methods = (it.NumVirtualMethods() != 0)
+ ? AllocArtMethodArray(self, it.NumVirtualMethods())
+ : nullptr;
+ {
+ // Used to get exclusion between with VisitNativeRoots so that no thread sees a length for
+ // one array with a pointer for a different array.
+ WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
+ // Load methods.
+ klass->SetDirectMethodsPtr(direct_methods);
+ klass->SetNumDirectMethods(it.NumDirectMethods());
+ klass->SetVirtualMethodsPtr(virtual_methods);
+ klass->SetNumVirtualMethods(it.NumVirtualMethods());
}
- klass->SetNumVirtualMethods(it.NumVirtualMethods());
size_t class_def_method_index = 0;
uint32_t last_dex_method_index = DexFile::kDexNoIndex;
size_t last_class_def_method_index = 0;
@@ -3321,8 +3328,11 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
self->AssertPendingOOMException();
return nullptr;
}
- klass->SetDirectMethodsPtr(directs);
- klass->SetNumDirectMethods(1u);
+ {
+ WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
+ klass->SetDirectMethodsPtr(directs);
+ klass->SetNumDirectMethods(1u);
+ }
CreateProxyConstructor(klass, klass->GetDirectMethodUnchecked(0, image_pointer_size_));
// Create virtual method using specified prototypes.
@@ -3337,8 +3347,11 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
self->AssertPendingOOMException();
return nullptr;
}
- klass->SetVirtualMethodsPtr(virtuals);
- klass->SetNumVirtualMethods(num_virtual_methods);
+ {
+ WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
+ klass->SetVirtualMethodsPtr(virtuals);
+ klass->SetNumVirtualMethods(num_virtual_methods);
+ }
for (size_t i = 0; i < num_virtual_methods; ++i) {
auto* virtual_method = klass->GetVirtualMethodUnchecked(i, image_pointer_size_);
auto* prototype = h_methods->Get(i)->GetArtMethod();