blob: 6ba9e12c1d52f37587b58566eb911b2c165064e5 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 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_DEFS
25#define _DALVIK_INTERP_DEFS
26
27
28/*
29 * Specify the starting point when switching between interpreters.
30 */
31typedef enum InterpEntry {
32 kInterpEntryInstr = 0, // continue to next instruction
33 kInterpEntryReturn = 1, // jump to method return
34 kInterpEntryThrow = 2, // jump to exception throw
Ben Chengba4fc8b2009-06-01 13:00:29 -070035#if defined(WITH_JIT)
36 kInterpEntryResume = 3, // Resume after single-step
37#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080038} InterpEntry;
39
Ben Chengba4fc8b2009-06-01 13:00:29 -070040#if defined(WITH_JIT)
41/*
Ben Cheng38329f52009-07-07 14:19:20 -070042 * There are six entry points from the compiled code to the interpreter:
Ben Chengba4fc8b2009-06-01 13:00:29 -070043 * 1) dvmJitToInterpNormal: find if there is a corresponding compilation for
44 * the new dalvik PC. If so, chain the originating compilation with the
45 * target then jump to it.
46 * 2) dvmJitToInterpInvokeNoChain: similar to 1) but don't chain. This is
47 * for handling 1-to-many mappings like virtual method call and
48 * packed switch.
49 * 3) dvmJitToInterpPunt: use the fast interpreter to execute the next
Bill Buzbee48f18242009-06-19 16:02:27 -070050 * instruction(s) and stay there as long as it is appropriate to return
Ben Chengba4fc8b2009-06-01 13:00:29 -070051 * to the compiled land. This is used when the jit'ed code is about to
52 * throw an exception.
53 * 4) dvmJitToInterpSingleStep: use the portable interpreter to execute the
54 * next instruction only and return to pre-specified location in the
55 * compiled code to resume execution. This is mainly used as debugging
56 * feature to bypass problematic opcode implementations without
57 * disturbing the trace formation.
58 * 5) dvmJitToTraceSelect: if there is a single exit from a translation that
59 * has already gone hot enough to be translated, we should assume that
60 * the exit point should also be translated (this is a common case for
61 * invokes). This trace exit will first check for a chaining
62 * opportunity, and if none is available will switch to the debug
63 * interpreter immediately for trace selection (as if threshold had
64 * just been reached).
Ben Cheng38329f52009-07-07 14:19:20 -070065 * 6) dvmJitToPredictedChain: patch the chaining cell for a virtual call site
66 * to a predicted callee.
Jeff Hao97319a82009-08-12 16:57:15 -070067 * 7) dvmJitToBackwardBranch: (WITH_SELF_VERIFICATION ONLY) special case of 1)
68 * and 5). This is used instead if the ending branch of the trace jumps back
69 * into the same basic block.
Ben Chengba4fc8b2009-06-01 13:00:29 -070070 */
71struct JitToInterpEntries {
72 void *dvmJitToInterpNormal;
73 void *dvmJitToInterpNoChain;
74 void *dvmJitToInterpPunt;
75 void *dvmJitToInterpSingleStep;
Ben Cheng40094c12010-02-24 20:58:44 -080076 void *dvmJitToInterpTraceSelectNoChain;
77 void *dvmJitToInterpTraceSelect;
Ben Cheng38329f52009-07-07 14:19:20 -070078 void *dvmJitToPatchPredictedChain;
Jeff Hao97319a82009-08-12 16:57:15 -070079#if defined(WITH_SELF_VERIFICATION)
Ben Cheng40094c12010-02-24 20:58:44 -080080 void *dvmJitToInterpBackwardBranch;
Jeff Hao97319a82009-08-12 16:57:15 -070081#endif
Ben Chengba4fc8b2009-06-01 13:00:29 -070082};
Bill Buzbee48f18242009-06-19 16:02:27 -070083
Bill Buzbee342806d2009-12-08 12:37:13 -080084/*
85 * Size of save area for callee-save FP regs, which are not automatically
86 * saved by interpreter main because it doesn't use them (but Jit'd code
87 * may). Save/restore routine is defined by target, and size should
88 * be >= max needed by any target.
89 */
90#define JIT_CALLEE_SAVE_DOUBLE_COUNT 8
91
Ben Cheng40094c12010-02-24 20:58:44 -080092/* Number of entries in the 2nd level JIT profiler filter cache */
93#define JIT_TRACE_THRESH_FILTER_SIZE 32
buzbee852aacd2010-06-08 16:24:46 -070094/* Number of low dalvik pc address bits to include in 2nd level filter key */
95#define JIT_TRACE_THRESH_FILTER_PC_BITS 4
Ben Chengba4fc8b2009-06-01 13:00:29 -070096#endif
97
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080098/*
99 * Interpreter context, used when switching from one interpreter to
100 * another. We also tuck "mterp" state in here.
101 */
102typedef struct InterpState {
103 /*
104 * To make some mterp state updates easier, "pc" and "fp" MUST come
105 * first and MUST appear in this order.
106 */
107 const u2* pc; // program counter
108 u4* fp; // frame pointer
109
110 JValue retval; // return value -- "out" only
111 const Method* method; // method being executed
112
113
114 /* ----------------------------------------------------------------------
115 * Mterp-only state
116 */
117 DvmDex* methodClassDex;
118 Thread* self;
119
120 /* housekeeping */
121 void* bailPtr;
122
123 /*
124 * These are available globally, from gDvm, or from another glue field
125 * (self/method). They're copied in here for speed.
126 */
Andy McFaddenc95e0fb2010-04-29 14:13:01 -0700127 /* copy of self->interpStackEnd */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800128 const u1* interpStackEnd;
Andy McFaddenc95e0fb2010-04-29 14:13:01 -0700129 /* points at self->suspendCount */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800130 volatile int* pSelfSuspendCount;
buzbee919eb062010-07-12 12:59:22 -0700131 /* Biased base of GC's card table */
132 u1* cardTable;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800133#if defined(WITH_DEBUGGER)
Andy McFaddenc95e0fb2010-04-29 14:13:01 -0700134 /* points at gDvm.debuggerActive, or NULL if debugger not enabled */
Andy McFaddena4365642009-08-07 11:37:44 -0700135 volatile u1* pDebuggerActive;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800136#endif
137#if defined(WITH_PROFILER)
Andy McFaddenc95e0fb2010-04-29 14:13:01 -0700138 /* points at gDvm.activeProfilers */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800139 volatile int* pActiveProfilers;
140#endif
141 /* ----------------------------------------------------------------------
142 */
143
144 /*
145 * Interpreter switching.
146 */
147 InterpEntry entryPoint; // what to do when we start
Ben Chengba4fc8b2009-06-01 13:00:29 -0700148 int nextMode; // INTERP_STD, INTERP_DBG
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800149
Ben Chengba4fc8b2009-06-01 13:00:29 -0700150#if defined(WITH_JIT)
151 /*
152 * Local copies of field from gDvm placed here for fast access
153 */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700154 unsigned char* pJitProfTable;
155 JitState jitState;
buzbee919eb062010-07-12 12:59:22 -0700156 const void* jitResumeNPC; // Native PC of compiled code
157 const u2* jitResumeDPC; // Dalvik PC corresponding to NPC
Bill Buzbeed7269912009-11-10 14:31:32 -0800158 int jitThreshold;
Bill Buzbee964a7b02010-01-28 12:54:19 -0800159 /*
160 * ppJitProfTable holds the address of gDvmJit.pJitProfTable, which
161 * doubles as an on/off switch for the Jit. Because a change in
162 * the value of gDvmJit.pJitProfTable isn't reflected in the cached
163 * copy above (pJitProfTable), we need to periodically refresh it.
164 * ppJitProfTable is used for that purpose.
165 */
166 unsigned char** ppJitProfTable; // Used to refresh pJitProfTable
Ben Chengb88ec3c2010-05-17 12:50:33 -0700167 int icRechainCount; // Count down to next rechain request
Ben Chengba4fc8b2009-06-01 13:00:29 -0700168#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800169
170#if defined(WITH_PROFILER) || defined(WITH_DEBUGGER)
171 bool debugIsMethodEntry; // used for method entry event triggers
172#endif
173#if defined(WITH_TRACKREF_CHECKS)
174 int debugTrackedRefStart; // tracked refs from prior invocations
175#endif
176
Ben Chengba4fc8b2009-06-01 13:00:29 -0700177#if defined(WITH_JIT)
178 struct JitToInterpEntries jitToInterpEntries;
179
180 int currTraceRun;
181 int totalTraceLen; // Number of Dalvik insts in trace
Ben Cheng79d173c2009-09-29 16:12:51 -0700182 const u2* currTraceHead; // Start of the trace we're building
183 const u2* currRunHead; // Start of run we're building
Ben Chengba4fc8b2009-06-01 13:00:29 -0700184 int currRunLen; // Length of run in 16-bit words
Bill Buzbee48f18242009-06-19 16:02:27 -0700185 int lastThreshFilter;
Ben Cheng79d173c2009-09-29 16:12:51 -0700186 const u2* lastPC; // Stage the PC first for the threaded interpreter
Ben Cheng40094c12010-02-24 20:58:44 -0800187 intptr_t threshFilter[JIT_TRACE_THRESH_FILTER_SIZE];
Ben Chengba4fc8b2009-06-01 13:00:29 -0700188 JitTraceRun trace[MAX_JIT_RUN_LEN];
Bill Buzbee342806d2009-12-08 12:37:13 -0800189 double calleeSave[JIT_CALLEE_SAVE_DOUBLE_COUNT];
Ben Chengba4fc8b2009-06-01 13:00:29 -0700190#endif
191
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800192} InterpState;
193
194/*
195 * These are generated from InterpCore.h.
196 */
197extern bool dvmInterpretDbg(Thread* self, InterpState* interpState);
198extern bool dvmInterpretStd(Thread* self, InterpState* interpState);
199#define INTERP_STD 0
200#define INTERP_DBG 1
201
202/*
203 * "mterp" interpreter.
204 */
205extern bool dvmMterpStd(Thread* self, InterpState* interpState);
206
207/*
208 * Get the "this" pointer from the current frame.
209 */
210Object* dvmGetThisPtr(const Method* method, const u4* fp);
211
212/*
213 * Verify that our tracked local references are valid.
214 */
215void dvmInterpCheckTrackedRefs(Thread* self, const Method* method,
216 int debugTrackedRefStart);
217
218/*
219 * Process switch statement.
220 */
221s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal);
222s4 dvmInterpHandleSparseSwitch(const u2* switchData, s4 testVal);
223
224/*
225 * Process fill-array-data.
226 */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700227bool dvmInterpHandleFillArrayData(ArrayObject* arrayObject,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800228 const u2* arrayData);
229
230/*
231 * Find an interface method.
232 */
233Method* dvmInterpFindInterfaceMethod(ClassObject* thisClass, u4 methodIdx,
234 const Method* method, DvmDex* methodClassDex);
235
236/*
237 * Determine if the debugger or profiler is currently active. Used when
238 * selecting which interpreter to start or switch to.
239 */
240static inline bool dvmDebuggerOrProfilerActive(void)
241{
242 return gDvm.debuggerActive
243#if defined(WITH_PROFILER)
244 || gDvm.activeProfilers != 0
245#endif
246 ;
247}
248
Ben Chengba4fc8b2009-06-01 13:00:29 -0700249#if defined(WITH_JIT)
250/*
251 * Determine if the jit, debugger or profiler is currently active. Used when
252 * selecting which interpreter to switch to.
253 */
Bill Buzbee5540f6e2010-02-08 10:41:32 -0800254static inline bool dvmJitDebuggerOrProfilerActive()
Ben Chengba4fc8b2009-06-01 13:00:29 -0700255{
Bill Buzbee51ae4422010-03-12 15:15:35 -0800256 return gDvmJit.pProfTable != NULL
Ben Chengba4fc8b2009-06-01 13:00:29 -0700257#if defined(WITH_PROFILER)
258 || gDvm.activeProfilers != 0
259#endif
260 ||gDvm.debuggerActive;
261}
262#endif
263
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800264#endif /*_DALVIK_INTERP_DEFS*/