Use try lock to fix class resolution race
There was some possible deadlocks related to EnsureResolved caused by
acquiring an object lock.
Scenario:
Thread 1 acquires lock on obj1
Thread 1 begins to resolve / initialize class1
Thread 1 blocks since it sees that class1 is already being resolved and
gets preempted before it can acquire the object lock on class1
Thread 2 finishes resolving and initializing class1 and locks class1
Thread 2 blocks attempting to lock obj1
Thread 1 blocks attempting to lock class1
Deadlock
Fixed the deadlock by changing EnsureResolved to use a try lock for the
unresolved case.
Added a test.
Test: Device boot, test-art-host, monitor_test
Bug: 27417671
Change-Id: Ic6e1c3ca6f45490cf8a7bf8e137dee71ac83ff64
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 76a36ac..e1097fa 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -106,7 +106,11 @@
}
inline mirror::Object* Object::MonitorEnter(Thread* self) {
- return Monitor::MonitorEnter(self, this);
+ return Monitor::MonitorEnter(self, this, /*trylock*/false);
+}
+
+inline mirror::Object* Object::MonitorTryEnter(Thread* self) {
+ return Monitor::MonitorEnter(self, this, /*trylock*/true);
}
inline bool Object::MonitorExit(Thread* self) {