1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "entrypoints/entrypoint_utils.h" 18 #include "mirror/art_method-inl.h" 19 #include "mirror/object-inl.h" 20 #include "thread-inl.h" 21 22 namespace art { 23 24 // Called on entry to JNI, transition out of Runnable and release share of mutator_lock_. 25 extern "C" uint32_t art_portable_jni_method_start(Thread* self) 26 UNLOCK_FUNCTION(GlobalSynchronizatio::mutator_lock_) { 27 JNIEnvExt* env = self->GetJniEnv(); 28 uint32_t saved_local_ref_cookie = env->local_ref_cookie; 29 env->local_ref_cookie = env->locals.GetSegmentState(); 30 self->TransitionFromRunnableToSuspended(kNative); 31 return saved_local_ref_cookie; 32 } 33 34 extern "C" uint32_t art_portable_jni_method_start_synchronized(jobject to_lock, Thread* self) 35 UNLOCK_FUNCTION(Locks::mutator_lock_) { 36 self->DecodeJObject(to_lock)->MonitorEnter(self); 37 return art_portable_jni_method_start(self); 38 } 39 40 static void PopLocalReferences(uint32_t saved_local_ref_cookie, Thread* self) { 41 JNIEnvExt* env = self->GetJniEnv(); 42 env->locals.SetSegmentState(env->local_ref_cookie); 43 env->local_ref_cookie = saved_local_ref_cookie; 44 } 45 46 extern "C" void art_portable_jni_method_end(uint32_t saved_local_ref_cookie, Thread* self) 47 SHARED_LOCK_FUNCTION(Locks::mutator_lock_) { 48 self->TransitionFromSuspendedToRunnable(); 49 PopLocalReferences(saved_local_ref_cookie, self); 50 } 51 52 53 extern "C" void art_portable_jni_method_end_synchronized(uint32_t saved_local_ref_cookie, 54 jobject locked, 55 Thread* self) 56 SHARED_LOCK_FUNCTION(Locks::mutator_lock_) { 57 self->TransitionFromSuspendedToRunnable(); 58 UnlockJniSynchronizedMethod(locked, self); // Must decode before pop. 59 PopLocalReferences(saved_local_ref_cookie, self); 60 } 61 62 extern "C" mirror::Object* art_portable_jni_method_end_with_reference(jobject result, 63 uint32_t saved_local_ref_cookie, 64 Thread* self) 65 SHARED_LOCK_FUNCTION(Locks::mutator_lock_) { 66 self->TransitionFromSuspendedToRunnable(); 67 mirror::Object* o = self->DecodeJObject(result); // Must decode before pop. 68 PopLocalReferences(saved_local_ref_cookie, self); 69 // Process result. 70 if (UNLIKELY(self->GetJniEnv()->check_jni)) { 71 if (self->IsExceptionPending()) { 72 return NULL; 73 } 74 CheckReferenceResult(o, self); 75 } 76 return o; 77 } 78 79 extern "C" mirror::Object* art_portable_jni_method_end_with_reference_synchronized(jobject result, 80 uint32_t saved_local_ref_cookie, 81 jobject locked, 82 Thread* self) 83 SHARED_LOCK_FUNCTION(Locks::mutator_lock_) { 84 self->TransitionFromSuspendedToRunnable(); 85 UnlockJniSynchronizedMethod(locked, self); // Must decode before pop. 86 mirror::Object* o = self->DecodeJObject(result); 87 PopLocalReferences(saved_local_ref_cookie, self); 88 // Process result. 89 if (UNLIKELY(self->GetJniEnv()->check_jni)) { 90 if (self->IsExceptionPending()) { 91 return NULL; 92 } 93 CheckReferenceResult(o, self); 94 } 95 return o; 96 } 97 98 } // namespace art 99