blob: c794db2b33c28f8ef8f52dd67b9a6a807efa2027 [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;
131#if defined(WITH_DEBUGGER)
Andy McFaddenc95e0fb2010-04-29 14:13:01 -0700132 /* points at gDvm.debuggerActive, or NULL if debugger not enabled */
Andy McFaddena4365642009-08-07 11:37:44 -0700133 volatile u1* pDebuggerActive;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800134#endif
135#if defined(WITH_PROFILER)
Andy McFaddenc95e0fb2010-04-29 14:13:01 -0700136 /* points at gDvm.activeProfilers */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800137 volatile int* pActiveProfilers;
138#endif
139 /* ----------------------------------------------------------------------
140 */
141
142 /*
143 * Interpreter switching.
144 */
145 InterpEntry entryPoint; // what to do when we start
Ben Chengba4fc8b2009-06-01 13:00:29 -0700146 int nextMode; // INTERP_STD, INTERP_DBG
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800147
Ben Chengba4fc8b2009-06-01 13:00:29 -0700148#if defined(WITH_JIT)
149 /*
150 * Local copies of field from gDvm placed here for fast access
151 */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700152 unsigned char* pJitProfTable;
153 JitState jitState;
Ben Chengd5adae12010-03-26 17:45:28 -0700154 const void* jitResumeNPC; // Native PC of compiled code
155 const u2* jitResumeDPC; // Dalvik PC corresponding to NPC
Bill Buzbeed7269912009-11-10 14:31:32 -0800156 int jitThreshold;
Bill Buzbee964a7b02010-01-28 12:54:19 -0800157 /*
158 * ppJitProfTable holds the address of gDvmJit.pJitProfTable, which
159 * doubles as an on/off switch for the Jit. Because a change in
160 * the value of gDvmJit.pJitProfTable isn't reflected in the cached
161 * copy above (pJitProfTable), we need to periodically refresh it.
162 * ppJitProfTable is used for that purpose.
163 */
164 unsigned char** ppJitProfTable; // Used to refresh pJitProfTable
Ben Chengb88ec3c2010-05-17 12:50:33 -0700165 int icRechainCount; // Count down to next rechain request
Ben Chengba4fc8b2009-06-01 13:00:29 -0700166#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800167
168#if defined(WITH_PROFILER) || defined(WITH_DEBUGGER)
169 bool debugIsMethodEntry; // used for method entry event triggers
170#endif
171#if defined(WITH_TRACKREF_CHECKS)
172 int debugTrackedRefStart; // tracked refs from prior invocations
173#endif
174
Ben Chengba4fc8b2009-06-01 13:00:29 -0700175#if defined(WITH_JIT)
176 struct JitToInterpEntries jitToInterpEntries;
177
178 int currTraceRun;
179 int totalTraceLen; // Number of Dalvik insts in trace
Ben Cheng79d173c2009-09-29 16:12:51 -0700180 const u2* currTraceHead; // Start of the trace we're building
181 const u2* currRunHead; // Start of run we're building
Ben Chengba4fc8b2009-06-01 13:00:29 -0700182 int currRunLen; // Length of run in 16-bit words
Bill Buzbee48f18242009-06-19 16:02:27 -0700183 int lastThreshFilter;
Ben Cheng79d173c2009-09-29 16:12:51 -0700184 const u2* lastPC; // Stage the PC first for the threaded interpreter
Ben Cheng40094c12010-02-24 20:58:44 -0800185 intptr_t threshFilter[JIT_TRACE_THRESH_FILTER_SIZE];
Ben Chengba4fc8b2009-06-01 13:00:29 -0700186 JitTraceRun trace[MAX_JIT_RUN_LEN];
Bill Buzbee342806d2009-12-08 12:37:13 -0800187 double calleeSave[JIT_CALLEE_SAVE_DOUBLE_COUNT];
Ben Chengba4fc8b2009-06-01 13:00:29 -0700188#endif
189
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800190} InterpState;
191
192/*
193 * These are generated from InterpCore.h.
194 */
195extern bool dvmInterpretDbg(Thread* self, InterpState* interpState);
196extern bool dvmInterpretStd(Thread* self, InterpState* interpState);
197#define INTERP_STD 0
198#define INTERP_DBG 1
199
200/*
201 * "mterp" interpreter.
202 */
203extern bool dvmMterpStd(Thread* self, InterpState* interpState);
204
205/*
206 * Get the "this" pointer from the current frame.
207 */
208Object* dvmGetThisPtr(const Method* method, const u4* fp);
209
210/*
211 * Verify that our tracked local references are valid.
212 */
213void dvmInterpCheckTrackedRefs(Thread* self, const Method* method,
214 int debugTrackedRefStart);
215
216/*
217 * Process switch statement.
218 */
219s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal);
220s4 dvmInterpHandleSparseSwitch(const u2* switchData, s4 testVal);
221
222/*
223 * Process fill-array-data.
224 */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700225bool dvmInterpHandleFillArrayData(ArrayObject* arrayObject,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800226 const u2* arrayData);
227
228/*
229 * Find an interface method.
230 */
231Method* dvmInterpFindInterfaceMethod(ClassObject* thisClass, u4 methodIdx,
232 const Method* method, DvmDex* methodClassDex);
233
234/*
235 * Determine if the debugger or profiler is currently active. Used when
236 * selecting which interpreter to start or switch to.
237 */
238static inline bool dvmDebuggerOrProfilerActive(void)
239{
240 return gDvm.debuggerActive
241#if defined(WITH_PROFILER)
242 || gDvm.activeProfilers != 0
243#endif
244 ;
245}
246
Ben Chengba4fc8b2009-06-01 13:00:29 -0700247#if defined(WITH_JIT)
248/*
249 * Determine if the jit, debugger or profiler is currently active. Used when
250 * selecting which interpreter to switch to.
251 */
Bill Buzbee5540f6e2010-02-08 10:41:32 -0800252static inline bool dvmJitDebuggerOrProfilerActive()
Ben Chengba4fc8b2009-06-01 13:00:29 -0700253{
Bill Buzbee51ae4422010-03-12 15:15:35 -0800254 return gDvmJit.pProfTable != NULL
Ben Chengba4fc8b2009-06-01 13:00:29 -0700255#if defined(WITH_PROFILER)
256 || gDvm.activeProfilers != 0
257#endif
258 ||gDvm.debuggerActive;
259}
260#endif
261
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800262#endif /*_DALVIK_INTERP_DEFS*/