Home | History | Annotate | Download | only in interp
      1 /*
      2  * Copyright (C) 2009 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  * Jit control
     18  */
     19 #ifndef DALVIK_INTERP_JIT_H_
     20 #define DALVIK_INTERP_JIT_H_
     21 
     22 #include "InterpDefs.h"
     23 #include "mterp/common/jit-config.h"
     24 
     25 #define JIT_MAX_TRACE_LEN 100
     26 
     27 #if defined (WITH_SELF_VERIFICATION)
     28 
     29 #define REG_SPACE 256                /* default size of shadow space */
     30 #define HEAP_SPACE JIT_MAX_TRACE_LEN /* default size of heap space */
     31 
     32 struct ShadowHeap {
     33     int addr;
     34     int data;
     35 };
     36 
     37 struct InstructionTrace {
     38     int addr;
     39     DecodedInstruction decInsn;
     40 };
     41 
     42 struct ShadowSpace {
     43     const u2* startPC;          /* starting pc of jitted region */
     44     u4* fp;                     /* starting fp of jitted region */
     45     const Method *method;
     46     DvmDex* methodClassDex;
     47     JValue retval;
     48     const u1* interpStackEnd;
     49     SelfVerificationState jitExitState;  /* exit point for JIT'ed code */
     50     SelfVerificationState selfVerificationState;  /* current SV running state */
     51     const u2* endPC;            /* ending pc of jitted region */
     52     void* shadowFP;       /* pointer to fp in shadow space */
     53     int* registerSpace;         /* copy of register state */
     54     int registerSpaceSize;      /* current size of register space */
     55     ShadowHeap heapSpace[HEAP_SPACE]; /* copy of heap space */
     56     ShadowHeap* heapSpaceTail;        /* tail pointer to heapSpace */
     57     const void* endShadowFP;    /* ending fp in shadow space */
     58     InstructionTrace trace[JIT_MAX_TRACE_LEN]; /* opcode trace for debugging */
     59     int traceLength;            /* counter for current trace length */
     60 };
     61 
     62 /*
     63  * Self verification functions.
     64  */
     65 extern "C" {
     66 void* dvmSelfVerificationShadowSpaceAlloc(Thread* self);
     67 void dvmSelfVerificationShadowSpaceFree(Thread* self);
     68 void* dvmSelfVerificationSaveState(const u2* pc, u4* fp,
     69                                    Thread* self,
     70                                    int targetTrace);
     71 void* dvmSelfVerificationRestoreState(const u2* pc, u4* fp,
     72                                       SelfVerificationState exitPoint,
     73                                       Thread *self);
     74 void dvmCheckSelfVerification(const u2* pc, Thread* self);
     75 }
     76 #endif
     77 
     78 /*
     79  * Offsets for metadata in the trace run array from the trace that ends with
     80  * invoke instructions.
     81  */
     82 #define JIT_TRACE_CLASS_DESC    1
     83 #define JIT_TRACE_CLASS_LOADER  2
     84 #define JIT_TRACE_CUR_METHOD    3
     85 
     86 /*
     87  * JitTable hash function.
     88  */
     89 
     90 static inline u4 dvmJitHashMask( const u2* p, u4 mask ) {
     91     return ((((u4)p>>12)^(u4)p)>>1) & (mask);
     92 }
     93 
     94 static inline u4 dvmJitHash( const u2* p ) {
     95     return dvmJitHashMask( p, gDvmJit.jitTableMask );
     96 }
     97 
     98 /*
     99  * The width of the chain field in JitEntryInfo sets the upper
    100  * bound on the number of translations.  Be careful if changing
    101  * the size of JitEntry struct - the Dalvik PC to JitEntry
    102  * hash functions have built-in knowledge of the size.
    103  */
    104 #define JIT_ENTRY_CHAIN_WIDTH 2
    105 #define JIT_MAX_ENTRIES (1 << (JIT_ENTRY_CHAIN_WIDTH * 8))
    106 
    107 /*
    108  * The trace profiling counters are allocated in blocks and individual
    109  * counters must not move so long as any referencing trace exists.
    110  */
    111 #define JIT_PROF_BLOCK_ENTRIES 1024
    112 #define JIT_PROF_BLOCK_BUCKETS (JIT_MAX_ENTRIES / JIT_PROF_BLOCK_ENTRIES)
    113 
    114 typedef s4 JitTraceCounter_t;
    115 
    116 struct JitTraceProfCounters {
    117     unsigned int           next;
    118     JitTraceCounter_t      *buckets[JIT_PROF_BLOCK_BUCKETS];
    119 };
    120 
    121 /*
    122  * Entries in the JIT's address lookup hash table.
    123  * Fields which may be updated by multiple threads packed into a
    124  * single 32-bit word to allow use of atomic update.
    125  */
    126 
    127 struct JitEntryInfo {
    128     unsigned int           isMethodEntry:1;
    129     unsigned int           inlineCandidate:1;
    130     unsigned int           profileEnabled:1;
    131     JitInstructionSetType  instructionSet:3;
    132     unsigned int           profileOffset:5;
    133     unsigned int           unused:5;
    134     u2                     chain;                 /* Index of next in chain */
    135 };
    136 
    137 union JitEntryInfoUnion {
    138     JitEntryInfo info;
    139     volatile int infoWord;
    140 };
    141 
    142 struct JitEntry {
    143     JitEntryInfoUnion   u;
    144     const u2*           dPC;            /* Dalvik code address */
    145     void*               codeAddress;    /* Code address of native translation */
    146 };
    147 
    148 extern "C" {
    149 void dvmCheckJit(const u2* pc, Thread* self);
    150 void* dvmJitGetTraceAddr(const u2* dPC);
    151 void* dvmJitGetMethodAddr(const u2* dPC);
    152 void* dvmJitGetTraceAddrThread(const u2* dPC, Thread* self);
    153 void* dvmJitGetMethodAddrThread(const u2* dPC, Thread* self);
    154 void dvmJitCheckTraceRequest(Thread* self);
    155 void dvmJitStopTranslationRequests(void);
    156 #if defined(WITH_JIT_TUNING)
    157 void dvmBumpNoChain(int from);
    158 void dvmBumpNormal(void);
    159 void dvmBumpPunt(int from);
    160 #endif
    161 void dvmJitStats(void);
    162 bool dvmJitResizeJitTable(unsigned int size);
    163 void dvmJitResetTable(void);
    164 JitEntry *dvmJitFindEntry(const u2* pc, bool isMethodEntry);
    165 s8 dvmJitd2l(double d);
    166 s8 dvmJitf2l(float f);
    167 void dvmJitSetCodeAddr(const u2* dPC, void *nPC, JitInstructionSetType set,
    168                        bool isMethodEntry, int profilePrefixSize);
    169 void dvmJitEndTraceSelect(Thread* self, const u2* dPC);
    170 JitTraceCounter_t *dvmJitNextTraceCounter(void);
    171 void dvmJitTraceProfilingOff(void);
    172 void dvmJitTraceProfilingOn(void);
    173 void dvmJitChangeProfileMode(TraceProfilingModes newState);
    174 void dvmJitDumpTraceDesc(JitTraceDescription *trace);
    175 void dvmJitUpdateThreadStateSingle(Thread* threead);
    176 void dvmJitUpdateThreadStateAll(void);
    177 void dvmJitResumeTranslation(Thread* self, const u2* pc, const u4* fp);
    178 }
    179 
    180 #endif  // DALVIK_INTERP_JIT_H_
    181