JniInternal.h revision a5f3ed80b3b058b006ee2b09915d1400cebd0442
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#ifdef __cplusplus
25extern "C" {
26#endif
27
28/* system init/shutdown */
29bool dvmJniStartup(void);
30void dvmJniShutdown(void);
31
32/*
33 * Our data structures for JNIEnv and JavaVM.
34 *
35 * Native code thinks it has a pointer to a pointer.  We know better.
36 */
37struct JavaVMExt;
38
39typedef struct JNIEnvExt {
40    const struct JNINativeInterface* funcTable;     /* must be first */
41
42    const struct JNINativeInterface* baseFuncTable;
43
44    /* pointer to the VM we are a part of */
45    struct JavaVMExt* vm;
46
47    u4      envThreadId;
48    Thread* self;
49
50    /* if nonzero, we are in a "critical" JNI call */
51    int     critical;
52
53    struct JNIEnvExt* prev;
54    struct JNIEnvExt* next;
55} JNIEnvExt;
56
57typedef struct JavaVMExt {
58    const struct JNIInvokeInterface* funcTable;     /* must be first */
59
60    const struct JNIInvokeInterface* baseFuncTable;
61
62    /* head of list of JNIEnvs associated with this VM */
63    JNIEnvExt*      envList;
64    pthread_mutex_t envListLock;
65} JavaVMExt;
66
67/*
68 * Native function return type; used by dvmPlatformInvoke().
69 *
70 * This is part of Method.jniArgInfo, and must fit in 3 bits.
71 * Note: Assembly code in arch/<arch>/Call<arch>.S relies on
72 * the enum values defined here.
73 */
74typedef enum DalvikJniReturnType {
75    DALVIK_JNI_RETURN_VOID = 0,     /* must be zero */
76    DALVIK_JNI_RETURN_FLOAT = 1,
77    DALVIK_JNI_RETURN_DOUBLE = 2,
78    DALVIK_JNI_RETURN_S8 = 3,
79    DALVIK_JNI_RETURN_S4 = 4,
80    DALVIK_JNI_RETURN_S2 = 5,
81    DALVIK_JNI_RETURN_U2 = 6,
82    DALVIK_JNI_RETURN_S1 = 7
83} DalvikJniReturnType;
84
85#define DALVIK_JNI_NO_ARG_INFO  0x80000000
86#define DALVIK_JNI_RETURN_MASK  0x70000000
87#define DALVIK_JNI_RETURN_SHIFT 28
88#define DALVIK_JNI_COUNT_MASK   0x0f000000
89#define DALVIK_JNI_COUNT_SHIFT  24
90
91
92/*
93 * Pop the JNI local stack when we return from a native method.  "saveArea"
94 * points to the StackSaveArea for the method we're leaving.
95 *
96 * (This may be implemented directly in assembly in mterp, so changes here
97 * may only affect the portable interpreter.)
98 */
99INLINE void dvmPopJniLocals(Thread* self, StackSaveArea* saveArea)
100{
101    self->jniLocalRefTable.segmentState.all = saveArea->xtra.localRefCookie;
102}
103
104/*
105 * Set the envThreadId field.
106 */
107INLINE void dvmSetJniEnvThreadId(JNIEnv* pEnv, Thread* self)
108{
109    ((JNIEnvExt*)pEnv)->envThreadId = self->threadId;
110    ((JNIEnvExt*)pEnv)->self = self;
111}
112
113/*
114 * JNI call bridges.  Not called directly.
115 *
116 * The "Check" versions are used when CheckJNI is enabled.
117 */
118void dvmCallJNIMethod_general(const u4* args, JValue* pResult,
119    const Method* method, Thread* self);
120void dvmCallJNIMethod_synchronized(const u4* args, JValue* pResult,
121    const Method* method, Thread* self);
122void dvmCallJNIMethod_virtualNoRef(const u4* args, JValue* pResult,
123    const Method* method, Thread* self);
124void dvmCallJNIMethod_staticNoRef(const u4* args, JValue* pResult,
125    const Method* method, Thread* self);
126void dvmCheckCallJNIMethod_general(const u4* args, JValue* pResult,
127    const Method* method, Thread* self);
128void dvmCheckCallJNIMethod_synchronized(const u4* args, JValue* pResult,
129    const Method* method, Thread* self);
130void dvmCheckCallJNIMethod_virtualNoRef(const u4* args, JValue* pResult,
131    const Method* method, Thread* self);
132void dvmCheckCallJNIMethod_staticNoRef(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 * Decode a local, global, or weak-global reference.
150 */
151Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj);
152
153/*
154 * Verify that a reference passed in from native code is valid.  Returns
155 * an indication of local/global/invalid.
156 */
157jobjectRefType dvmGetJNIRefType(JNIEnv* env, jobject jobj);
158
159/*
160 * Get the last method called on the interp stack.  This is the method
161 * "responsible" for calling into JNI.
162 */
163const Method* dvmGetCurrentJNIMethod(void);
164
165/*
166 * Create/destroy a JNIEnv for the current thread.
167 */
168JNIEnv* dvmCreateJNIEnv(Thread* self);
169void dvmDestroyJNIEnv(JNIEnv* env);
170
171/*
172 * Find the JNIEnv associated with the current thread.
173 */
174JNIEnvExt* dvmGetJNIEnvForThread(void);
175
176/*
177 * Extract the return type enum from the "jniArgInfo" value.
178 */
179DalvikJniReturnType dvmGetArgInfoReturnType(int jniArgInfo);
180
181/*
182 * Release all MonitorEnter-acquired locks that are still held.  Called at
183 * DetachCurrentThread time.
184 */
185void dvmReleaseJniMonitors(Thread* self);
186
187/*
188 * Dump the contents of the JNI reference tables to the log file.
189 *
190 * The local ref tables associated with other threads are not included.
191 */
192void dvmDumpJniReferenceTables(void);
193
194#ifdef __cplusplus
195}
196#endif
197
198#endif /*_DALVIK_JNIINTERNAL*/
199