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 */
25 bool dvmJniStartup(void);
26 void 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 */
33 struct JavaVMExt;
34
35 typedef 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
56 typedef 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 */
78 typedef enum DalvikJniReturnType {
79 DALVIK_JNI_RETURN_VOID = 0, /* must be zero */
80 DALVIK_JNI_RETURN_FLOAT,
81 DALVIK_JNI_RETURN_DOUBLE,
82 DALVIK_JNI_RETURN_S8,
83 DALVIK_JNI_RETURN_S4
84 } DalvikJniReturnType;
85
86 #define DALVIK_JNI_NO_ARG_INFO 0x80000000
87 #define DALVIK_JNI_RETURN_MASK 0x70000000
88 #define DALVIK_JNI_RETURN_SHIFT 28
89 #define DALVIK_JNI_COUNT_MASK 0x0f000000
90 #define DALVIK_JNI_COUNT_SHIFT 24
91
92
93 /*
94 * Pop the JNI local stack when we return from a native method. "saveArea"
95 * points to the StackSaveArea for the method we're leaving.
96 */
dvmPopJniLocals(Thread * self,StackSaveArea * saveArea)97 INLINE void dvmPopJniLocals(Thread* self, StackSaveArea* saveArea)
98 {
99 if (saveArea->xtra.localRefTop != self->jniLocalRefTable.nextEntry) {
100 LOGVV("LREF: popped %d entries (%d remain)\n",
101 (int)(self->jniLocalRefTable.nextEntry-saveArea->xtra.localRefTop),
102 (int)(saveArea->xtra.localRefTop - self->jniLocalRefTable.table));
103 }
104 self->jniLocalRefTable.nextEntry = saveArea->xtra.localRefTop;
105 }
106
107 /*
108 * Set the envThreadId field.
109 */
dvmSetJniEnvThreadId(JNIEnv * pEnv,Thread * self)110 INLINE void dvmSetJniEnvThreadId(JNIEnv* pEnv, Thread* self)
111 {
112 ((JNIEnvExt*)pEnv)->envThreadId = self->threadId;
113 ((JNIEnvExt*)pEnv)->self = self;
114 }
115
116 /*
117 * JNI call bridges. Not usually called directly.
118 */
119 void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method,
120 Thread* self);
121 void dvmCallSynchronizedJNIMethod(const u4* args, JValue* pResult,
122 const Method* method, Thread* self);
123
124 /*
125 * Enable the "checked" versions.
126 */
127 void dvmUseCheckedJniEnv(JNIEnvExt* pEnv);
128 void dvmUseCheckedJniVm(JavaVMExt* pVm);
129 void dvmLateEnableCheckedJni(void);
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(Object* obj);
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 * Extract the return type enum from the "jniArgInfo" value.
156 */
157 DalvikJniReturnType dvmGetArgInfoReturnType(int jniArgInfo);
158
159 /*
160 * Release all MonitorEnter-acquired locks that are still held. Called at
161 * DetachCurrentThread time.
162 */
163 void dvmReleaseJniMonitors(Thread* self);
164
165 #endif /*_DALVIK_JNIINTERNAL*/
166