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