Home | History | Annotate | Download | only in jni
      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_JAVA_VM_EXT_H_
     18 #define ART_RUNTIME_JNI_JAVA_VM_EXT_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 "obj_ptr.h"
     26 #include "reference_table.h"
     27 
     28 namespace art {
     29 
     30 namespace mirror {
     31 class Array;
     32 }  // namespace mirror
     33 
     34 class ArtMethod;
     35 class IsMarkedVisitor;
     36 class Libraries;
     37 class ParsedOptions;
     38 class Runtime;
     39 struct RuntimeArgumentMap;
     40 
     41 class JavaVMExt;
     42 // Hook definition for runtime plugins.
     43 using GetEnvHook = jint (*)(JavaVMExt* vm, /*out*/void** new_env, jint version);
     44 
     45 class JavaVMExt : public JavaVM {
     46  public:
     47   // Creates a new JavaVMExt object.
     48   // Returns nullptr on error, in which case error_msg is set to a message
     49   // describing the error.
     50   static std::unique_ptr<JavaVMExt> Create(Runtime* runtime,
     51                                            const RuntimeArgumentMap& runtime_options,
     52                                            std::string* error_msg);
     53 
     54 
     55   ~JavaVMExt();
     56 
     57   bool ForceCopy() const {
     58     return force_copy_;
     59   }
     60 
     61   bool IsCheckJniEnabled() const {
     62     return check_jni_;
     63   }
     64 
     65   bool IsTracingEnabled() const {
     66     return tracing_enabled_;
     67   }
     68 
     69   Runtime* GetRuntime() const {
     70     return runtime_;
     71   }
     72 
     73   void SetCheckJniAbortHook(void (*hook)(void*, const std::string&), void* data) {
     74     check_jni_abort_hook_ = hook;
     75     check_jni_abort_hook_data_ = data;
     76   }
     77 
     78   // Aborts execution unless there is an abort handler installed in which case it will return. Its
     79   // therefore important that callers return after aborting as otherwise code following the abort
     80   // will be executed in the abort handler case.
     81   void JniAbort(const char* jni_function_name, const char* msg);
     82 
     83   void JniAbortV(const char* jni_function_name, const char* fmt, va_list ap);
     84 
     85   void JniAbortF(const char* jni_function_name, const char* fmt, ...)
     86       __attribute__((__format__(__printf__, 3, 4)));
     87 
     88   // If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
     89   // when a native method that matches the -Xjnitrace argument calls a JNI function
     90   // such as NewByteArray.
     91   // If -verbose:third-party-jni is on, we want to log any JNI function calls
     92   // made by a third-party native method.
     93   bool ShouldTrace(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
     94 
     95   /**
     96    * Loads the given shared library. 'path' is an absolute pathname.
     97    *
     98    * Returns 'true' on success. On failure, sets 'error_msg' to a
     99    * human-readable description of the error.
    100    */
    101   bool LoadNativeLibrary(JNIEnv* env,
    102                          const std::string& path,
    103                          jobject class_loader,
    104                          jclass caller_class,
    105                          std::string* error_msg);
    106 
    107   // Unload native libraries with cleared class loaders.
    108   void UnloadNativeLibraries()
    109       REQUIRES(!Locks::jni_libraries_lock_)
    110       REQUIRES_SHARED(Locks::mutator_lock_);
    111 
    112   // Unload all boot classpath native libraries.
    113   void UnloadBootNativeLibraries()
    114       REQUIRES(!Locks::jni_libraries_lock_)
    115       REQUIRES_SHARED(Locks::mutator_lock_);
    116 
    117   /**
    118    * Returns a pointer to the code for the native method 'm', found
    119    * using dlsym(3) on every native library that's been loaded so far.
    120    */
    121   void* FindCodeForNativeMethod(ArtMethod* m)
    122       REQUIRES_SHARED(Locks::mutator_lock_);
    123 
    124   void DumpForSigQuit(std::ostream& os)
    125       REQUIRES(!Locks::jni_libraries_lock_,
    126                !Locks::jni_globals_lock_,
    127                !Locks::jni_weak_globals_lock_);
    128 
    129   void DumpReferenceTables(std::ostream& os)
    130       REQUIRES_SHARED(Locks::mutator_lock_)
    131       REQUIRES(!Locks::jni_globals_lock_,
    132                !Locks::jni_weak_globals_lock_,
    133                !Locks::alloc_tracker_lock_);
    134 
    135   bool SetCheckJniEnabled(bool enabled);
    136 
    137   void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_)
    138       REQUIRES(!Locks::jni_globals_lock_);
    139 
    140   void DisallowNewWeakGlobals()
    141       REQUIRES_SHARED(Locks::mutator_lock_)
    142       REQUIRES(!Locks::jni_weak_globals_lock_);
    143   void AllowNewWeakGlobals()
    144       REQUIRES_SHARED(Locks::mutator_lock_)
    145       REQUIRES(!Locks::jni_weak_globals_lock_);
    146   void BroadcastForNewWeakGlobals()
    147       REQUIRES(!Locks::jni_weak_globals_lock_);
    148 
    149   jobject AddGlobalRef(Thread* self, ObjPtr<mirror::Object> obj)
    150       REQUIRES_SHARED(Locks::mutator_lock_)
    151       REQUIRES(!Locks::jni_globals_lock_);
    152 
    153   jweak AddWeakGlobalRef(Thread* self, ObjPtr<mirror::Object> obj)
    154       REQUIRES_SHARED(Locks::mutator_lock_)
    155       REQUIRES(!Locks::jni_weak_globals_lock_);
    156 
    157   void DeleteGlobalRef(Thread* self, jobject obj) REQUIRES(!Locks::jni_globals_lock_);
    158 
    159   void DeleteWeakGlobalRef(Thread* self, jweak obj) REQUIRES(!Locks::jni_weak_globals_lock_);
    160 
    161   void SweepJniWeakGlobals(IsMarkedVisitor* visitor)
    162       REQUIRES_SHARED(Locks::mutator_lock_)
    163       REQUIRES(!Locks::jni_weak_globals_lock_);
    164 
    165   ObjPtr<mirror::Object> DecodeGlobal(IndirectRef ref)
    166       REQUIRES_SHARED(Locks::mutator_lock_);
    167 
    168   void UpdateGlobal(Thread* self, IndirectRef ref, ObjPtr<mirror::Object> result)
    169       REQUIRES_SHARED(Locks::mutator_lock_)
    170       REQUIRES(!Locks::jni_globals_lock_);
    171 
    172   ObjPtr<mirror::Object> DecodeWeakGlobal(Thread* self, IndirectRef ref)
    173       REQUIRES_SHARED(Locks::mutator_lock_)
    174       REQUIRES(!Locks::jni_weak_globals_lock_);
    175 
    176   ObjPtr<mirror::Object> DecodeWeakGlobalLocked(Thread* self, IndirectRef ref)
    177       REQUIRES_SHARED(Locks::mutator_lock_)
    178       REQUIRES(Locks::jni_weak_globals_lock_);
    179 
    180   // Like DecodeWeakGlobal() but to be used only during a runtime shutdown where self may be
    181   // null.
    182   ObjPtr<mirror::Object> DecodeWeakGlobalDuringShutdown(Thread* self, IndirectRef ref)
    183       REQUIRES_SHARED(Locks::mutator_lock_)
    184       REQUIRES(!Locks::jni_weak_globals_lock_);
    185 
    186   // Checks if the weak global ref has been cleared by the GC without decode (read barrier.)
    187   bool IsWeakGlobalCleared(Thread* self, IndirectRef ref)
    188       REQUIRES_SHARED(Locks::mutator_lock_)
    189       REQUIRES(!Locks::jni_weak_globals_lock_);
    190 
    191   void UpdateWeakGlobal(Thread* self, IndirectRef ref, ObjPtr<mirror::Object> result)
    192       REQUIRES_SHARED(Locks::mutator_lock_)
    193       REQUIRES(!Locks::jni_weak_globals_lock_);
    194 
    195   const JNIInvokeInterface* GetUncheckedFunctions() const {
    196     return unchecked_functions_;
    197   }
    198 
    199   void TrimGlobals() REQUIRES_SHARED(Locks::mutator_lock_)
    200       REQUIRES(!Locks::jni_globals_lock_);
    201 
    202   jint HandleGetEnv(/*out*/void** env, jint version);
    203 
    204   void AddEnvironmentHook(GetEnvHook hook);
    205 
    206   static bool IsBadJniVersion(int version);
    207 
    208   // Return the library search path for the given classloader, if the classloader is of a
    209   // well-known type. The jobject will be a local reference and is expected to be managed by the
    210   // caller.
    211   static jstring GetLibrarySearchPath(JNIEnv* env, jobject class_loader);
    212 
    213  private:
    214   // The constructor should not be called directly. It may leave the object in
    215   // an erroneous state, and the result needs to be checked.
    216   JavaVMExt(Runtime* runtime, const RuntimeArgumentMap& runtime_options, std::string* error_msg);
    217 
    218   // Return true if self can currently access weak globals.
    219   bool MayAccessWeakGlobalsUnlocked(Thread* self) const REQUIRES_SHARED(Locks::mutator_lock_);
    220   bool MayAccessWeakGlobals(Thread* self) const
    221       REQUIRES_SHARED(Locks::mutator_lock_)
    222       REQUIRES(Locks::jni_weak_globals_lock_);
    223 
    224   void CheckGlobalRefAllocationTracking();
    225 
    226   Runtime* const runtime_;
    227 
    228   // Used for testing. By default, we'll LOG(FATAL) the reason.
    229   void (*check_jni_abort_hook_)(void* data, const std::string& reason);
    230   void* check_jni_abort_hook_data_;
    231 
    232   // Extra checking.
    233   bool check_jni_;
    234   const bool force_copy_;
    235   const bool tracing_enabled_;
    236 
    237   // Extra diagnostics.
    238   const std::string trace_;
    239 
    240   // Not guarded by globals_lock since we sometimes use SynchronizedGet in Thread::DecodeJObject.
    241   IndirectReferenceTable globals_;
    242 
    243   // No lock annotation since UnloadNativeLibraries is called on libraries_ but locks the
    244   // jni_libraries_lock_ internally.
    245   std::unique_ptr<Libraries> libraries_;
    246 
    247   // Used by -Xcheck:jni.
    248   const JNIInvokeInterface* const unchecked_functions_;
    249 
    250   // Since weak_globals_ contain weak roots, be careful not to
    251   // directly access the object references in it. Use Get() with the
    252   // read barrier enabled.
    253   // Not guarded by weak_globals_lock since we may use SynchronizedGet in DecodeWeakGlobal.
    254   IndirectReferenceTable weak_globals_;
    255   // Not guarded by weak_globals_lock since we may use SynchronizedGet in DecodeWeakGlobal.
    256   Atomic<bool> allow_accessing_weak_globals_;
    257   ConditionVariable weak_globals_add_condition_ GUARDED_BY(Locks::jni_weak_globals_lock_);
    258 
    259   // TODO Maybe move this to Runtime.
    260   std::vector<GetEnvHook> env_hooks_;
    261 
    262   size_t enable_allocation_tracking_delta_;
    263   std::atomic<bool> allocation_tracking_enabled_;
    264   std::atomic<bool> old_allocation_tracking_state_;
    265 
    266   DISALLOW_COPY_AND_ASSIGN(JavaVMExt);
    267 };
    268 
    269 }  // namespace art
    270 
    271 #endif  // ART_RUNTIME_JNI_JAVA_VM_EXT_H_
    272