Implement JVMTI can_signal_thread capability.

Implements the JVMTI can_signal_thread capability and all associated
methods and behaviors. This includes both the StopThread and
InterruptThread functions.

This CL contains the tests for the previous CL.

Test: ./test.py --host -j50
Test: stress --cpu 59 && while ./test/run-test --host 1934; do; done

Bug: 62821960
Bug: 34415266
Change-Id: I7b6fc37da0d2673caa993e486f078cf129d74c0f
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index 907b515..9a809df 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -949,4 +949,65 @@
   return OK;
 }
 
+jvmtiError ThreadUtil::StopThread(jvmtiEnv* env ATTRIBUTE_UNUSED,
+                                  jthread thread,
+                                  jobject exception) {
+  art::Thread* self = art::Thread::Current();
+  art::ScopedObjectAccess soa(self);
+  art::StackHandleScope<1> hs(self);
+  if (exception == nullptr) {
+    return ERR(INVALID_OBJECT);
+  }
+  art::ObjPtr<art::mirror::Object> obj(soa.Decode<art::mirror::Object>(exception));
+  if (!obj->GetClass()->IsThrowableClass()) {
+    return ERR(INVALID_OBJECT);
+  }
+  art::Handle<art::mirror::Throwable> exc(hs.NewHandle(obj->AsThrowable()));
+  art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
+  art::Thread* target = nullptr;
+  jvmtiError err = ERR(INTERNAL);
+  if (!GetAliveNativeThread(thread, soa, &target, &err)) {
+    return err;
+  } else if (target->GetState() == art::ThreadState::kStarting || target->IsStillStarting()) {
+    return ERR(THREAD_NOT_ALIVE);
+  }
+  struct StopThreadClosure : public art::Closure {
+   public:
+    explicit StopThreadClosure(art::Handle<art::mirror::Throwable> except) : exception_(except) { }
+
+    void Run(art::Thread* me) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+      // Make sure the thread is prepared to notice the exception.
+      art::Runtime::Current()->GetInstrumentation()->InstrumentThreadStack(me);
+      me->SetAsyncException(exception_.Get());
+      // Wake up the thread if it is sleeping.
+      me->Notify();
+    }
+
+   private:
+    art::Handle<art::mirror::Throwable> exception_;
+  };
+  StopThreadClosure c(exc);
+  if (target->RequestSynchronousCheckpoint(&c)) {
+    return OK;
+  } else {
+    // Something went wrong, probably the thread died.
+    return ERR(THREAD_NOT_ALIVE);
+  }
+}
+
+jvmtiError ThreadUtil::InterruptThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread thread) {
+  art::Thread* self = art::Thread::Current();
+  art::ScopedObjectAccess soa(self);
+  art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
+  art::Thread* target = nullptr;
+  jvmtiError err = ERR(INTERNAL);
+  if (!GetAliveNativeThread(thread, soa, &target, &err)) {
+    return err;
+  } else if (target->GetState() == art::ThreadState::kStarting || target->IsStillStarting()) {
+    return ERR(THREAD_NOT_ALIVE);
+  }
+  target->Interrupt(self);
+  return OK;
+}
+
 }  // namespace openjdkjvmti