• 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     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