Avoid race on Thread::tlsPtr_::top_handle_scope.

Require mutator lock for that field and update tests to hold
the mutator lock when needed. This prevents GC thread that
executes a thread roots flip on behalf of suspended threads
from racing against construction or destruction of handle
scopes by those threads and possibly seeing invalid values.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 189439174
Change-Id: I268a0ef6e5aa838347956febca0d3b6e02fe3ae5
diff --git a/runtime/handle_scope-inl.h b/runtime/handle_scope-inl.h
index cb0333f..3aa9e52 100644
--- a/runtime/handle_scope-inl.h
+++ b/runtime/handle_scope-inl.h
@@ -44,26 +44,22 @@
 }
 
 template<size_t kNumReferences>
-inline FixedSizeHandleScope<kNumReferences>::FixedSizeHandleScope(BaseHandleScope* link)
-    : HandleScope(link, kNumReferences) {
-  static_assert(kNumReferences >= 1, "FixedSizeHandleScope must contain at least 1 reference");
-  DCHECK_EQ(&storage_[0], GetReferences());  // TODO: Figure out how to use a compile assert.
-  for (size_t i = 0; i < kNumReferences; ++i) {
-    SetReferenceToNull(i);
-  }
-}
-
-template<size_t kNumReferences>
 inline StackHandleScope<kNumReferences>::StackHandleScope(Thread* self,
                                                           ObjPtr<mirror::Object> fill_value)
     : FixedSizeHandleScope<kNumReferences>(self->GetTopHandleScope(), fill_value),
       self_(self) {
   DCHECK_EQ(self, Thread::Current());
+  if (kDebugLocking) {
+    Locks::mutator_lock_->AssertSharedHeld(self_);
+  }
   self_->PushHandleScope(this);
 }
 
 template<size_t kNumReferences>
 inline StackHandleScope<kNumReferences>::~StackHandleScope() {
+  if (kDebugLocking) {
+    Locks::mutator_lock_->AssertSharedHeld(self_);
+  }
   BaseHandleScope* top_handle_scope = self_->PopHandleScope();
   DCHECK_EQ(top_handle_scope, this);
 }
@@ -161,12 +157,6 @@
   GetReferences()[i].Assign(object);
 }
 
-template<size_t kNumReferences>
-inline void FixedSizeHandleScope<kNumReferences>::SetReferenceToNull(size_t i) {
-  DCHECK_LT(i, kNumReferences);
-  GetReferences()[i].Assign(nullptr);
-}
-
 // Number of references contained within this handle scope.
 inline uint32_t BaseHandleScope::NumberOfReferences() const {
   return LIKELY(!IsVariableSized())
@@ -227,10 +217,17 @@
       self_(self),
       current_scope_(&first_scope_),
       first_scope_(/*link=*/ nullptr) {
+  DCHECK_EQ(self, Thread::Current());
+  if (kDebugLocking) {
+    Locks::mutator_lock_->AssertSharedHeld(self_);
+  }
   self_->PushHandleScope(this);
 }
 
 inline VariableSizedHandleScope::~VariableSizedHandleScope() {
+  if (kDebugLocking) {
+    Locks::mutator_lock_->AssertSharedHeld(self_);
+  }
   BaseHandleScope* top_handle_scope = self_->PopHandleScope();
   DCHECK_EQ(top_handle_scope, this);
   // Don't delete first_scope_ since it is not heap allocated.