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