Fix concurrent start bytes race

Previously, we set concurrent start bytes to max int when we
requested a concurrent GC, but there was a race if another thread
was doing another GC and had already completed GrowForUtilization
but had not yet finished the GC. This meant that the thread doing
the GC would update the concurrent start bytes properly, but the
allocating thread would re-update it to max int. Then when the
concurrent GC thread woke up, it would call WaitForGcToComplete
and see that there was a collector running and avoid doing the
concurrent GC, leaving the concurrent start bytes set to max int.

This meant that there would be no more concurrent GC until either
the next explicit GC or the next GC for alloc.

The fix is to only set concurrent start bytes to max int inside of
the CollectGarbageInternal code such that there isn't any way for
two threads to race.

Bug: 17942071

(cherry picked from commit 0133ec454d8dd3fa5ffe35649b5704aa18f15a49)

Change-Id: Ibc23dd2f937a2b5fda51ed064634c034dbb6e668
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index c2baa29..ae37d7c 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2138,6 +2138,13 @@
   } else {
     LOG(FATAL) << "Invalid current allocator " << current_allocator_;
   }
+  if (IsGcConcurrent()) {
+    // Disable concurrent GC check so that we don't have spammy JNI requests.
+    // This gets recalculated in GrowForUtilization. It is important that it is disabled /
+    // calculated in the same thread so that there aren't any races that can cause it to become
+    // permanantly disabled. b/17942071
+    concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
+  }
   CHECK(collector != nullptr)
       << "Could not find garbage collector with collector_type="
       << static_cast<size_t>(collector_type_) << " and gc_type=" << gc_type;
@@ -2956,9 +2963,6 @@
       self->IsHandlingStackOverflow()) {
     return;
   }
-  // We already have a request pending, no reason to start more until we update
-  // concurrent_start_bytes_.
-  concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
   JNIEnv* env = self->GetJniEnv();
   DCHECK(WellKnownClasses::java_lang_Daemons != nullptr);
   DCHECK(WellKnownClasses::java_lang_Daemons_requestGC != nullptr);