Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 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 #ifndef ART_RUNTIME_JNI_INTERNAL_H_
     18 #define ART_RUNTIME_JNI_INTERNAL_H_
     19 
     20 #include "jni.h"
     21 
     22 #include "base/macros.h"
     23 #include "base/mutex.h"
     24 #include "indirect_reference_table.h"
     25 #include "object_callbacks.h"
     26 #include "reference_table.h"
     27 
     28 #include <iosfwd>
     29 #include <string>
     30 
     31 #ifndef NATIVE_METHOD
     32 #define NATIVE_METHOD(className, functionName, signature) \
     33   { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
     34 #endif
     35 #define REGISTER_NATIVE_METHODS(jni_class_name) \
     36   RegisterNativeMethods(env, jni_class_name, gMethods, arraysize(gMethods))
     37 
     38 namespace art {
     39 namespace mirror {
     40   class ArtField;
     41   class ArtMethod;
     42   class ClassLoader;
     43 }  // namespace mirror
     44 union JValue;
     45 class Libraries;
     46 class ParsedOptions;
     47 class Runtime;
     48 class ScopedObjectAccess;
     49 template<class T> class Handle;
     50 class Thread;
     51 
     52 void JniAbortF(const char* jni_function_name, const char* fmt, ...)
     53     __attribute__((__format__(__printf__, 2, 3)));
     54 void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
     55                            jint method_count);
     56 
     57 int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause);
     58 
     59 class JavaVMExt : public JavaVM {
     60  public:
     61   JavaVMExt(Runtime* runtime, ParsedOptions* options);
     62   ~JavaVMExt();
     63 
     64   /**
     65    * Loads the given shared library. 'path' is an absolute pathname.
     66    *
     67    * Returns 'true' on success. On failure, sets 'detail' to a
     68    * human-readable description of the error.
     69    */
     70   bool LoadNativeLibrary(const std::string& path, Handle<mirror::ClassLoader> class_loader,
     71                          std::string* detail)
     72       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     73 
     74   /**
     75    * Returns a pointer to the code for the native method 'm', found
     76    * using dlsym(3) on every native library that's been loaded so far.
     77    */
     78   void* FindCodeForNativeMethod(mirror::ArtMethod* m)
     79       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     80 
     81   void DumpForSigQuit(std::ostream& os);
     82 
     83   void DumpReferenceTables(std::ostream& os)
     84       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     85 
     86   void SetCheckJniEnabled(bool enabled);
     87 
     88   void VisitRoots(RootCallback* callback, void* arg)
     89       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     90 
     91   void DisallowNewWeakGlobals() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
     92   void AllowNewWeakGlobals() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     93   jweak AddWeakGlobalReference(Thread* self, mirror::Object* obj)
     94     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     95   void DeleteWeakGlobalRef(Thread* self, jweak obj)
     96     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     97   void SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg)
     98       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     99   mirror::Object* DecodeWeakGlobal(Thread* self, IndirectRef ref)
    100       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    101 
    102   Runtime* runtime;
    103 
    104   // Used for testing. By default, we'll LOG(FATAL) the reason.
    105   void (*check_jni_abort_hook)(void* data, const std::string& reason);
    106   void* check_jni_abort_hook_data;
    107 
    108   // Extra checking.
    109   bool check_jni;
    110   bool force_copy;
    111 
    112   // Extra diagnostics.
    113   std::string trace;
    114 
    115   // JNI global references.
    116   ReaderWriterMutex globals_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
    117   // Not guarded by globals_lock since we sometimes use SynchronizedGet in Thread::DecodeJObject.
    118   IndirectReferenceTable globals;
    119 
    120   Mutex libraries_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
    121   Libraries* libraries GUARDED_BY(libraries_lock);
    122 
    123   // Used by -Xcheck:jni.
    124   const JNIInvokeInterface* unchecked_functions;
    125 
    126  private:
    127   // TODO: Make the other members of this class also private.
    128   // JNI weak global references.
    129   Mutex weak_globals_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    130   // Since weak_globals_ contain weak roots, be careful not to
    131   // directly access the object references in it. Use Get() with the
    132   // read barrier enabled.
    133   IndirectReferenceTable weak_globals_ GUARDED_BY(weak_globals_lock_);
    134   bool allow_new_weak_globals_ GUARDED_BY(weak_globals_lock_);
    135   ConditionVariable weak_globals_add_condition_ GUARDED_BY(weak_globals_lock_);
    136 };
    137 
    138 struct JNIEnvExt : public JNIEnv {
    139   JNIEnvExt(Thread* self, JavaVMExt* vm);
    140   ~JNIEnvExt();
    141 
    142   void DumpReferenceTables(std::ostream& os)
    143       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    144 
    145   void SetCheckJniEnabled(bool enabled);
    146 
    147   void PushFrame(int capacity);
    148   void PopFrame();
    149 
    150   template<typename T>
    151   T AddLocalReference(mirror::Object* obj)
    152       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    153 
    154   static Offset SegmentStateOffset();
    155 
    156   static Offset LocalRefCookieOffset() {
    157     return Offset(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie));
    158   }
    159 
    160   static Offset SelfOffset() {
    161     return Offset(OFFSETOF_MEMBER(JNIEnvExt, self));
    162   }
    163 
    164   jobject NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    165   void DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    166 
    167   Thread* const self;
    168   JavaVMExt* vm;
    169 
    170   // Cookie used when using the local indirect reference table.
    171   uint32_t local_ref_cookie;
    172 
    173   // JNI local references.
    174   IndirectReferenceTable locals GUARDED_BY(Locks::mutator_lock_);
    175 
    176   // Stack of cookies corresponding to PushLocalFrame/PopLocalFrame calls.
    177   // TODO: to avoid leaks (and bugs), we need to clear this vector on entry (or return)
    178   // to a native method.
    179   std::vector<uint32_t> stacked_local_ref_cookies;
    180 
    181   // Frequently-accessed fields cached from JavaVM.
    182   bool check_jni;
    183 
    184   // How many nested "critical" JNI calls are we in?
    185   int critical;
    186 
    187   // Entered JNI monitors, for bulk exit on thread detach.
    188   ReferenceTable monitors;
    189 
    190   // Used by -Xcheck:jni.
    191   const JNINativeInterface* unchecked_functions;
    192 };
    193 
    194 const JNINativeInterface* GetCheckJniNativeInterface();
    195 const JNIInvokeInterface* GetCheckJniInvokeInterface();
    196 
    197 // Used to save and restore the JNIEnvExt state when not going through code created by the JNI
    198 // compiler
    199 class ScopedJniEnvLocalRefState {
    200  public:
    201   explicit ScopedJniEnvLocalRefState(JNIEnvExt* env) : env_(env) {
    202     saved_local_ref_cookie_ = env->local_ref_cookie;
    203     env->local_ref_cookie = env->locals.GetSegmentState();
    204   }
    205 
    206   ~ScopedJniEnvLocalRefState() {
    207     env_->locals.SetSegmentState(env_->local_ref_cookie);
    208     env_->local_ref_cookie = saved_local_ref_cookie_;
    209   }
    210 
    211  private:
    212   JNIEnvExt* env_;
    213   uint32_t saved_local_ref_cookie_;
    214   DISALLOW_COPY_AND_ASSIGN(ScopedJniEnvLocalRefState);
    215 };
    216 
    217 }  // namespace art
    218 
    219 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs);
    220 #endif  // ART_RUNTIME_JNI_INTERNAL_H_
    221