Home | History | Annotate | Download | only in portable
      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-inl.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(Locks::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_) NO_THREAD_SAFETY_ANALYSIS {
     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     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     42   JNIEnvExt* env = self->GetJniEnv();
     43   env->locals.SetSegmentState(env->local_ref_cookie);
     44   env->local_ref_cookie = saved_local_ref_cookie;
     45 }
     46 
     47 extern "C" void art_portable_jni_method_end(uint32_t saved_local_ref_cookie, Thread* self)
     48     SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
     49   self->TransitionFromSuspendedToRunnable();
     50   PopLocalReferences(saved_local_ref_cookie, self);
     51 }
     52 
     53 
     54 extern "C" void art_portable_jni_method_end_synchronized(uint32_t saved_local_ref_cookie,
     55                                               jobject locked,
     56                                               Thread* self)
     57     SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
     58   self->TransitionFromSuspendedToRunnable();
     59   UnlockJniSynchronizedMethod(locked, self);  // Must decode before pop.
     60   PopLocalReferences(saved_local_ref_cookie, self);
     61 }
     62 
     63 extern "C" mirror::Object* art_portable_jni_method_end_with_reference(jobject result,
     64                                                                       uint32_t saved_local_ref_cookie,
     65                                                                       Thread* self)
     66     SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
     67   self->TransitionFromSuspendedToRunnable();
     68   mirror::Object* o = self->DecodeJObject(result);  // Must decode before pop.
     69   PopLocalReferences(saved_local_ref_cookie, self);
     70   // Process result.
     71   if (UNLIKELY(self->GetJniEnv()->check_jni)) {
     72     if (self->IsExceptionPending()) {
     73       return NULL;
     74     }
     75     CheckReferenceResult(o, self);
     76   }
     77   return o;
     78 }
     79 
     80 extern "C" mirror::Object* art_portable_jni_method_end_with_reference_synchronized(jobject result,
     81                                                                                    uint32_t saved_local_ref_cookie,
     82                                                                                    jobject locked,
     83                                                                                    Thread* self)
     84     SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
     85   self->TransitionFromSuspendedToRunnable();
     86   UnlockJniSynchronizedMethod(locked, self);  // Must decode before pop.
     87   mirror::Object* o = self->DecodeJObject(result);
     88   PopLocalReferences(saved_local_ref_cookie, self);
     89   // Process result.
     90   if (UNLIKELY(self->GetJniEnv()->check_jni)) {
     91     if (self->IsExceptionPending()) {
     92       return NULL;
     93     }
     94     CheckReferenceResult(o, self);
     95   }
     96   return o;
     97 }
     98 
     99 }  // namespace art
    100