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