Revert^2 "Add hooks in palette for reporting JNI invocations."

Test: test.py
Bug: 140968481

Change-Id: I3ebbec153040b9bcfe4fb86618c15d2f9c93abb6
diff --git a/libartpalette/Android.bp b/libartpalette/Android.bp
index 66e8bda..e8b7fd8 100644
--- a/libartpalette/Android.bp
+++ b/libartpalette/Android.bp
@@ -54,7 +54,10 @@
         // support both prebuilts and sources present simultaneously.
         "//prebuilts/module_sdk/art/current/host-exports",
     ],
-    header_libs: ["libbase_headers"],
+    header_libs: [
+        "libbase_headers",
+        "jni_headers",
+    ],
     target: {
         // Targets supporting dlopen build the client library which loads
         // and binds the methods in the libartpalette-system library.
diff --git a/libartpalette/include/palette/palette_hooks.h b/libartpalette/include/palette/palette_hooks.h
index 14e7b3f..40e09fa 100644
--- a/libartpalette/include/palette/palette_hooks.h
+++ b/libartpalette/include/palette/palette_hooks.h
@@ -19,6 +19,8 @@
 
 #include "palette_types.h"
 
+#include "jni.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif  // __cplusplus
@@ -39,6 +41,15 @@
 
   // Notify the Hooks object that the runtime is loading a .oat file.
   void (*NotifyOatFileLoaded)(const char* path);
+
+  // Whether to report JNI method entry/exit.
+  int (*ShouldReportJniInvocations)();
+
+  // Notify the Hooks object that a native call is starting.
+  void (*NotifyBeginJniInvocation)(JNIEnv* env);
+
+  // Notify the Hooks object that a native call is ending.
+  void (*NotifyEndJniInvocation)(JNIEnv* env);
 } paletteHooksInterface;
 
 struct PaletteHooks {
@@ -56,6 +67,15 @@
   void NotifyOatFileLoaded(const char* path) {
     return functions->NotifyOatFileLoaded(path);
   }
+  int ShouldReportJniInvocations() {
+    return functions->ShouldReportJniInvocations();
+  }
+  void NotifyBeginJniInvocation(JNIEnv* env) {
+    return functions->NotifyBeginJniInvocation(env);
+  }
+  void NotifyEndJniInvocation(JNIEnv* env) {
+    return functions->NotifyEndJniInvocation(env);
+  }
 #endif
 };
 
diff --git a/runtime/entrypoints/quick/quick_default_init_entrypoints.h b/runtime/entrypoints/quick/quick_default_init_entrypoints.h
index ae9bdd6..d74561d 100644
--- a/runtime/entrypoints/quick/quick_default_init_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_default_init_entrypoints.h
@@ -20,6 +20,7 @@
 #include "base/logging.h"  // FOR VLOG_IS_ON.
 #include "entrypoints/jni/jni_entrypoints.h"
 #include "entrypoints/runtime_asm_entrypoints.h"
+#include "palette/palette.h"
 #include "quick_alloc_entrypoints.h"
 #include "quick_default_externs.h"
 #include "quick_entrypoints.h"
@@ -129,6 +130,17 @@
   // Tiered JIT support
   qpoints->pUpdateInlineCache = art_quick_update_inline_cache;
   qpoints->pCompileOptimized = art_quick_compile_optimized;
+
+  PaletteHooks* hooks = nullptr;
+  if (PaletteGetHooks(&hooks) == PALETTE_STATUS_OK && hooks->ShouldReportJniInvocations()) {
+    qpoints->pJniMethodStart = JniMonitoredMethodStart;
+    qpoints->pJniMethodStartSynchronized = JniMonitoredMethodStartSynchronized;
+    qpoints->pJniMethodEnd = JniMonitoredMethodEnd;
+    qpoints->pJniMethodEndSynchronized = JniMonitoredMethodEndSynchronized;
+    qpoints->pJniMethodEndWithReference = JniMonitoredMethodEndWithReference;
+    qpoints->pJniMethodEndWithReferenceSynchronized =
+        JniMonitoredMethodEndWithReferenceSynchronized;
+  }
 }
 
 }  // namespace art
diff --git a/runtime/entrypoints/quick/quick_entrypoints.h b/runtime/entrypoints/quick/quick_entrypoints.h
index d9fbbc7..d41a276 100644
--- a/runtime/entrypoints/quick/quick_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_entrypoints.h
@@ -79,6 +79,28 @@
                                                              jobject locked, Thread* self)
     NO_THREAD_SAFETY_ANALYSIS HOT_ATTR;
 
