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