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