1 /* 2 * Copyright (C) 2011 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 * Dalvik interpreter definitions. These are internal to the interpreter. 18 * 19 * This includes defines, types, function declarations, and inline functions 20 * that are common to all interpreter implementations. 21 * 22 * Functions and globals declared here are defined in Interp.c. 23 */ 24 #ifndef DALVIK_INTERP_STATE_H_ 25 #define DALVIK_INTERP_STATE_H_ 26 27 /* 28 * For x86 JIT. In the lowered code sequences for bytecodes, at most 10 29 * temporary variables may be live at the same time. Therefore, at most 30 * 10 temporary variables can be spilled at the same time. 31 */ 32 #define MAX_SPILL_JIT_IA 10 33 34 /* 35 * Execution mode, e.g. interpreter vs. JIT. 36 */ 37 enum ExecutionMode { 38 kExecutionModeUnknown = 0, 39 kExecutionModeInterpPortable, 40 kExecutionModeInterpFast, 41 #if defined(WITH_JIT) 42 kExecutionModeJit, 43 #endif 44 #if defined(WITH_JIT) /* IA only */ 45 kExecutionModeNcgO0, 46 kExecutionModeNcgO1, 47 #endif 48 }; 49 50 /* 51 * Execution sub modes, e.g. debugging, profiling, etc. 52 * Treated as bit flags for fast access. These values are used directly 53 * by assembly code in the mterp interpeter and may also be used by 54 * code generated by the JIT. Take care when changing. 55 */ 56 enum ExecutionSubModes { 57 kSubModeNormal = 0x0000, /* No active subMode */ 58 kSubModeMethodTrace = 0x0001, 59 kSubModeEmulatorTrace = 0x0002, 60 kSubModeInstCounting = 0x0004, 61 kSubModeDebuggerActive = 0x0008, 62 kSubModeSuspendPending = 0x0010, 63 kSubModeCallbackPending = 0x0020, 64 kSubModeCountedStep = 0x0040, 65 kSubModeCheckAlways = 0x0080, 66 kSubModeJitTraceBuild = 0x4000, 67 kSubModeJitSV = 0x8000, 68 kSubModeDebugProfile = (kSubModeMethodTrace | 69 kSubModeEmulatorTrace | 70 kSubModeInstCounting | 71 kSubModeDebuggerActive) 72 }; 73 74 /* 75 * Interpreter break flags. When set, causes the interpreter to 76 * break from normal execution and invoke the associated callback 77 * handler. 78 */ 79 80 enum InterpBreakFlags { 81 kInterpNoBreak = 0x00, /* Don't check */ 82 kInterpSingleStep = 0x01, /* Check between each inst */ 83 kInterpSafePoint = 0x02, /* Check at safe points */ 84 }; 85 86 /* 87 * Mapping between subModes and required check intervals. Note: in 88 * the future we might want to make this mapping target-dependent. 89 */ 90 #define SINGLESTEP_BREAK_MASK ( kSubModeInstCounting | \ 91 kSubModeDebuggerActive | \ 92 kSubModeCountedStep | \ 93 kSubModeCheckAlways | \ 94 kSubModeJitSV | \ 95 kSubModeJitTraceBuild ) 96 97 #define SAFEPOINT_BREAK_MASK ( kSubModeSuspendPending | \ 98 kSubModeCallbackPending ) 99 100 typedef bool (*SafePointCallback)(struct Thread* thread, void* arg); 101 102 /* 103 * Identify which break and submode flags should be local 104 * to an interpreter activation. 105 */ 106 #define LOCAL_SUBMODE (kSubModeJitTraceBuild) 107 108 struct InterpSaveState { 109 const u2* pc; // Dalvik PC 110 u4* curFrame; // Dalvik frame pointer 111 const Method *method; // Method being executed 112 DvmDex* methodClassDex; 113 JValue retval; 114 void* bailPtr; 115 #if defined(WITH_TRACKREF_CHECKS) 116 int debugTrackedRefStart; 117 #else 118 int unused; // Keep struct size constant 119 #endif 120 struct InterpSaveState* prev; // To follow nested activations 121 } __attribute__ ((__packed__)); 122 123 #ifdef WITH_JIT 124 /* 125 * NOTE: Only entry points dispatched via [self + #offset] are put 126 * in this struct, and there are six of them: 127 * 1) dvmJitToInterpNormal: find if there is a corresponding compilation for 128 * the new dalvik PC. If so, chain the originating compilation with the 129 * target then jump to it. If the destination trace doesn't exist, update 130 * the profile count for that Dalvik PC. 131 * 2) dvmJitToInterpNoChain: similar to dvmJitToInterpNormal but chaining is 132 * not performed. 133 * 3) dvmJitToInterpPunt: use the fast interpreter to execute the next 134 * instruction(s) and stay there as long as it is appropriate to return 135 * to the compiled land. This is used when the jit'ed code is about to 136 * throw an exception. 137 * 4) dvmJitToInterpSingleStep: use the portable interpreter to execute the 138 * next instruction only and return to pre-specified location in the 139 * compiled code to resume execution. This is mainly used as debugging 140 * feature to bypass problematic opcode implementations without 141 * disturbing the trace formation. 142 * 5) dvmJitToTraceSelect: Similar to dvmJitToInterpNormal except for the 143 * profiling operation. If the new Dalvik PC is dominated by an already 144 * translated trace, directly request a new translation if the destinaion 145 * trace doesn't exist. 146 * 6) dvmJitToBackwardBranch: special case for SELF_VERIFICATION when the 147 * destination Dalvik PC is included by the trace itself. 148 */ 149 struct JitToInterpEntries { 150 void (*dvmJitToInterpNormal)(void); 151 void (*dvmJitToInterpNoChain)(void); 152 void (*dvmJitToInterpPunt)(void); 153 void (*dvmJitToInterpSingleStep)(void); 154 void (*dvmJitToInterpTraceSelect)(void); 155 #if defined(WITH_SELF_VERIFICATION) 156 void (*dvmJitToInterpBackwardBranch)(void); 157 #else 158 void (*unused)(void); // Keep structure size constant 159 #endif 160 }; 161 162 /* States of the interpreter when serving a JIT-related request */ 163 enum JitState { 164 /* Entering states in the debug interpreter */ 165 kJitNot = 0, // Non-JIT related reasons */ 166 kJitTSelectRequest = 1, // Request a trace (subject to filtering) 167 kJitTSelectRequestHot = 2, // Request a hot trace (bypass the filter) 168 kJitSelfVerification = 3, // Self Verification Mode 169 170 /* Operational states in the debug interpreter */ 171 kJitTSelect = 4, // Actively selecting a trace 172 kJitTSelectEnd = 5, // Done with the trace - wrap it up 173 kJitDone = 6, // No further JIT actions for interpBreak 174 }; 175 176 #if defined(WITH_SELF_VERIFICATION) 177 enum SelfVerificationState { 178 kSVSIdle = 0, // Idle 179 kSVSStart = 1, // Shadow space set up, running compiled code 180 kSVSPunt = 2, // Exiting compiled code by punting 181 kSVSSingleStep = 3, // Exiting compiled code by single stepping 182 kSVSNoProfile = 4, // Exiting compiled code and don't collect profiles 183 kSVSTraceSelect = 5, // Exiting compiled code and compile the next pc 184 kSVSNormal = 6, // Exiting compiled code normally 185 kSVSNoChain = 7, // Exiting compiled code by no chain 186 kSVSBackwardBranch = 8, // Exiting compiled code with backward branch trace 187 kSVSDebugInterp = 9, // Normal state restored, running debug interpreter 188 }; 189 #endif 190 191 /* Number of entries in the 2nd level JIT profiler filter cache */ 192 #define JIT_TRACE_THRESH_FILTER_SIZE 32 193 /* Number of low dalvik pc address bits to include in 2nd level filter key */ 194 #define JIT_TRACE_THRESH_FILTER_PC_BITS 4 195 #define MAX_JIT_RUN_LEN 64 196 197 enum JitHint { 198 kJitHintNone = 0, 199 kJitHintTaken = 1, // Last inst in run was taken branch 200 kJitHintNotTaken = 2, // Last inst in run was not taken branch 201 kJitHintNoBias = 3, // Last inst in run was unbiased branch 202 }; 203 204 /* 205 * Element of a Jit trace description. If the isCode bit is set, it describes 206 * a contiguous sequence of Dalvik byte codes. 207 */ 208 struct JitCodeDesc { 209 unsigned numInsts:8; // Number of Byte codes in run 210 unsigned runEnd:1; // Run ends with last byte code 211 JitHint hint:7; // Hint to apply to final code of run 212 u2 startOffset; // Starting offset for trace run 213 }; 214 215 /* 216 * A complete list of trace runs passed to the compiler looks like the 217 * following: 218 * frag1 219 * frag2 220 * frag3 221 * meta1 222 * : 223 * metan 224 * frag4 225 * 226 * frags 1-4 have the "isCode" field set and describe the location/length of 227 * real code traces, while metas 1-n are misc information. 228 * The meaning of the meta content is loosely defined. It is usually the code 229 * fragment right before the first meta field (frag3 in this case) to 230 * understand and parse them. Frag4 could be a dummy one with 0 "numInsts" but 231 * the "runEnd" field set. 232 * 233 * For example, if a trace run contains a method inlining target, the class 234 * descriptor/loader of "this" and the currently resolved method pointer are 235 * three instances of meta information stored there. 236 */ 237 struct JitTraceRun { 238 union { 239 JitCodeDesc frag; 240 void* meta; 241 } info; 242 u4 isCode:1; 243 u4 unused:31; 244 }; 245 246 #if defined(ARCH_IA32) 247 /* 248 * JIT code genarator optimization level 249 */ 250 enum JitOptLevel { 251 kJitOptLevelO0 = 0, 252 kJitOptLevelO1 = 1, 253 }; 254 #endif // #if defined(ARCH_IA32) 255 #endif 256 257 #endif // DALVIK_INTERP_STATE_H_ 258