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 */
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 struct 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
50 struct 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 */
67 enum 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 */
dvmPopJniLocals(Thread * self,StackSaveArea * saveArea)92 INLINE void dvmPopJniLocals(Thread* self, StackSaveArea* saveArea)
93 {
94 self->jniLocalRefTable.segmentState.all = saveArea->xtra.localRefCookie;
95 }
96
97 /*
98 * Set the envThreadId field.
99 */
dvmSetJniEnvThreadId(JNIEnv * pEnv,Thread * self)100 INLINE void dvmSetJniEnvThreadId(JNIEnv* pEnv, Thread* self)
101 {
102 ((JNIEnvExt*)pEnv)->envThreadId = self->threadId;
103 ((JNIEnvExt*)pEnv)->self = self;
104 }
105
106 void dvmCallJNIMethod(const u4* args, JValue* pResult,
107 const Method* method, Thread* self);
108 void dvmCheckCallJNIMethod(const u4* args, JValue* pResult,
109 const Method* method, Thread* self);
110
111 /*
112 * Configure "method" to use the JNI bridge to call "func".
113 */
114 void dvmUseJNIBridge(Method* method, void* func);
115
116
117 /*
118 * Enable the "checked" versions.
119 */
120 void dvmUseCheckedJniEnv(JNIEnvExt* pEnv);
121 void dvmUseCheckedJniVm(JavaVMExt* pVm);
122 void dvmLateEnableCheckedJni(void);
123
124 /*
125 * Decode a local, global, or weak-global reference.
126 */
127 Object* dvmDecodeIndirectRef(Thread* self, jobject jobj);
128
129 /*
130 * Verify that a reference passed in from native code is valid. Returns
131 * an indication of local/global/invalid.
132 */
133 jobjectRefType dvmGetJNIRefType(Thread* self, jobject jobj);
134
135 /*
136 * Get the last method called on the interp stack. This is the method
137 * "responsible" for calling into JNI.
138 */
139 const Method* dvmGetCurrentJNIMethod(void);
140
141 /*
142 * Create/destroy a JNIEnv for the current thread.
143 */
144 JNIEnv* dvmCreateJNIEnv(Thread* self);
145 void dvmDestroyJNIEnv(JNIEnv* env);
146
147 /*
148 * Find the JNIEnv associated with the current thread.
149 */
150 JNIEnvExt* dvmGetJNIEnvForThread(void);
151
152 /*
153 * Release all MonitorEnter-acquired locks that are still held. Called at
154 * DetachCurrentThread time.
155 */
156 void dvmReleaseJniMonitors(Thread* self);
157
158 /*
159 * Dump the contents of the JNI reference tables to the log file.
160 *
161 * The local ref tables associated with other threads are not included.
162 */
163 void dvmDumpJniReferenceTables(void);
164
165 // Dumps JNI statistics in response to SIGQUIT.
166 struct DebugOutputTarget;
167 void dvmDumpJniStats(DebugOutputTarget* target);
168
169 #endif // DALVIK_JNIINTERNAL_H_
170