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