Emit JVMTI events for LockSupport.park

This restores the behavior from when park was implemented with
wait/notify, except that the blocker object is used as the monitor
rather than the Thread that is parking.

Bug: 28845097
Tested: ./test/run-test --jvm 1931

Change-Id: I523d719ca3e49a538c06f48f032b322fb91e147e
diff --git a/runtime/runtime_callbacks.cc b/runtime/runtime_callbacks.cc
index 758917c..bf74816 100644
--- a/runtime/runtime_callbacks.cc
+++ b/runtime/runtime_callbacks.cc
@@ -151,6 +151,26 @@
   Remove(cb, &monitor_callbacks_);
 }
 
+void RuntimeCallbacks::ThreadParkStart(bool is_absolute, int64_t timeout) {
+  for (ParkCallback * cb : park_callbacks_) {
+    cb->ThreadParkStart(is_absolute, timeout);
+  }
+}
+
+void RuntimeCallbacks::ThreadParkFinished(bool timeout) {
+  for (ParkCallback * cb : park_callbacks_) {
+    cb->ThreadParkFinished(timeout);
+  }
+}
+
+void RuntimeCallbacks::AddParkCallback(ParkCallback* cb) {
+  park_callbacks_.push_back(cb);
+}
+
+void RuntimeCallbacks::RemoveParkCallback(ParkCallback* cb) {
+  Remove(cb, &park_callbacks_);
+}
+
 void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
   Remove(cb, &thread_callbacks_);
 }
diff --git a/runtime/runtime_callbacks.h b/runtime/runtime_callbacks.h
index 9f0410d..4cce15e 100644
--- a/runtime/runtime_callbacks.h
+++ b/runtime/runtime_callbacks.h
@@ -115,6 +115,19 @@
   virtual ~MonitorCallback() {}
 };
 
+class ParkCallback {
+ public:
+  // Called on entry to the Unsafe.#park method
+  virtual void ThreadParkStart(bool is_absolute, int64_t millis_timeout)
+      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
+
+  // Called just after the thread has woken up from going to sleep for a park(). This will only be
+  // called for Unsafe.park() calls where the thread did (or at least could have) gone to sleep.
+  virtual void ThreadParkFinished(bool timed_out) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
+
+  virtual ~ParkCallback() {}
+};
+
 // A callback to let parts of the runtime note that they are currently relying on a particular
 // method remaining in it's current state. Users should not rely on always being called. If multiple
 // callbacks are added the runtime will short-circuit when the first one returns 'true'.
@@ -193,6 +206,11 @@
   void AddMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
   void RemoveMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
 
