Issue 5177609: remove Monitor(Enter|Exit)Helper

Add necessary indirection for synchronized native methods that
lock/unlock the object/class using the regular JNI MonitorEnter/Exit
functions.

Change-Id: I00cda7284fcfa09e1218ddbfb1e24ea4aaa94ac3
diff --git a/src/assembler_arm.cc b/src/assembler_arm.cc
index c13db39..2022ee9 100644
--- a/src/assembler_arm.cc
+++ b/src/assembler_arm.cc
@@ -1499,6 +1499,13 @@
                  base.AsCoreRegister(), offs.Int32Value());
 }
 
+void Assembler::LoadRawPtr(ManagedRegister dest, ManagedRegister base,
+                           Offset offs) {
+  CHECK(dest.IsCoreRegister() && dest.IsCoreRegister());
+  LoadFromOffset(kLoadWord, dest.AsCoreRegister(),
+                 base.AsCoreRegister(), offs.Int32Value());
+}
+
 void Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
                                       ManagedRegister scratch) {
   CHECK(scratch.IsCoreRegister());
diff --git a/src/assembler_arm.h b/src/assembler_arm.h
index 99ff9fe..bad3023 100644
--- a/src/assembler_arm.h
+++ b/src/assembler_arm.h
@@ -431,6 +431,7 @@
 
   void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch);
   void LoadRef(ManagedRegister dest, ManagedRegister base, MemberOffset offs);
+  void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs);
 
   void StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
                              ManagedRegister scratch);
diff --git a/src/assembler_x86.cc b/src/assembler_x86.cc
index b6183a9..693f1b4 100644
--- a/src/assembler_x86.cc
+++ b/src/assembler_x86.cc
@@ -1487,6 +1487,12 @@
   movl(dest.AsCpuRegister(), Address(base.AsCpuRegister(), offs));
 }
 
+void Assembler::LoadRawPtr(ManagedRegister dest, ManagedRegister base,
+                           Offset offs) {
+  CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
+  movl(dest.AsCpuRegister(), Address(base.AsCpuRegister(), offs));
+}
+
 void Assembler::LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset offs) {
   CHECK(dest.IsCpuRegister());
   fs()->movl(dest.AsCpuRegister(), Address::Absolute(offs));
diff --git a/src/assembler_x86.h b/src/assembler_x86.h
index 2c7f2d2..afccc4d 100644
--- a/src/assembler_x86.h
+++ b/src/assembler_x86.h
@@ -125,6 +125,10 @@
     Init(base, disp);
   }
 
+  Address(Register base, Offset disp) {
+    Init(base, disp.Int32Value());
+  }
+
   Address(Register base, FrameOffset disp) {
     CHECK_EQ(base, ESP);
     Init(ESP, disp.Int32Value());
@@ -442,6 +446,8 @@
 
   void LoadRef(ManagedRegister dest, ManagedRegister base, MemberOffset offs);
 
+  void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs);
+
   void LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset offs);
 
   void CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset thr_offs,
diff --git a/src/jni_compiler.cc b/src/jni_compiler.cc
index dd7d5e5..f3d13c8 100644
--- a/src/jni_compiler.cc
+++ b/src/jni_compiler.cc
@@ -25,6 +25,9 @@
   JniCallingConvention jni_conv(native_method);
   ManagedRuntimeCallingConvention mr_conv(native_method);
   const bool is_static = native_method->IsStatic();
+  static Offset functions(OFFSETOF_MEMBER(JNIEnvExt, fns));
+  static Offset monitor_enter(OFFSETOF_MEMBER(JNINativeInterface, MonitorEnter));
+  static Offset monitor_exit(OFFSETOF_MEMBER(JNINativeInterface, MonitorExit));
 
   // 1. Build the frame
   const size_t frame_size(jni_conv.FrameSize());
@@ -136,9 +139,10 @@
       FrameOffset out_off = jni_conv.CurrentParamStackOffset();
       jni_asm->StoreRawPtr(out_off, jni_env_register);
     }
-    // Call JNIEnvExt::MonitorEnterHelper(JNIEnv*, object)
-    static Offset monitor_enter(OFFSETOF_MEMBER(JNIEnvExt, MonitorEnterHelper));
-    jni_asm->Call(jni_env_register, monitor_enter,
+    // Call JNIEnv->MonitorEnter(object)
+    ManagedRegister jni_fns_register = jni_conv.InterproceduralScratchRegister();
+    jni_asm->LoadRawPtr(jni_fns_register, jni_env_register, functions);
+    jni_asm->Call(jni_fns_register, monitor_enter,
                   jni_conv.InterproceduralScratchRegister());
     jni_asm->FillFromSpillArea(spill_regs, out_arg_size);
     jni_asm->ExceptionPoll(jni_conv.InterproceduralScratchRegister());
@@ -238,9 +242,10 @@
       FrameOffset out_off = jni_conv.CurrentParamStackOffset();
       jni_asm->StoreRawPtr(out_off, jni_env_register);
     }
-    // Call JNIEnvExt::MonitorExitHelper(JNIEnv*, object)
-    static Offset monitor_exit(OFFSETOF_MEMBER(JNIEnvExt, MonitorExitHelper));
-    jni_asm->Call(jni_env_register, monitor_exit,
+    // Call JNIEnv->MonitorExit(object)
+    ManagedRegister jni_fns_register = jni_conv.InterproceduralScratchRegister();
+    jni_asm->LoadRawPtr(jni_fns_register, jni_env_register, functions);
+    jni_asm->Call(jni_fns_register, monitor_exit,
                   jni_conv.InterproceduralScratchRegister());
     // Reload return value
     jni_asm->Load(jni_conv.ReturnRegister(), return_save_location,
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 1be9d76..d6cfcb9 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -2024,16 +2024,6 @@
   GetObjectRefType,
 };
 
-void MonitorEnterHelper(JNIEnv* env, jobject obj) {
-  CHECK_EQ(Thread::Current()->GetJniEnv(), env);
-  MonitorEnter(env, obj);  // Ignore the result.
-}
-
-void MonitorExitHelper(JNIEnv* env, jobject obj) {
-  CHECK_EQ(Thread::Current()->GetJniEnv(), env);
-  MonitorExit(env, obj);  // Ignore the result.
-}
-
 static const size_t kMonitorTableInitialSize = 32; // Arbitrary.
 static const size_t kMonitorTableMaxSize = 4096; // Arbitrary sanity check.
 
@@ -2043,9 +2033,6 @@
       check_jni(check_jni),
       critical(false),
       monitor_table("monitor table", kMonitorTableInitialSize, kMonitorTableMaxSize) {
-  // TODO: kill these.
-  MonitorEnterHelper = &::art::MonitorEnterHelper;
-  MonitorExitHelper = &::art::MonitorExitHelper;
 }
 
 // JNI Invocation interface.
diff --git a/src/jni_internal.h b/src/jni_internal.h
index 2935c73..9cf8d57 100644
--- a/src/jni_internal.h
+++ b/src/jni_internal.h
@@ -43,11 +43,6 @@
 
   // Entered JNI monitors, for bulk exit on thread detach.
   ReferenceTable  monitor_table;
-
-  // Used to help call synchronized native methods.
-  // TODO: make jni_compiler.cc do the indirection itself.
-  void (*MonitorEnterHelper)(JNIEnv*, jobject);
-  void (*MonitorExitHelper)(JNIEnv*, jobject);
 };
 
 }  // namespace art