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