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 bool 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  */
     35 struct JavaVMExt;
     36 
     37 struct 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 
     52 struct 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  */
     69 enum 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  */
     94 INLINE void dvmPopJniLocals(Thread* self, StackSaveArea* saveArea)
     95 {
     96     self->jniLocalRefTable.segmentState.all = saveArea->xtra.localRefCookie;
     97 }
     98 
     99 /*
    100  * Set the envThreadId field.
    101  */
    102 INLINE void dvmSetJniEnvThreadId(JNIEnv* pEnv, Thread* self)
    103 {
    104     ((JNIEnvExt*)pEnv)->envThreadId = self->threadId;
    105     ((JNIEnvExt*)pEnv)->self = self;
    106 }
    107 
    108 void dvmCallJNIMethod(const u4* args, JValue* pResult,
    109     const Method* method, Thread* self);
    110 void 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  */
    116 void dvmUseJNIBridge(Method* method, void* func);
    117 
    118 
    119 /*
    120  * Enable the "checked" versions.
    121  */
    122 void dvmUseCheckedJniEnv(JNIEnvExt* pEnv);
    123 void dvmUseCheckedJniVm(JavaVMExt* pVm);
    124 void dvmLateEnableCheckedJni(void);
    125 
    126 /*
    127  * Decode a local, global, or weak-global reference.
    128  */
    129 Object* 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  */
    135 jobjectRefType 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  */
    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  * Release all MonitorEnter-acquired locks that are still held.  Called at
    156  * DetachCurrentThread time.
    157  */
    158 void 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  */
    165 void dvmDumpJniReferenceTables(void);
    166 
    167 // Dumps JNI statistics in response to SIGQUIT.
    168 struct DebugOutputTarget;
    169 void dvmDumpJniStats(DebugOutputTarget* target);
    170 
    171 #endif  // DALVIK_JNIINTERNAL_H_
    172