Fix JNI compiler for portable path.

Change-Id: Ic2cbfcf126137b1b72f3b51e7af5a9be87987737
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index 1f687f6..8bb8b87 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -32,6 +32,7 @@
 #include <llvm/BasicBlock.h>
 #include <llvm/DerivedTypes.h>
 #include <llvm/Function.h>
+#include <llvm/ADT/SmallVector.h>
 #include <llvm/Type.h>
 
 namespace art {
@@ -117,13 +118,8 @@
   // Get JNIEnv
   llvm::Value* jni_env_object_addr =
       irb_.Runtime().EmitLoadFromThreadOffset(Thread::JniEnvOffset().Int32Value(),
-                                          irb_.getJObjectTy(),
-                                          kTBAAJRuntime);
-
-  // Set thread state to kNative
-  irb_.Runtime().EmitStoreToThreadOffset(Thread::StateOffset().Int32Value(),
-                                     irb_.getInt32(kNative),
-                                     kTBAARuntimeInfo);
+                                              irb_.getJObjectTy(),
+                                              kTBAAJRuntime);
 
   // Get callee code_addr
   llvm::Value* code_addr =
@@ -152,7 +148,8 @@
   llvm::Value* sirt_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
   irb_.CreateStore(this_object_or_class_object, sirt_field_addr, kTBAAShadowFrame);
   // Push the "this object or class object" to out args
-  args.push_back(irb_.CreateBitCast(sirt_field_addr, irb_.getJObjectTy()));
+  this_object_or_class_object = irb_.CreateBitCast(sirt_field_addr, irb_.getJObjectTy());
+  args.push_back(this_object_or_class_object);
   // Store arguments to SIRT, and push back to args
   for (arg_iter = arg_begin; arg_iter != arg_end; ++arg_iter) {
     if (arg_iter->getType() == irb_.getJObjectTy()) {
@@ -173,74 +170,48 @@
     }
   }
 
-  // Acquire lock for synchronized methods.
-  if (is_synchronized) {
-    irb_.Runtime().EmitLockObject(this_object_or_class_object);
+  llvm::Value* saved_local_ref_cookie;
+  { // JniMethodStart
+    RuntimeId func_id = is_synchronized ? JniMethodStartSynchronized
+                                        : JniMethodStart;
+    llvm::SmallVector<llvm::Value*, 2> args;
+    if (is_synchronized) {
+      args.push_back(this_object_or_class_object);
+    }
+    args.push_back(irb_.Runtime().EmitGetCurrentThread());
+    saved_local_ref_cookie =
+        irb_.CreateCall(irb_.GetRuntime(func_id), args);
   }
 
-  // saved_local_ref_cookie = env->local_ref_cookie
-  llvm::Value* saved_local_ref_cookie =
-      irb_.LoadFromObjectOffset(jni_env_object_addr,
-                                JNIEnvExt::LocalRefCookieOffset().Int32Value(),
-                                irb_.getInt32Ty(),
-                                kTBAARuntimeInfo);
-
-  // env->local_ref_cookie = env->locals.segment_state
-  llvm::Value* segment_state =
-      irb_.LoadFromObjectOffset(jni_env_object_addr,
-                                JNIEnvExt::SegmentStateOffset().Int32Value(),
-                                irb_.getInt32Ty(),
-                                kTBAARuntimeInfo);
-  irb_.StoreToObjectOffset(jni_env_object_addr,
-                           JNIEnvExt::LocalRefCookieOffset().Int32Value(),
-                           segment_state,
-                           kTBAARuntimeInfo);
-
-
   // Call!!!
   llvm::Value* retval = irb_.CreateCall(code_addr, args);
 
+  { // JniMethodEnd
+    bool is_return_ref = return_shorty == 'L';
+    RuntimeId func_id =
+        is_return_ref ? (is_synchronized ? JniMethodEndWithReferenceSynchronized
+                                         : JniMethodEndWithReference)
+                      : (is_synchronized ? JniMethodEndSynchronized
+                                         : JniMethodEnd);
+    llvm::SmallVector<llvm::Value*, 4> args;
+    if (is_return_ref) {
+      args.push_back(retval);
+    }
+    args.push_back(saved_local_ref_cookie);
+    if (is_synchronized) {
+      args.push_back(this_object_or_class_object);
+    }
+    args.push_back(irb_.Runtime().EmitGetCurrentThread());
 
-  // Release lock for synchronized methods.
-  if (is_synchronized) {
-    irb_.Runtime().EmitUnlockObject(this_object_or_class_object);
+    llvm::Value* decoded_jobject =
+        irb_.CreateCall(irb_.GetRuntime(func_id), args);
+
+    // Return decoded jobject if return reference.
+    if (is_return_ref) {
+      retval = decoded_jobject;
+    }
   }
 
-  // Set thread state to kRunnable
-  irb_.Runtime().EmitStoreToThreadOffset(Thread::StateOffset().Int32Value(),
-                                     irb_.getInt32(kRunnable),
-                                     kTBAARuntimeInfo);
-
-  // Do a suspend check
-  irb_.Runtime().EmitTestSuspend();
-
-  if (return_shorty == 'L') {
-    // Get thread object
-    llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
-
-    // If the return value is reference, it may point to SIRT, we should decode it.
-    retval = irb_.CreateCall2(irb_.GetRuntime(DecodeJObjectInThread),
-                              thread_object_addr,
-                              retval);
-  }
-
-  // env->locals.segment_state = env->local_ref_cookie
-  llvm::Value* local_ref_cookie =
-      irb_.LoadFromObjectOffset(jni_env_object_addr,
-                                JNIEnvExt::LocalRefCookieOffset().Int32Value(),
-                                irb_.getInt32Ty(),
-                                kTBAARuntimeInfo);
-  irb_.StoreToObjectOffset(jni_env_object_addr,
-                           JNIEnvExt::SegmentStateOffset().Int32Value(),
-                           local_ref_cookie,
-                           kTBAARuntimeInfo);
-
-  // env->local_ref_cookie = saved_local_ref_cookie
-  irb_.StoreToObjectOffset(jni_env_object_addr,
-                           JNIEnvExt::LocalRefCookieOffset().Int32Value(),
-                           saved_local_ref_cookie,
-                           kTBAARuntimeInfo);
-
   // Pop the shadow frame
   irb_.Runtime().EmitPopShadowFrame(old_shadow_frame);