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 union replace_val_t replace_val_t;
63 #include "vm/jit/reg.h"
64 #include "vm/jit/stacktrace.h"
66 #include "vmcore/method.h"
69 /*** structs *********************************************************/
71 #define RPLALLOC_STACK -1
72 #define RPLALLOC_PARAM -2
73 #define RPLALLOC_SYNC -3
75 /* `rplalloc` is a compact struct for register allocation info */
77 /* XXX optimize this for space efficiency */
79 s4 index; /* local index, -1 for stack slot */
80 s4 regoff; /* register index / stack slot offset */
81 unsigned int flags:4; /* OR of (INMEMORY,...) */
82 unsigned int type:4; /* TYPE_... constant */
86 #error value of INMEMORY is too big to fit in rplalloc.flags
90 /* XXX what to do about overlapping rplpoints? */
91 /* CAUTION: Do not change the numerical values. These are used as */
92 /* indices into replace_normalize_type_map. */
93 #define RPLPOINT_TYPE_STD BBTYPE_STD
94 #define RPLPOINT_TYPE_EXH BBTYPE_EXH
95 #define RPLPOINT_TYPE_SBR BBTYPE_SBR
96 #define RPLPOINT_TYPE_CALL 3
97 #define RPLPOINT_TYPE_INLINE 4
98 #define RPLPOINT_TYPE_RETURN 5
99 #define RPLPOINT_TYPE_BODY 6
101 #define RPLPOINT_FLAG_NOTRAP 0x01 /* rplpoint cannot be trapped */
102 #define RPLPOINT_FLAG_COUNTDOWN 0x02 /* count down hits */
103 #define RPLPOINT_FLAG_ACTIVE 0x08 /* trap is active */
107 #define RPLPOINT_CHECK(type) , RPLPOINT_TYPE_##type
108 #define RPLPOINT_CHECK_BB(bptr) , (bptr)->type
110 #define RPLPOINT_CHECK(type)
111 #define RPLPOINT_CHECK_BB(bptr)
115 /* An `rplpoint` represents a replacement point in a compiled method */
118 u1 *pc; /* machine code PC of this point */
119 methodinfo *method; /* source method this point is in */
120 rplpoint *parent; /* rplpoint of the inlined body */ /* XXX unify with code */
121 rplalloc *regalloc; /* pointer to register index table */
122 s4 id; /* id of the rplpoint within method */
123 s4 callsize; /* size of call code in bytes */
124 unsigned int regalloccount:20; /* number of local allocations */
125 unsigned int type:4; /* RPLPOINT_TYPE_... constant */
126 unsigned int flags:8; /* OR of RPLPOINT_... constants */
130 union replace_val_t {
144 /* An `executionsstate` represents the state of a thread as it reached */
145 /* an replacement point or is about to enter one. */
147 struct executionstate_t {
148 u1 *pc; /* program counter */
149 u1 *sp; /* stack pointer within method */
150 u1 *pv; /* procedure value. NULL means */
151 /* search the AVL tree */
153 ptrint intregs[INT_REG_CNT]; /* register values */
154 double fltregs[FLT_REG_CNT]; /* register values */
155 #if defined(HAS_ADDRESS_REGISTER_FILE)
156 ptrint adrregs[ADR_REG_CNT]; /* register values */
159 codeinfo *code; /* codeinfo corresponding to the pv */
163 struct sourceframe_t {
164 sourceframe_t *down; /* source frame down the call chain */
166 methodinfo *method; /* method this frame is in */
171 replace_val_t instance;
173 replace_val_t *javastack; /* values of stack vars */
174 u1 *javastacktype; /* types of stack vars */
175 s4 javastackdepth; /* number of stack vars */
177 replace_val_t *javalocals; /* values of javalocals */
178 u1 *javalocaltype; /* types of javalocals */
179 s4 javalocalcount; /* number of javalocals */
181 replace_val_t *syncslots;
182 s4 syncslotcount; /* XXX do we need more than one? */
185 rplpoint *fromrp; /* rplpoint used to read this frame */
186 codeinfo *fromcode; /* code this frame was using */
187 rplpoint *torp; /* rplpoint this frame was mapped to */
188 codeinfo *tocode; /* code this frame was mapped to */
190 /* info for native frames */
191 stackframeinfo *sfi; /* sfi for native frames, otherwise NULL */
192 s4 nativeframesize; /* size (bytes) of native frame */
194 ptrint nativesavint[INT_SAV_CNT]; /* XXX temporary */
195 double nativesavflt[FLT_REG_CNT]; /* XXX temporary */
196 #if defined(HAS_ADDRESS_REGISTER_FILE)
197 ptrint nativesavadr[ADR_SAV_CNT]; /* XXX temporary */
201 #define REPLACE_IS_NATIVE_FRAME(frame) ((frame)->sfi != NULL)
202 #define REPLACE_IS_JAVA_FRAME(frame) ((frame)->sfi == NULL)
205 struct sourcestate_t {
206 sourceframe_t *frames; /* list of source frames, from bottom up */
210 /*** macros for the codegens *******************************************/
212 #define REPLACEMENT_POINTS_INIT(cd, jd) \
213 if (!replace_create_replacement_points(jd)) \
215 (cd)->replacementpoint = (jd)->code->rplpoints;
217 #define REPLACEMENT_POINTS_RESET(cd, jd) \
218 (cd)->replacementpoint = (jd)->code->rplpoints;
220 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr) \
221 if ((bptr)->bitflags & BBFLAG_REPLACEMENT) \
222 codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
224 #define REPLACEMENT_POINT_INLINE_START(cd, iptr) \
225 codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
227 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr) \
228 codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
230 #define REPLACEMENT_POINT_RETURN(cd, iptr) \
231 codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
233 #define REPLACEMENT_POINT_INVOKE(cd, iptr) \
234 codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
236 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr) \
237 if (iptr->opc != ICMD_BUILTIN) \
238 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
239 - (ptrint) cd->replacementpoint[-1].pc;
242 /*** macros for the codegens (for GC) **********************************/
244 #if defined(ENABLE_GC_CACAO)
246 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr) \
247 codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
249 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr) \
250 if (iptr->opc == ICMD_BUILTIN) \
251 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
252 - (ptrint) cd->replacementpoint[-1].pc;
254 #else /* defined(ENABLE_GC_CACAO) */
256 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
257 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
259 #endif /* defined(ENABLE_GC_CACAO) */
262 /*** prototypes ********************************************************/
264 bool replace_create_replacement_points(jitdata *jd);
265 void replace_free_replacement_points(codeinfo *code);
267 void replace_activate_replacement_points(codeinfo *code, bool mappable);
268 void replace_deactivate_replacement_points(codeinfo *code);
270 bool replace_me_wrapper(u1 *pc, void *context);
273 void replace_show_replacement_points(codeinfo *code);
274 void replace_replacement_point_println(rplpoint *rp, int depth);
275 void replace_executionstate_println(executionstate_t *es);
276 void replace_sourcestate_println(sourcestate_t *ss);
277 void replace_sourcestate_println_short(sourcestate_t *ss);
278 void replace_source_frame_println(sourceframe_t *frame);
281 /* machine dependent functions (code in ARCH_DIR/md.c) */
283 #if defined(ENABLE_JIT)
284 void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert);
287 /* machine and OS dependent functions (code in ARCH_DIR/OS_DIR/md-os.c) */
289 void md_replace_executionstate_read(executionstate_t *es, void *context);
290 void md_replace_executionstate_write(executionstate_t *es, void *context);
292 #endif /* defined(ENABLE_REPLACEMENT) */
294 #endif /* _REPLACE_H */
298 * These are local overrides for various environment variables in Emacs.
299 * Please do not remove this and leave it at the end of the file, where
300 * Emacs will automagically detect them.
301 * ---------------------------------------------------------------------
304 * indent-tabs-mode: t
308 * vim:noexpandtab:sw=4:ts=4: