JniInternal.h revision 89c1feb0a69a7707b271086e749975b3f7acacf7
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 */
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().
75 */
76typedef enum DalvikJniReturnType {
77    DALVIK_JNI_RETURN_VOID = 0,     /* must be zero */
78    DALVIK_JNI_RETURN_FLOAT,
79    DALVIK_JNI_RETURN_DOUBLE,
80    DALVIK_JNI_RETURN_S8,
81    DALVIK_JNI_RETURN_S4
82} DalvikJniReturnType;
83
84#define DALVIK_JNI_NO_ARG_INFO  0x80000000
85#define DALVIK_JNI_RETURN_MASK  0x70000000
86#define DALVIK_JNI_RETURN_SHIFT 28
87#define DALVIK_JNI_COUNT_MASK   0x0f000000
88#define DALVIK_JNI_COUNT_SHIFT  24
89
90
91/*
92 * Pop the JNI local stack when we return from a native method.  "saveArea"
93 * points to the StackSaveArea for the method we're leaving.
94 */
95INLINE void dvmPopJniLocals(Thread* self, StackSaveArea* saveArea)
96{
97    if (saveArea->xtra.localRefTop != self->jniLocalRefTable.nextEntry) {
98        LOGVV("LREF: popped %d entries (%d remain)\n",
99            (int)(self->jniLocalRefTable.nextEntry-saveArea->xtra.localRefTop),
100            (int)(saveArea->xtra.localRefTop - self->jniLocalRefTable.table));
101    }
102    self->jniLocalRefTable.nextEntry = saveArea->xtra.localRefTop;
103}
104
105/*
106 * Set the envThreadId field.
107 */
108INLINE void dvmSetJniEnvThreadId(JNIEnv* pEnv, Thread* self)
109{
110    ((JNIEnvExt*)pEnv)->envThreadId = self->threadId;
111    ((JNIEnvExt*)pEnv)->self = self;
112}
113
114/*
115 * JNI call bridges.  Not usually called directly.
116 */
117void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method,
118    Thread* self);
119void dvmCallSynchronizedJNIMethod(const u4* args, JValue* pResult,
120    const Method* method, Thread* self);
121
122/*
123 * Enable the "checked" versions.
124 */
125void dvmUseCheckedJniEnv(JNIEnvExt* pEnv);
126void dvmUseCheckedJniVm(JavaVMExt* pVm);
127void dvmLateEnableCheckedJni(void);
128
129/*
130 * Verify that a reference passed in from native code is valid.  Returns
131 * an indication of local/global/invalid.
132 */
133jobjectRefType dvmGetJNIRefType(Object* obj);
134
135/*
136 * Get the last method called on the interp stack.  This is the method
137 * "responsible" for calling into JNI.
138 */
139const Method* dvmGetCurrentJNIMethod(void);
140
141/*
142 * Create/destroy a JNIEnv for the current thread.
143 */
144JNIEnv* dvmCreateJNIEnv(Thread* self);
145void dvmDestroyJNIEnv(JNIEnv* env);
146
147/*
148 * Find the JNIEnv associated with the current thread.
149 */
150JNIEnvExt* dvmGetJNIEnvForThread(void);
151
152/*
153 * Extract the return type enum from the "jniArgInfo" value.
154 */
155DalvikJniReturnType dvmGetArgInfoReturnType(int jniArgInfo);
156
157/*
158 * Release all MonitorEnter-acquired locks that are still held.  Called at
159 * DetachCurrentThread time.
160 */
161void dvmReleaseJniMonitors(Thread* self);
162
163#endif /*_DALVIK_JNIINTERNAL*/
164