Fix race condition for method root marking in VisitNativeRoots
Only mark if non null, we may see a non zero length with a null
array due to race conditions with class loading.
Bug: 22077752
Change-Id: Icd37f70482efe320185d46ce4391aa0e0e43ff6f
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 7f89b1d..15f2887 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -832,11 +832,21 @@
f->VisitRoots(visitor);
}
}
- for (auto& m : GetDirectMethods(pointer_size)) {
- m.VisitRoots(visitor);
+ // We may see GetDirectMethodsPtr() == null with NumDirectMethods() != 0 if the root marking
+ // thread reads a null DirectMethodsBegin() but a non null DirectMethodsBegin() due to a race
+ // SetDirectMethodsPtr from class linking. Same for virtual methods.
+ // In this case, it is safe to avoid marking the roots since we must be either the CC or CMS. If
+ // we are CMS then the roots are already marked through other sources, otherwise the roots are
+ // already marked due to the to-space invariant.
+ if (GetDirectMethodsPtr() != nullptr) {
+ for (auto& m : GetDirectMethods(pointer_size)) {
+ m.VisitRoots(visitor);
+ }
}
- for (auto& m : GetVirtualMethods(pointer_size)) {
- m.VisitRoots(visitor);
+ if (GetVirtualMethodsPtr() != nullptr) {
+ for (auto& m : GetVirtualMethods(pointer_size)) {
+ m.VisitRoots(visitor);
+ }
}
}