Home | History | Annotate | Download | only in vm
      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  */
     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  */
    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 #endif  // DALVIK_JNIINTERNAL_H_
    166