blob: 3c15ce43e5c2984f4866b2415c9c0f1f355e82ae [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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().
Andy McFadden8e5c7842009-07-23 17:47:18 -070075 *
76 * This is part of Method.jniArgInfo, and must fit in 3 bits.
Bill Buzbeee2557512009-07-27 15:51:54 -070077 * Note: Assembly code in arch/<arch>/Call<arch>.S relies on
78 * the enum values defined here.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080079 */
80typedef enum DalvikJniReturnType {
81 DALVIK_JNI_RETURN_VOID = 0, /* must be zero */
Bill Buzbeee2557512009-07-27 15:51:54 -070082 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
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080089} 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.
Andy McFaddend5ab7262009-08-25 07:19:34 -0700101 *
102 * (This may be implemented directly in assembly in mterp, so changes here
103 * may only affect the portable interpreter.)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800104 */
105INLINE void dvmPopJniLocals(Thread* self, StackSaveArea* saveArea)
106{
Andy McFaddend5ab7262009-08-25 07:19:34 -0700107#ifdef USE_INDIRECT_REF
108 self->jniLocalRefTable.segmentState.all = saveArea->xtra.localRefCookie;
109#else
110 self->jniLocalRefTable.nextEntry = saveArea->xtra.localRefCookie;
111#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800112}
113
114/*
115 * Set the envThreadId field.
116 */
117INLINE void dvmSetJniEnvThreadId(JNIEnv* pEnv, Thread* self)
118{
119 ((JNIEnvExt*)pEnv)->envThreadId = self->threadId;
120 ((JNIEnvExt*)pEnv)->self = self;
121}
122
123/*
Andy McFadden0083d372009-08-21 14:44:04 -0700124 * JNI call bridges. Not called directly.
Andy McFadden59b61772009-05-13 16:44:34 -0700125 *
126 * The "Check" versions are used when CheckJNI is enabled.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800127 */
Andy McFadden0083d372009-08-21 14:44:04 -0700128void dvmCallJNIMethod_general(const u4* args, JValue* pResult,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800129 const Method* method, Thread* self);
Andy McFadden0083d372009-08-21 14:44:04 -0700130void dvmCallJNIMethod_synchronized(const u4* args, JValue* pResult,
Andy McFadden59b61772009-05-13 16:44:34 -0700131 const Method* method, Thread* self);
Andy McFadden0083d372009-08-21 14:44:04 -0700132void dvmCallJNIMethod_virtualNoRef(const u4* args, JValue* pResult,
133 const Method* method, Thread* self);
134void dvmCallJNIMethod_staticNoRef(const u4* args, JValue* pResult,
135 const Method* method, Thread* self);
136void dvmCheckCallJNIMethod_general(const u4* args, JValue* pResult,
137 const Method* method, Thread* self);
138void dvmCheckCallJNIMethod_synchronized(const u4* args, JValue* pResult,
139 const Method* method, Thread* self);
140void dvmCheckCallJNIMethod_virtualNoRef(const u4* args, JValue* pResult,
141 const Method* method, Thread* self);
142void dvmCheckCallJNIMethod_staticNoRef(const u4* args, JValue* pResult,
Andy McFadden59b61772009-05-13 16:44:34 -0700143 const Method* method, Thread* self);
144
145/*
146 * Configure "method" to use the JNI bridge to call "func".
147 */
148void dvmUseJNIBridge(Method* method, void* func);
149
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800150
151/*
152 * Enable the "checked" versions.
153 */
154void dvmUseCheckedJniEnv(JNIEnvExt* pEnv);
155void dvmUseCheckedJniVm(JavaVMExt* pVm);
156void dvmLateEnableCheckedJni(void);
157
158/*
Andy McFaddenab00d452009-08-19 07:21:41 -0700159 * Decode a local, global, or weak-global reference.
160 */
Andy McFaddeneb9cbc32009-08-28 14:45:12 -0700161#ifdef USE_INDIRECT_REF
Andy McFaddenab00d452009-08-19 07:21:41 -0700162Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj);
Andy McFaddeneb9cbc32009-08-28 14:45:12 -0700163#else
164/* use an inline to ensure this is a no-op */
165INLINE Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj) {
166 return (Object*) jobj;
167}
168#endif
Andy McFaddenab00d452009-08-19 07:21:41 -0700169
170/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800171 * Verify that a reference passed in from native code is valid. Returns
172 * an indication of local/global/invalid.
173 */
Andy McFaddenab00d452009-08-19 07:21:41 -0700174jobjectRefType dvmGetJNIRefType(JNIEnv* env, jobject jobj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800175
176/*
177 * Get the last method called on the interp stack. This is the method
178 * "responsible" for calling into JNI.
179 */
180const Method* dvmGetCurrentJNIMethod(void);
181
182/*
183 * Create/destroy a JNIEnv for the current thread.
184 */
185JNIEnv* dvmCreateJNIEnv(Thread* self);
186void dvmDestroyJNIEnv(JNIEnv* env);
187
188/*
189 * Find the JNIEnv associated with the current thread.
190 */
191JNIEnvExt* dvmGetJNIEnvForThread(void);
192
193/*
194 * Extract the return type enum from the "jniArgInfo" value.
195 */
196DalvikJniReturnType dvmGetArgInfoReturnType(int jniArgInfo);
197
198/*
199 * Release all MonitorEnter-acquired locks that are still held. Called at
200 * DetachCurrentThread time.
201 */
202void dvmReleaseJniMonitors(Thread* self);
203
Andy McFaddenb18992f2009-09-25 10:42:15 -0700204
205/*
206 * This mask is applied to weak global reference values returned to
207 * native code. The goal is to create an invalid pointer that will cause
208 * a crash if misused. The mmap region for the virtual heap is typically
209 * around 0x40xxxxxx.
210 *
211 * To make weak global references easily distinguishable from other kinds
212 * of references when !USE_INDIRECT_REF, we XOR the low bits. Assuming >=
213 * 64-bit alignment of objects, this changes the low 3 bits from all clear
214 * to all set.
215 */
216#define WEAK_GLOBAL_XOR 0x9e0fffff
217
218/*
219 * "Obfuscate" a weak global reference pointer.
220 */
221INLINE jweak dvmObfuscateWeakGlobalRef(jobject jobj) {
222 return (jweak) ((u4) jobj ^ WEAK_GLOBAL_XOR);
223}
224
225/*
226 * Undo the obfuscation.
227 */
228INLINE jobject dvmNormalizeWeakGlobalRef(jweak ref) {
229 return (jobject) ((u4) ref ^ WEAK_GLOBAL_XOR);
230}
231
232/*
233 * Returns "true" if this looks like a weak global reference.
234 *
235 * Relies on the low 3 bits being set instead of clear (the latter is
236 * guaranteed by 64-bit alignment of objects).
237 */
238INLINE bool dvmIsWeakGlobalRef(jobject jobj) {
239 return (((u4) jobj & 0x07) == 0x07);
240}
241
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800242#endif /*_DALVIK_JNIINTERNAL*/