Revert "Revert "Prevent races with GC when transferring objects between threads""

This reverts commit e5179ce0ca8becf34ba6e7b2f3988874fe647c26.

Reason for revert: Fixed issues with:
  Checkpoint flag set without pending checkpoint in parent CL.

Bug: 67838964
Test: ./test.py --host -j50

Change-Id: I7622f9c18866b58ee3cbd9f4fe38a29b2cf84a88
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index 99dea54..6d075a6 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -38,6 +38,9 @@
 #include "base/mutex.h"
 #include "events-inl.h"
 #include "gc/system_weak.h"
+#include "gc/collector_type.h"
+#include "gc/gc_cause.h"
+#include "gc/scoped_gc_critical_section.h"
 #include "gc_root-inl.h"
 #include "jni_internal.h"
 #include "mirror/class.h"
@@ -1061,7 +1064,7 @@
   };
   StopThreadClosure c(exc);
   // RequestSynchronousCheckpoint releases the thread_list_lock_ as a part of its execution.
-  if (target->RequestSynchronousCheckpoint(&c)) {
+  if (RequestGCSafeSynchronousCheckpoint(target, &c)) {
     return OK;
   } else {
     // Something went wrong, probably the thread died.
@@ -1084,4 +1087,29 @@
   return OK;
 }
 
+class GcCriticalSectionClosure : public art::Closure {
+ public:
+  explicit GcCriticalSectionClosure(art::Closure* wrapped) : wrapped_(wrapped) {}
+
+  void Run(art::Thread* self) OVERRIDE {
+    if (art::kIsDebugBuild) {
+      art::Locks::thread_list_lock_->AssertNotHeld(art::Thread::Current());
+    }
+    // This might block as it waits for any in-progress GCs to finish but this is fine since we
+    // released the Thread-list-lock prior to calling this in RequestSynchronousCheckpoint.
+    art::gc::ScopedGCCriticalSection sgccs(art::Thread::Current(),
+                                           art::gc::kGcCauseDebugger,
+                                           art::gc::kCollectorTypeDebugger);
+    wrapped_->Run(self);
+  }
+
+ private:
+  art::Closure* wrapped_;
+};
+
+bool ThreadUtil::RequestGCSafeSynchronousCheckpoint(art::Thread* thr, art::Closure* function) {
+  GcCriticalSectionClosure gccsc(function);
+  return thr->RequestSynchronousCheckpoint(&gccsc);
+}
+
 }  // namespace openjdkjvmti