Fix racy DCHECKS.

Added a size bracket lock to fix a race condition where we were
inserting into full_runs_ and non_full_runs_ holding a lock but
reading without holding a lock from a different thread.

Bug: 14326370
Change-Id: I5c492bddc4b9927e4a36603f3d787b046961675d
diff --git a/runtime/gc/allocator/rosalloc.cc b/runtime/gc/allocator/rosalloc.cc
index 821aa2d..ff59016 100644
--- a/runtime/gc/allocator/rosalloc.cc
+++ b/runtime/gc/allocator/rosalloc.cc
@@ -600,8 +600,12 @@
     // Use a thread-local run.
     Run* thread_local_run = reinterpret_cast<Run*>(self->GetRosAllocRun(idx));
     // Allow invalid since this will always fail the allocation.
-    DCHECK(non_full_runs_[idx].find(thread_local_run) == non_full_runs_[idx].end());
-    DCHECK(full_runs_[idx].find(thread_local_run) == full_runs_[idx].end());
+    if (kIsDebugBuild) {
+      // Need the lock to prevent race conditions.
+      MutexLock mu(self, *size_bracket_locks_[idx]);
+      CHECK(non_full_runs_[idx].find(thread_local_run) == non_full_runs_[idx].end());
+      CHECK(full_runs_[idx].find(thread_local_run) == full_runs_[idx].end());
+    }
     DCHECK(thread_local_run != nullptr);
     DCHECK(thread_local_run->IsThreadLocal() || thread_local_run == dedicated_full_run_);
     slot_addr = thread_local_run->AllocSlot();