+  void ThreadParkStart(bool is_absolute, int64_t timeout) REQUIRES_SHARED(Locks::mutator_lock_);
+  void ThreadParkFinished(bool timed_out) REQUIRES_SHARED(Locks::mutator_lock_);
+  void AddParkCallback(ParkCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
+  void RemoveParkCallback(ParkCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
+
   // Returns true if some MethodInspectionCallback indicates the method is being inspected/depended
   // on by some code.
   bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -243,6 +261,8 @@
       GUARDED_BY(Locks::mutator_lock_);
   std::vector<MonitorCallback*> monitor_callbacks_
       GUARDED_BY(Locks::mutator_lock_);
+  std::vector<ParkCallback*> park_callbacks_
+      GUARDED_BY(Locks::mutator_lock_);
   std::vector<MethodInspectionCallback*> method_inspection_callbacks_
       GUARDED_BY(Locks::mutator_lock_);
   std::vector<DdmCallback*> ddm_callbacks_
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 7a06be9..e9fed76 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -302,8 +302,9 @@
   int old_state = tls32_.park_state_.fetch_add(1, std::memory_order_relaxed);
   if (old_state == kNoPermit) {
     // no permit was available. block thread until later.
-    // TODO: Call to signal jvmti here
+    Runtime::Current()->GetRuntimeCallbacks()->ThreadParkStart(is_absolute, time);
     int result = 0;
+    bool timed_out = false;
     if (!is_absolute && time == 0) {
       // Thread.getState() is documented to return waiting for untimed parks.
       ScopedThreadSuspension sts(this, ThreadState::kWaiting);
@@ -351,8 +352,10 @@
     }
     if (result == -1) {
       switch (errno) {
-        case EAGAIN:
         case ETIMEDOUT:
+          timed_out = true;
+          FALLTHROUGH_INTENDED;
+        case EAGAIN:
         case EINTR: break;  // park() is allowed to spuriously return
         default: PLOG(FATAL) << "Failed to park";
       }
@@ -360,6 +363,7 @@
     // Mark as no longer waiting, and consume permit if there is one.
     tls32_.park_state_.store(kNoPermit, std::memory_order_relaxed);
     // TODO: Call to signal jvmti here
+    Runtime::Current()->GetRuntimeCallbacks()->ThreadParkFinished(timed_out);
   } else {
     // the fetch_add has consumed the permit. immediately return.
     DCHECK_EQ(old_state, kPermitAvailable);
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 94faa62..65039bc 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -122,6 +122,7 @@
 jfieldID WellKnownClasses::dalvik_system_DexPathList_dexElements;
 jfieldID WellKnownClasses::dalvik_system_DexPathList__Element_dexFile;
 jfieldID WellKnownClasses::dalvik_system_VMRuntime_nonSdkApiUsageConsumer;
+jfieldID WellKnownClasses::java_lang_Thread_parkBlocker;
 jfieldID WellKnownClasses::java_lang_Thread_daemon;
 jfieldID WellKnownClasses::java_lang_Thread_group;
 jfieldID WellKnownClasses::java_lang_Thread_lock;
@@ -371,6 +372,7 @@
   dalvik_system_DexPathList_dexElements = CacheField(env, dalvik_system_DexPathList, false, "dexElements", "[Ldalvik/system/DexPathList$Element;");
   dalvik_system_DexPathList__Element_dexFile = CacheField(env, dalvik_system_DexPathList__Element, false, "dexFile", "Ldalvik/system/DexFile;");
   dalvik_system_VMRuntime_nonSdkApiUsageConsumer = CacheField(env, dalvik_system_VMRuntime, true, "nonSdkApiUsageConsumer", "Ljava/util/function/Consumer;");
+  java_lang_Thread_parkBlocker = CacheField(env, java_lang_Thread, false, "parkBlocker", "Ljava/lang/Object;");
   java_lang_Thread_daemon = CacheField(env, java_lang_Thread, false, "daemon", "Z");
   java_lang_Thread_group = CacheField(env, java_lang_Thread, false, "group", "Ljava/lang/ThreadGroup;");
   java_lang_Thread_lock = CacheField(env, java_lang_Thread, false, "lock", "Ljava/lang/Object;");
@@ -518,6 +520,7 @@
   dalvik_system_DexPathList_dexElements = nullptr;
   dalvik_system_DexPathList__Element_dexFile = nullptr;
   dalvik_system_VMRuntime_nonSdkApiUsageConsumer = nullptr;
+  java_lang_Thread_parkBlocker = nullptr;
   java_lang_Thread_daemon = nullptr;
   java_lang_Thread_group = nullptr;
   java_lang_Thread_lock = nullptr;
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index 8c85228..130747c 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -131,6 +131,7 @@
   static jfieldID dalvik_system_DexPathList_dexElements;
   static jfieldID dalvik_system_DexPathList__Element_dexFile;
   static jfieldID dalvik_system_VMRuntime_nonSdkApiUsageConsumer;
+  static jfieldID java_lang_Thread_parkBlocker;
   static jfieldID java_lang_Thread_daemon;
   static jfieldID java_lang_Thread_group;
   static jfieldID java_lang_Thread_lock;