Do not reset SirtRef pointing to a live object
ClassLinker::FindClass reset the klass SirtRef to point to the
existing Class value. However, the old value was still referenced by
the ObjectLock. In the rare case of a two thread resolving the same
class at the same time and a garbage collection happening, the
ObjectLock would point to freed memory.
Change-Id: I93dbbfe3e5d7a8922464242270ac90c71a125e47
diff --git a/src/class_linker.cc b/src/class_linker.cc
index e8700be..80dd7eb 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1251,12 +1251,10 @@
ObjectLock lock(klass.get());
klass->SetClinitThreadId(self->GetTid());
// Add the newly loaded class to the loaded classes table.
- Class* existing = InsertClass(descriptor, klass.get(), false);
- if (existing != NULL) {
+ SirtRef<Class> existing(InsertClass(descriptor, klass.get(), false));
+ if (existing.get() != NULL) {
// We failed to insert because we raced with another thread.
- klass->SetClinitThreadId(0);
- klass.reset(existing);
- return EnsureResolved(klass.get());
+ return EnsureResolved(existing.get());
}
// Finish loading (if necessary) by finding parents
CHECK(!klass->IsLoaded());