+// JNI entrypoints when monitoring entry/exit.
+extern uint32_t JniMonitoredMethodStart(Thread* self) NO_THREAD_SAFETY_ANALYSIS HOT_ATTR;
+extern uint32_t JniMonitoredMethodStartSynchronized(jobject to_lock, Thread* self)
+    NO_THREAD_SAFETY_ANALYSIS HOT_ATTR;
+extern void JniMonitoredMethodEnd(uint32_t saved_local_ref_cookie, Thread* self)
+    NO_THREAD_SAFETY_ANALYSIS HOT_ATTR;
+extern void JniMonitoredMethodEndSynchronized(uint32_t saved_local_ref_cookie,
+                                              jobject locked,
+                                              Thread* self)
+    NO_THREAD_SAFETY_ANALYSIS HOT_ATTR;
+extern mirror::Object* JniMonitoredMethodEndWithReference(jobject result,
+                                                          uint32_t saved_local_ref_cookie,
+                                                          Thread* self)
+    NO_THREAD_SAFETY_ANALYSIS HOT_ATTR;
+
+extern mirror::Object* JniMonitoredMethodEndWithReferenceSynchronized(
+    jobject result,
+    uint32_t saved_local_ref_cookie,
+    jobject locked, Thread* self)
+    NO_THREAD_SAFETY_ANALYSIS HOT_ATTR;
+
+
 extern "C" mirror::String* artStringBuilderAppend(uint32_t format,
                                                   const uint32_t* args,
                                                   Thread* self)
@@ -88,7 +110,6 @@
                            Thread* self)
     NO_THREAD_SAFETY_ANALYSIS HOT_ATTR;
 
-
 // Read barrier entrypoints.
 //
 // Compilers for ARM, ARM64 can insert a call to these
diff --git a/runtime/entrypoints/quick/quick_jni_entrypoints.cc b/runtime/entrypoints/quick/quick_jni_entrypoints.cc
index 7d55817..82ec04b 100644
--- a/runtime/entrypoints/quick/quick_jni_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_jni_entrypoints.cc
@@ -21,9 +21,20 @@
 #include "entrypoints/entrypoint_utils-inl.h"
 #include "indirect_reference_table.h"
 #include "mirror/object-inl.h"
+#include "palette/palette.h"
+#include "palette/palette_hooks.h"
 #include "thread-inl.h"
 #include "verify_object.h"
 
+// For methods that monitor JNI invocations and report their begin/end to
+// palette hooks.
+#define MONITOR_JNI(kind)                               \
+  PaletteHooks* hooks = nullptr;                        \
+  if (PaletteGetHooks(&hooks) == PALETTE_STATUS_OK &&   \
+      hooks->ShouldReportJniInvocations()) {            \
+    hooks->kind(self->GetJniEnv());                     \
+  }                                                     \
+
 namespace art {
 
 static_assert(sizeof(IRTSegmentState) == sizeof(uint32_t), "IRTSegmentState size unexpected");
@@ -224,6 +235,7 @@
   // @CriticalNative does not do a state transition. @FastNative usually does not do a state
   // transition either but it performs a suspend check that may do state transitions.
   if (LIKELY(normal_native)) {
+    MONITOR_JNI(NotifyEndJniInvocation);
     GoToRunnable(self);
   } else if (fast_native) {
     GoToRunnableFast(self);
@@ -277,4 +289,44 @@
   }
 }
 
+extern uint32_t JniMonitoredMethodStart(Thread* self) {
+  uint32_t result = JniMethodStart(self);
+  MONITOR_JNI(NotifyBeginJniInvocation);
+  return result;
+}
+
+extern uint32_t JniMonitoredMethodStartSynchronized(jobject to_lock, Thread* self) {
+  uint32_t result = JniMethodStartSynchronized(to_lock, self);
+  MONITOR_JNI(NotifyBeginJniInvocation);
+  return result;
+}
+
+extern void JniMonitoredMethodEnd(uint32_t saved_local_ref_cookie, Thread* self) {
+  MONITOR_JNI(NotifyEndJniInvocation);
+  return JniMethodEnd(saved_local_ref_cookie, self);
+}
+
+extern void JniMonitoredMethodEndSynchronized(uint32_t saved_local_ref_cookie,
+                                             jobject locked,
+                                             Thread* self) {
+  MONITOR_JNI(NotifyEndJniInvocation);
+  return JniMethodEndSynchronized(saved_local_ref_cookie, locked, self);
+}
+
+extern mirror::Object* JniMonitoredMethodEndWithReference(jobject result,
+                                                          uint32_t saved_local_ref_cookie,
+                                                          Thread* self) {
+  MONITOR_JNI(NotifyEndJniInvocation);
+  return JniMethodEndWithReference(result, saved_local_ref_cookie, self);
+}
+
+extern mirror::Object* JniMonitoredMethodEndWithReferenceSynchronized(
+    jobject result,
+    uint32_t saved_local_ref_cookie,
+    jobject locked,
+    Thread* self) {
+  MONITOR_JNI(NotifyEndJniInvocation);
+  return JniMethodEndWithReferenceSynchronized(result, saved_local_ref_cookie, locked, self);
+}
+
 }  // namespace art