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