• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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