1 /* src/vm/jit/replace.h - on-stack replacement of methods
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #if !defined(ENABLE_REPLACEMENT)
36 /*** macros for the codegens (disabled version) ************************/
38 #define REPLACEMENT_POINTS_INIT(cd, jd)
39 #define REPLACEMENT_POINTS_RESET(cd, jd)
40 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)
41 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)
42 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)
43 #define REPLACEMENT_POINT_RETURN(cd, iptr)
44 #define REPLACEMENT_POINT_INVOKE(cd, iptr)
45 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr)
46 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
47 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
49 #else /* defined(ENABLE_REPLACEMENT) */
51 /* forward typedefs ***********************************************************/
53 typedef struct rplalloc rplalloc;
54 typedef struct rplpoint rplpoint;
55 typedef struct executionstate_t executionstate_t;
56 typedef struct sourcestate_t sourcestate_t;
57 typedef struct sourceframe_t sourceframe_t;
58 typedef struct replace_safestack_t replace_safestack_t;
59 typedef union replace_val_t replace_val_t;
64 #include "vm/jit/reg.h"
65 #include "vm/jit/stacktrace.h"
67 #include "vmcore/method.h"
70 /* alignment for the safe stack used during replacement */
72 #define REPLACE_STACK_ALIGNMENT 16
74 /* the size of the safe stack we use during replacement */
75 /* Must be a multiple of REPLACE_STACK_ALIGNMENT. */
77 #define REPLACE_SAFESTACK_SIZE 16384 /* bytes */
80 /*** structs *********************************************************/
82 #define RPLALLOC_STACK -1
83 #define RPLALLOC_PARAM -2
84 #define RPLALLOC_SYNC -3
86 /* `rplalloc` is a compact struct for register allocation info */
88 /* XXX optimize this for space efficiency */
90 s4 index; /* local index, -1 for stack slot */
91 s4 regoff; /* register index / stack slot offset */
92 unsigned int flags:4; /* OR of (INMEMORY,...) */
93 unsigned int type:4; /* TYPE_... constant */
97 #error value of INMEMORY is too big to fit in rplalloc.flags
101 /* XXX what to do about overlapping rplpoints? */
102 /* CAUTION: Do not change the numerical values. These are used as */
103 /* indices into replace_normalize_type_map. */
104 #define RPLPOINT_TYPE_STD BBTYPE_STD
105 #define RPLPOINT_TYPE_EXH BBTYPE_EXH
106 #define RPLPOINT_TYPE_SBR BBTYPE_SBR
107 #define RPLPOINT_TYPE_CALL 3
108 #define RPLPOINT_TYPE_INLINE 4
109 #define RPLPOINT_TYPE_RETURN 5
110 #define RPLPOINT_TYPE_BODY 6
112 #define RPLPOINT_FLAG_NOTRAP 0x01 /* rplpoint cannot be trapped */
113 #define RPLPOINT_FLAG_COUNTDOWN 0x02 /* count down hits */
114 #define RPLPOINT_FLAG_ACTIVE 0x08 /* trap is active */
118 #define RPLPOINT_CHECK(type) , RPLPOINT_TYPE_##type
119 #define RPLPOINT_CHECK_BB(bptr) , (bptr)->type
121 #define RPLPOINT_CHECK(type)
122 #define RPLPOINT_CHECK_BB(bptr)
126 /* An `rplpoint` represents a replacement point in a compiled method */
129 u1 *pc; /* machine code PC of this point */
130 methodinfo *method; /* source method this point is in */
131 rplpoint *parent; /* rplpoint of the inlined body */ /* XXX unify with code */
132 rplalloc *regalloc; /* pointer to register index table */
133 s4 id; /* id of the rplpoint within method */
134 s4 callsize; /* size of call code in bytes */
135 unsigned int regalloccount:20; /* number of local allocations */
136 unsigned int type:4; /* RPLPOINT_TYPE_... constant */
137 unsigned int flags:8; /* OR of RPLPOINT_... constants */
141 union replace_val_t {
155 /* An `executionsstate` represents the state of a thread as it reached */
156 /* an replacement point or is about to enter one. */
158 struct executionstate_t {
159 u1 *pc; /* program counter */
160 u1 *sp; /* stack pointer within method */
161 u1 *pv; /* procedure value. NULL means */
162 /* search the AVL tree */
164 ptrint intregs[INT_REG_CNT]; /* register values */
165 double fltregs[FLT_REG_CNT]; /* register values */
166 #if defined(HAS_ADDRESS_REGISTER_FILE)
167 ptrint adrregs[ADR_REG_CNT]; /* register values */
170 codeinfo *code; /* codeinfo corresponding to the pv */
174 struct sourceframe_t {
175 sourceframe_t *down; /* source frame down the call chain */
177 methodinfo *method; /* method this frame is in */
182 replace_val_t instance;
184 replace_val_t *javastack; /* values of stack vars */
185 u1 *javastacktype; /* types of stack vars */
186 s4 javastackdepth; /* number of stack vars */
188 replace_val_t *javalocals; /* values of javalocals */
189 u1 *javalocaltype; /* types of javalocals */
190 s4 javalocalcount; /* number of javalocals */
192 replace_val_t *syncslots;
193 s4 syncslotcount; /* XXX do we need more than one? */
196 rplpoint *fromrp; /* rplpoint used to read this frame */
197 codeinfo *fromcode; /* code this frame was using */
198 rplpoint *torp; /* rplpoint this frame was mapped to */
199 codeinfo *tocode; /* code this frame was mapped to */
201 /* info for native frames */
202 stackframeinfo *sfi; /* sfi for native frames, otherwise NULL */
203 s4 nativeframesize; /* size (bytes) of native frame */
205 ptrint nativesavint[INT_SAV_CNT]; /* XXX temporary */
206 double nativesavflt[FLT_REG_CNT]; /* XXX temporary */
207 #if defined(HAS_ADDRESS_REGISTER_FILE)
208 ptrint nativesavadr[ADR_SAV_CNT]; /* XXX temporary */
212 #define REPLACE_IS_NATIVE_FRAME(frame) ((frame)->sfi != NULL)
213 #define REPLACE_IS_JAVA_FRAME(frame) ((frame)->sfi == NULL)
216 struct sourcestate_t {
217 sourceframe_t *frames; /* list of source frames, from bottom up */
221 /* replace_safestack_t *********************************************************
223 This struct is used to allocate a safe stack area to be used during the
224 last phase of replacement. It also contains copies of all data needed
225 during this phase. (The data cannot be kept in normal variables, as
226 the C stack may be destroyed during replacement.)
228 CAUTION: Do not change the layout of this struct! The assembler code
229 depends on the order of fields. (`stack` must be first,
230 directly followed by `es`.)
232 *******************************************************************************/
234 struct replace_safestack_t {
235 u1 stack[REPLACE_SAFESTACK_SIZE];
238 u1 *mem; /* start of the allocated memory chunk */
243 /*** macros for the codegens *******************************************/
245 #define REPLACEMENT_POINTS_INIT(cd, jd) \
246 if (!replace_create_replacement_points(jd)) \
248 (cd)->replacementpoint = (jd)->code->rplpoints;
250 #define REPLACEMENT_POINTS_RESET(cd, jd) \
251 (cd)->replacementpoint = (jd)->code->rplpoints;
253 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr) \
254 if ((bptr)->bitflags & BBFLAG_REPLACEMENT) \
255 codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
257 #define REPLACEMENT_POINT_INLINE_START(cd, iptr) \
258 codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
260 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr) \
261 codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
263 #define REPLACEMENT_POINT_RETURN(cd, iptr) \
264 codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
266 #define REPLACEMENT_POINT_INVOKE(cd, iptr) \
267 codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
269 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr) \
270 if (iptr->opc != ICMD_BUILTIN) \
271 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
272 - (ptrint) cd->replacementpoint[-1].pc;
274 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr) \
275 codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
277 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr) \
278 if (iptr->opc == ICMD_BUILTIN) \
279 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
280 - (ptrint) cd->replacementpoint[-1].pc;
283 /*** prototypes ********************************************************/
285 bool replace_create_replacement_points(jitdata *jd);
286 void replace_free_replacement_points(codeinfo *code);
288 void replace_activate_replacement_points(codeinfo *code, bool mappable);
289 void replace_deactivate_replacement_points(codeinfo *code);
291 bool replace_me_wrapper(u1 *pc);
293 void replace_me(rplpoint *rp,executionstate_t *es);
296 void replace_show_replacement_points(codeinfo *code);
297 void replace_replacement_point_println(rplpoint *rp, int depth);
298 void replace_executionstate_println(executionstate_t *es);
299 void replace_sourcestate_println(sourcestate_t *ss);
300 void replace_sourcestate_println_short(sourcestate_t *ss);
301 void replace_source_frame_println(sourceframe_t *frame);
304 /* machine dependent functions (code in ARCH_DIR/md.c) */
306 #if defined(ENABLE_JIT)
307 void md_patch_replacement_point(codeinfo *code, s4 index, rplpoint *rp,
311 #endif /* defined(ENABLE_REPLACEMENT) */
313 #endif /* _REPLACE_H */
317 * These are local overrides for various environment variables in Emacs.
318 * Please do not remove this and leave it at the end of the file, where
319 * Emacs will automagically detect them.
320 * ---------------------------------------------------------------------
323 * indent-tabs-mode: t
327 * vim:noexpandtab:sw=4:ts=4: