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 LocalRefCookieOffsetJNIEnvExt156 static Offset LocalRefCookieOffset() { 157 return Offset(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie)); 158 } 159 SelfOffsetJNIEnvExt160 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: ScopedJniEnvLocalRefState(JNIEnvExt * env)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 ~ScopedJniEnvLocalRefState()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