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_JAVA_VM_EXT_H_
     18 #define ART_RUNTIME_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 "reference_table.h"
     26 
     27 namespace art {
     28 
     29 namespace mirror {
     30   class Array;
     31 }  // namespace mirror
     32 
     33 class ArtMethod;
     34 class Libraries;
     35 class ParsedOptions;
     36 class Runtime;
     37 struct RuntimeArgumentMap;
     38 
     39 class JavaVMExt : public JavaVM {
     40  public:
     41   JavaVMExt(Runtime* runtime, const RuntimeArgumentMap& runtime_options);
     42   ~JavaVMExt();
     43 
     44   bool ForceCopy() const {
     45     return force_copy_;
     46   }
     47 
     48   bool IsCheckJniEnabled() const {
     49     return check_jni_;
     50   }
     51 
     52   bool IsTracingEnabled() const {
     53     return tracing_enabled_;
     54   }
     55 
     56   Runtime* GetRuntime() const {
     57     return runtime_;
     58   }
     59 
     60   void SetCheckJniAbortHook(void (*hook)(void*, const std::string&), void* data) {
     61     check_jni_abort_hook_ = hook;
     62     check_jni_abort_hook_data_ = data;
     63   }
     64 
     65   // Aborts execution unless there is an abort handler installed in which case it will return. Its
     66   // therefore important that callers return after aborting as otherwise code following the abort
     67   // will be executed in the abort handler case.
     68   void JniAbort(const char* jni_function_name, const char* msg);
     69 
     70   void JniAbortV(const char* jni_function_name, const char* fmt, va_list ap);
     71 
     72   void JniAbortF(const char* jni_function_name, const char* fmt, ...)
     73       __attribute__((__format__(__printf__, 3, 4)));
     74 
     75   // If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
     76   // when a native method that matches the -Xjnitrace argument calls a JNI function
     77   // such as NewByteArray.
     78   // If -verbose:third-party-jni is on, we want to log any JNI function calls
     79   // made by a third-party native method.
     80   bool ShouldTrace(ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_);
     81 
     82   /**
     83    * Loads the given shared library. 'path' is an absolute pathname.
     84    *
     85    * Returns 'true' on success. On failure, sets 'error_msg' to a
     86    * human-readable description of the error.
     87    */
     88   bool LoadNativeLibrary(JNIEnv* env,
     89                          const std::string& path,
     90                          jobject class_loader,
     91                          jstring library_path,
     92                          std::string* error_msg);
     93 
     94   // Unload native libraries with cleared class loaders.
     95   void UnloadNativeLibraries()
     96       REQUIRES(!Locks::jni_libraries_lock_)
     97       SHARED_REQUIRES(Locks::mutator_lock_);
     98 
     99   /**
    100    * Returns a pointer to the code for the native method 'm', found
    101    * using dlsym(3) on every native library that's been loaded so far.
    102    */
    103   void* FindCodeForNativeMethod(ArtMethod* m)
    104       SHARED_REQUIRES(Locks::mutator_lock_);
    105 
    106   void DumpForSigQuit(std::ostream& os)
    107       REQUIRES(!Locks::jni_libraries_lock_, !globals_lock_, !weak_globals_lock_);
    108 
    109   void DumpReferenceTables(std::ostream& os)
    110       SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!globals_lock_, !weak_globals_lock_);
    111 
    112   bool SetCheckJniEnabled(bool enabled);
    113 
    114   void VisitRoots(RootVisitor* visitor) SHARED_REQUIRES(Locks::mutator_lock_)
    115       REQUIRES(!globals_lock_);
    116 
    117   void DisallowNewWeakGlobals() SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!weak_globals_lock_);
    118   void AllowNewWeakGlobals() SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!weak_globals_lock_);
    119   void BroadcastForNewWeakGlobals() SHARED_REQUIRES(Locks::mutator_lock_)
    120       REQUIRES(!weak_globals_lock_);
    121 
    122   jobject AddGlobalRef(Thread* self, mirror::Object* obj)
    123       SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!globals_lock_);
    124 
    125   jweak AddWeakGlobalRef(Thread* self, mirror::Object* obj)
    126     SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!weak_globals_lock_);
    127 
    128   void DeleteGlobalRef(Thread* self, jobject obj) REQUIRES(!globals_lock_);
    129 
    130   void DeleteWeakGlobalRef(Thread* self, jweak obj) REQUIRES(!weak_globals_lock_);
    131 
    132   void SweepJniWeakGlobals(IsMarkedVisitor* visitor)
    133       SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!weak_globals_lock_);
    134 
    135   mirror::Object* DecodeGlobal(IndirectRef ref)
    136       SHARED_REQUIRES(Locks::mutator_lock_);
    137 
    138   void UpdateGlobal(Thread* self, IndirectRef ref, mirror::Object* result)
    139       SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!globals_lock_);
    140 
    141   mirror::Object* DecodeWeakGlobal(Thread* self, IndirectRef ref)
    142       SHARED_REQUIRES(Locks::mutator_lock_)
    143       REQUIRES(!weak_globals_lock_);
    144 
    145   mirror::Object* DecodeWeakGlobalLocked(Thread* self, IndirectRef ref)
    146       SHARED_REQUIRES(Locks::mutator_lock_)
    147       REQUIRES(weak_globals_lock_);
    148 
    149   // Like DecodeWeakGlobal() but to be used only during a runtime shutdown where self may be
    150   // null.
    151   mirror::Object* DecodeWeakGlobalDuringShutdown(Thread* self, IndirectRef ref)
    152       SHARED_REQUIRES(Locks::mutator_lock_)
    153       REQUIRES(!weak_globals_lock_);
    154 
    155   // Checks if the weak global ref has been cleared by the GC without decode (read barrier.)
    156   bool IsWeakGlobalCleared(Thread* self, IndirectRef ref)
    157       SHARED_REQUIRES(Locks::mutator_lock_)
    158       REQUIRES(!weak_globals_lock_);
    159 
    160   Mutex& WeakGlobalsLock() RETURN_CAPABILITY(weak_globals_lock_) {
    161     return weak_globals_lock_;
    162   }
    163 
    164   void UpdateWeakGlobal(Thread* self, IndirectRef ref, mirror::Object* result)
    165       SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!weak_globals_lock_);
    166 
    167   const JNIInvokeInterface* GetUncheckedFunctions() const {
    168     return unchecked_functions_;
    169   }
    170 
    171   void TrimGlobals() SHARED_REQUIRES(Locks::mutator_lock_)
    172       REQUIRES(!globals_lock_);
    173 
    174  private:
    175   // Return true if self can currently access weak globals.
    176   bool MayAccessWeakGlobalsUnlocked(Thread* self) const SHARED_REQUIRES(Locks::mutator_lock_);
    177   bool MayAccessWeakGlobals(Thread* self) const
    178       SHARED_REQUIRES(Locks::mutator_lock_)
    179       REQUIRES(weak_globals_lock_);
    180 
    181   Runtime* const runtime_;
    182 
    183   // Used for testing. By default, we'll LOG(FATAL) the reason.
    184   void (*check_jni_abort_hook_)(void* data, const std::string& reason);
    185   void* check_jni_abort_hook_data_;
    186 
    187   // Extra checking.
    188   bool check_jni_;
    189   bool force_copy_;
    190   const bool tracing_enabled_;
    191 
    192   // Extra diagnostics.
    193   const std::string trace_;
    194 
    195   // JNI global references.
    196   ReaderWriterMutex globals_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    197   // Not guarded by globals_lock since we sometimes use SynchronizedGet in Thread::DecodeJObject.
    198   IndirectReferenceTable globals_;
    199 
    200   // No lock annotation since UnloadNativeLibraries is called on libraries_ but locks the
    201   // jni_libraries_lock_ internally.
    202   std::unique_ptr<Libraries> libraries_;
    203 
    204   // Used by -Xcheck:jni.
    205   const JNIInvokeInterface* const unchecked_functions_;
    206 
    207   // JNI weak global references.
    208   Mutex weak_globals_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    209   // Since weak_globals_ contain weak roots, be careful not to
    210   // directly access the object references in it. Use Get() with the
    211   // read barrier enabled.
    212   // Not guarded by weak_globals_lock since we may use SynchronizedGet in DecodeWeakGlobal.
    213   IndirectReferenceTable weak_globals_;
    214   // Not guarded by weak_globals_lock since we may use SynchronizedGet in DecodeWeakGlobal.
    215   Atomic<bool> allow_accessing_weak_globals_;
    216   ConditionVariable weak_globals_add_condition_ GUARDED_BY(weak_globals_lock_);
    217 
    218   DISALLOW_COPY_AND_ASSIGN(JavaVMExt);
    219 };
    220 
    221 }  // namespace art
    222 
    223 #endif  // ART_RUNTIME_JAVA_VM_EXT_H_
    224