1 /* 2 * Copyright (C) 2008 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 * JNI innards, common to the regular and "checked" interfaces. 18 */ 19 #ifndef DALVIK_JNIINTERNAL_H_ 20 #define DALVIK_JNIINTERNAL_H_ 21 22 #include "jni.h" 23 24 /* system init/shutdown */ 25 bool dvmJniStartup(void); 26 void dvmJniShutdown(void); 27 28 bool dvmIsBadJniVersion(int version); 29 30 /* 31 * Our data structures for JNIEnv and JavaVM. 32 * 33 * Native code thinks it has a pointer to a pointer. We know better. 34 */ 35 struct JavaVMExt; 36 37 struct JNIEnvExt { 38 const struct JNINativeInterface* funcTable; /* must be first */ 39 40 const struct JNINativeInterface* baseFuncTable; 41 42 u4 envThreadId; 43 Thread* self; 44 45 /* if nonzero, we are in a "critical" JNI call */ 46 int critical; 47 48 struct JNIEnvExt* prev; 49 struct JNIEnvExt* next; 50 }; 51 52 struct JavaVMExt { 53 const struct JNIInvokeInterface* funcTable; /* must be first */ 54 55 const struct JNIInvokeInterface* baseFuncTable; 56 57 /* head of list of JNIEnvs associated with this VM */ 58 JNIEnvExt* envList; 59 pthread_mutex_t envListLock; 60 }; 61 62 /* 63 * Native function return type; used by dvmPlatformInvoke(). 64 * 65 * This is part of Method.jniArgInfo, and must fit in 3 bits. 66 * Note: Assembly code in arch/<arch>/Call<arch>.S relies on 67 * the enum values defined here. 68 */ 69 enum DalvikJniReturnType { 70 DALVIK_JNI_RETURN_VOID = 0, /* must be zero */ 71 DALVIK_JNI_RETURN_FLOAT = 1, 72 DALVIK_JNI_RETURN_DOUBLE = 2, 73 DALVIK_JNI_RETURN_S8 = 3, 74 DALVIK_JNI_RETURN_S4 = 4, 75 DALVIK_JNI_RETURN_S2 = 5, 76 DALVIK_JNI_RETURN_U2 = 6, 77 DALVIK_JNI_RETURN_S1 = 7 78 }; 79 80 #define DALVIK_JNI_NO_ARG_INFO 0x80000000 81 #define DALVIK_JNI_RETURN_MASK 0x70000000 82 #define DALVIK_JNI_RETURN_SHIFT 28 83 #define DALVIK_JNI_COUNT_MASK 0x0f000000 84 #define DALVIK_JNI_COUNT_SHIFT 24 85 86 87 /* 88 * Pop the JNI local stack when we return from a native method. "saveArea" 89 * points to the StackSaveArea for the method we're leaving. 90 * 91 * (This may be implemented directly in assembly in mterp, so changes here 92 * may only affect the portable interpreter.) 93 */ 94 INLINE void dvmPopJniLocals(Thread* self, StackSaveArea* saveArea) 95 { 96 self->jniLocalRefTable.segmentState.all = saveArea->xtra.localRefCookie; 97 } 98 99 /* 100 * Set the envThreadId field. 101 */ 102 INLINE void dvmSetJniEnvThreadId(JNIEnv* pEnv, Thread* self) 103 { 104 ((JNIEnvExt*)pEnv)->envThreadId = self->threadId; 105 ((JNIEnvExt*)pEnv)->self = self; 106 } 107 108 void dvmCallJNIMethod(const u4* args, JValue* pResult, 109 const Method* method, Thread* self); 110 void dvmCheckCallJNIMethod(const u4* args, JValue* pResult, 111 const Method* method, Thread* self); 112 113 /* 114 * Configure "method" to use the JNI bridge to call "func". 115 */ 116 void dvmUseJNIBridge(Method* method, void* func); 117 118 119 /* 120 * Enable the "checked" versions. 121 */ 122 void dvmUseCheckedJniEnv(JNIEnvExt* pEnv); 123 void dvmUseCheckedJniVm(JavaVMExt* pVm); 124 void dvmLateEnableCheckedJni(void); 125 126 /* 127 * Decode a local, global, or weak-global reference. 128 */ 129 Object* dvmDecodeIndirectRef(Thread* self, jobject jobj); 130 131 /* 132 * Verify that a reference passed in from native code is valid. Returns 133 * an indication of local/global/invalid. 134 */ 135 jobjectRefType dvmGetJNIRefType(Thread* self, jobject jobj); 136 137 /* 138 * Get the last method called on the interp stack. This is the method 139 * "responsible" for calling into JNI. 140 */ 141 const Method* dvmGetCurrentJNIMethod(void); 142 143 /* 144 * Create/destroy a JNIEnv for the current thread. 145 */ 146 JNIEnv* dvmCreateJNIEnv(Thread* self); 147 void dvmDestroyJNIEnv(JNIEnv* env); 148 149 /* 150 * Find the JNIEnv associated with the current thread. 151 */ 152 JNIEnvExt* dvmGetJNIEnvForThread(void); 153 154 /* 155 * Release all MonitorEnter-acquired locks that are still held. Called at 156 * DetachCurrentThread time. 157 */ 158 void dvmReleaseJniMonitors(Thread* self); 159 160 /* 161 * Dump the contents of the JNI reference tables to the log file. 162 * 163 * The local ref tables associated with other threads are not included. 164 */ 165 void dvmDumpJniReferenceTables(void); 166 167 // Dumps JNI statistics in response to SIGQUIT. 168 struct DebugOutputTarget; 169 void dvmDumpJniStats(DebugOutputTarget* target); 170 171 #endif // DALVIK_JNIINTERNAL_H_ 172