JniInternal.h revision e2557513420f6be2d70c19a4d826731174c828d1
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 20#define _DALVIK_JNIINTERNAL 21 22#include "jni.h" 23 24/* system init/shutdown */ 25bool dvmJniStartup(void); 26void dvmJniShutdown(void); 27 28/* 29 * Our data structures for JNIEnv and JavaVM. 30 * 31 * Native code thinks it has a pointer to a pointer. We know better. 32 */ 33struct JavaVMExt; 34 35typedef struct JNIEnvExt { 36 const struct JNINativeInterface* funcTable; /* must be first */ 37 38 const struct JNINativeInterface* baseFuncTable; 39 40 /* pointer to the VM we are a part of */ 41 struct JavaVMExt* vm; 42 43 u4 envThreadId; 44 Thread* self; 45 46 /* if nonzero, we are in a "critical" JNI call */ 47 int critical; 48 49 /* keep a copy of this here for speed */ 50 bool forceDataCopy; 51 52 struct JNIEnvExt* prev; 53 struct JNIEnvExt* next; 54} JNIEnvExt; 55 56typedef struct JavaVMExt { 57 const struct JNIInvokeInterface* funcTable; /* must be first */ 58 59 const struct JNIInvokeInterface* baseFuncTable; 60 61 /* if multiple VMs are desired, add doubly-linked list stuff here */ 62 63 /* per-VM feature flags */ 64 bool useChecked; 65 bool warnError; 66 bool forceDataCopy; 67 68 /* head of list of JNIEnvs associated with this VM */ 69 JNIEnvExt* envList; 70 pthread_mutex_t envListLock; 71} JavaVMExt; 72 73/* 74 * Native function return type; used by dvmPlatformInvoke(). 75 * 76 * This is part of Method.jniArgInfo, and must fit in 3 bits. 77 * Note: Assembly code in arch/<arch>/Call<arch>.S relies on 78 * the enum values defined here. 79 */ 80typedef enum DalvikJniReturnType { 81 DALVIK_JNI_RETURN_VOID = 0, /* must be zero */ 82 DALVIK_JNI_RETURN_FLOAT = 1, 83 DALVIK_JNI_RETURN_DOUBLE = 2, 84 DALVIK_JNI_RETURN_S8 = 3, 85 DALVIK_JNI_RETURN_S4 = 4, 86 DALVIK_JNI_RETURN_S2 = 5, 87 DALVIK_JNI_RETURN_U2 = 6, 88 DALVIK_JNI_RETURN_S1 = 7 89} DalvikJniReturnType; 90 91#define DALVIK_JNI_NO_ARG_INFO 0x80000000 92#define DALVIK_JNI_RETURN_MASK 0x70000000 93#define DALVIK_JNI_RETURN_SHIFT 28 94#define DALVIK_JNI_COUNT_MASK 0x0f000000 95#define DALVIK_JNI_COUNT_SHIFT 24 96 97 98/* 99 * Pop the JNI local stack when we return from a native method. "saveArea" 100 * points to the StackSaveArea for the method we're leaving. 101 */ 102INLINE void dvmPopJniLocals(Thread* self, StackSaveArea* saveArea) 103{ 104 if (saveArea->xtra.localRefTop != self->jniLocalRefTable.nextEntry) { 105 LOGVV("LREF: popped %d entries (%d remain)\n", 106 (int)(self->jniLocalRefTable.nextEntry-saveArea->xtra.localRefTop), 107 (int)(saveArea->xtra.localRefTop - self->jniLocalRefTable.table)); 108 } 109 self->jniLocalRefTable.nextEntry = saveArea->xtra.localRefTop; 110} 111 112/* 113 * Set the envThreadId field. 114 */ 115INLINE void dvmSetJniEnvThreadId(JNIEnv* pEnv, Thread* self) 116{ 117 ((JNIEnvExt*)pEnv)->envThreadId = self->threadId; 118 ((JNIEnvExt*)pEnv)->self = self; 119} 120 121/* 122 * JNI call bridges. Not usually called directly. 123 * 124 * The "Check" versions are used when CheckJNI is enabled. 125 */ 126void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, 127 Thread* self); 128void dvmCallSynchronizedJNIMethod(const u4* args, JValue* pResult, 129 const Method* method, Thread* self); 130void dvmCheckCallJNIMethod(const u4* args, JValue* pResult, 131 const Method* method, Thread* self); 132void dvmCheckCallSynchronizedJNIMethod(const u4* args, JValue* pResult, 133 const Method* method, Thread* self); 134 135/* 136 * Configure "method" to use the JNI bridge to call "func". 137 */ 138void dvmUseJNIBridge(Method* method, void* func); 139 140 141/* 142 * Enable the "checked" versions. 143 */ 144void dvmUseCheckedJniEnv(JNIEnvExt* pEnv); 145void dvmUseCheckedJniVm(JavaVMExt* pVm); 146void dvmLateEnableCheckedJni(void); 147 148/* 149 * Verify that a reference passed in from native code is valid. Returns 150 * an indication of local/global/invalid. 151 */ 152jobjectRefType dvmGetJNIRefType(Object* obj); 153 154/* 155 * Get the last method called on the interp stack. This is the method 156 * "responsible" for calling into JNI. 157 */ 158const Method* dvmGetCurrentJNIMethod(void); 159 160/* 161 * Create/destroy a JNIEnv for the current thread. 162 */ 163JNIEnv* dvmCreateJNIEnv(Thread* self); 164void dvmDestroyJNIEnv(JNIEnv* env); 165 166/* 167 * Find the JNIEnv associated with the current thread. 168 */ 169JNIEnvExt* dvmGetJNIEnvForThread(void); 170 171/* 172 * Extract the return type enum from the "jniArgInfo" value. 173 */ 174DalvikJniReturnType dvmGetArgInfoReturnType(int jniArgInfo); 175 176/* 177 * Release all MonitorEnter-acquired locks that are still held. Called at 178 * DetachCurrentThread time. 179 */ 180void dvmReleaseJniMonitors(Thread* self); 181 182#endif /*_DALVIK_JNIINTERNAL*/ 183