Handle spurious wakeups in VerifyClass
Spurious wakeups in VerifyClass can cause the class status to be
the same as the old status. Relax the check to be >= to handle this.
Adding a regression test is infeasible since it is a hard to get a
thread in the "somebody else verifying" loop.
Test: test-art-host
Bug: 62912904
Change-Id: I308a395220507a875bb2fbf0800a14fabb434fda
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 928645a..10e0bd2 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4064,7 +4064,10 @@
while (old_status == mirror::Class::kStatusVerifying ||
old_status == mirror::Class::kStatusVerifyingAtRuntime) {
lock.WaitIgnoringInterrupts();
- CHECK(klass->IsErroneous() || (klass->GetStatus() > old_status))
+ // WaitIgnoringInterrupts can still receive an interrupt and return early, in this
+ // case we may see the same status again. b/62912904. This is why the check is
+ // greater or equal.
+ CHECK(klass->IsErroneous() || (klass->GetStatus() >= old_status))
<< "Class '" << klass->PrettyClass()
<< "' performed an illegal verification state transition from " << old_status
<< " to " << klass->GetStatus();