1 /* vm/jit/replace.h - on-stack replacement of methods
3 Copyright (C) 1996-2005, 2006 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
25 Contact: cacao@cacaojvm.org
27 Authors: Edwin Steiner
42 #if defined(ENABLE_REPLACEMENT)
44 /* forward typedefs ***********************************************************/
46 typedef struct rplalloc rplalloc;
47 typedef struct rplpoint rplpoint;
48 typedef struct executionstate_t executionstate_t;
49 typedef struct sourcestate_t sourcestate_t;
50 typedef struct sourceframe_t sourceframe_t;
51 typedef struct replace_safestack_t replace_safestack_t;
52 typedef union replace_val_t replace_val_t;
57 #include "vm/jit/reg.h"
58 #include "vm/jit/stacktrace.h"
60 #include "vmcore/method.h"
63 /* alignment for the safe stack used during replacement */
65 #define REPLACE_STACK_ALIGNMENT 16
67 /* the size of the safe stack we use during replacement */
68 /* Must be a multiple of REPLACE_STACK_ALIGNMENT. */
70 #define REPLACE_SAFESTACK_SIZE 16384 /* bytes */
73 /*** structs *********************************************************/
75 #define RPLALLOC_STACK -1
76 #define RPLALLOC_PARAM -2
77 #define RPLALLOC_SYNC -3
79 /* `rplalloc` is a compact struct for register allocation info */
81 /* XXX optimize this for space efficiency */
83 s4 index; /* local index, -1 for stack slot */
84 s4 regoff; /* register index / stack slot offset */
85 unsigned int flags:4; /* OR of (INMEMORY,...) */
86 unsigned int type:4; /* TYPE_... constant */
90 #error value of INMEMORY is too big to fit in rplalloc.flags
94 /* XXX what to do about overlapping rplpoints? */
95 /* CAUTION: Do not change the numerical values. These are used as */
96 /* indices into replace_normalize_type_map. */
97 #define RPLPOINT_TYPE_STD BBTYPE_STD
98 #define RPLPOINT_TYPE_EXH BBTYPE_EXH
99 #define RPLPOINT_TYPE_SBR BBTYPE_SBR
100 #define RPLPOINT_TYPE_CALL 3
101 #define RPLPOINT_TYPE_INLINE 4
102 #define RPLPOINT_TYPE_RETURN 5
103 #define RPLPOINT_TYPE_BODY 6
105 #define RPLPOINT_FLAG_NOTRAP 0x01 /* rplpoint cannot be trapped */
106 #define RPLPOINT_FLAG_COUNTDOWN 0x02 /* count down hits */
107 #define RPLPOINT_FLAG_ACTIVE 0x08 /* trap is active */
111 #define RPLPOINT_CHECK(type) , RPLPOINT_TYPE_##type
112 #define RPLPOINT_CHECK_BB(bptr) , (bptr)->type
114 #define RPLPOINT_CHECK(type)
115 #define RPLPOINT_CHECK_BB(bptr)
119 /* An `rplpoint` represents a replacement point in a compiled method */
122 u1 *pc; /* machine code PC of this point */
123 methodinfo *method; /* source method this point is in */
124 rplpoint *parent; /* rplpoint of the inlined body */ /* XXX unify with code */
125 rplalloc *regalloc; /* pointer to register index table */
126 s4 id; /* id of the rplpoint within method */
127 s4 callsize; /* size of call code in bytes */
128 unsigned int regalloccount:20; /* number of local allocations */
129 unsigned int type:4; /* RPLPOINT_TYPE_... constant */
130 unsigned int flags:8; /* OR of RPLPOINT_... constants */
134 union replace_val_t {
144 java_objectheader *a;
148 /* An `executionsstate` represents the state of a thread as it reached */
149 /* an replacement point or is about to enter one. */
151 struct executionstate_t {
152 u1 *pc; /* program counter */
153 u1 *sp; /* stack pointer within method */
154 u1 *pv; /* procedure value. NULL means */
155 /* search the AVL tree */
157 ptrint intregs[INT_REG_CNT]; /* register values */
158 double fltregs[FLT_REG_CNT]; /* register values */
160 codeinfo *code; /* codeinfo corresponding to the pv */
164 struct sourceframe_t {
165 sourceframe_t *down; /* source frame down the call chain */
167 methodinfo *method; /* method this frame is in */
172 replace_val_t instance;
174 replace_val_t *javastack; /* values of stack vars */
175 u1 *javastacktype; /* types of stack vars */
176 s4 javastackdepth; /* number of stack vars */
178 replace_val_t *javalocals; /* values of javalocals */
179 u1 *javalocaltype; /* types of javalocals */
180 s4 javalocalcount; /* number of javalocals */
182 replace_val_t *syncslots;
183 s4 syncslotcount; /* XXX do we need more than one? */
186 rplpoint *fromrp; /* rplpoint used to read this frame */
187 codeinfo *fromcode; /* code this frame was using */
188 rplpoint *torp; /* rplpoint this frame was mapped to */
189 codeinfo *tocode; /* code this frame was mapped to */
191 /* info for native frames */
192 stackframeinfo *sfi; /* sfi for native frames, otherwise NULL */
193 s4 nativeframesize; /* size (bytes) of native frame */
195 ptrint nativesavint[INT_SAV_CNT]; /* XXX temporary */
196 double nativesavflt[FLT_REG_CNT]; /* XXX temporary */
199 #define REPLACE_IS_NATIVE_FRAME(frame) ((frame)->sfi != NULL)
200 #define REPLACE_IS_JAVA_FRAME(frame) ((frame)->sfi == NULL)
203 struct sourcestate_t {
204 sourceframe_t *frames; /* list of source frames, from bottom up */
208 /* replace_safestack_t *********************************************************
210 This struct is used to allocate a safe stack area to be used during the
211 last phase of replacement. It also contains copies of all data needed
212 during this phase. (The data cannot be kept in normal variables, as
213 the C stack may be destroyed during replacement.)
215 CAUTION: Do not change the layout of this struct! The assembler code
216 depends on the order of fields. (`stack` must be first,
217 directly followed by `es`.)
219 *******************************************************************************/
221 struct replace_safestack_t {
222 u1 stack[REPLACE_SAFESTACK_SIZE];
225 u1 *mem; /* start of the allocated memory chunk */
230 /*** macros for the codegens *******************************************/
232 #define REPLACEMENT_POINTS_INIT(cd, jd) \
233 if (!replace_create_replacement_points(jd)) \
235 (cd)->replacementpoint = (jd)->code->rplpoints;
237 #define REPLACEMENT_POINTS_RESET(cd, jd) \
238 (cd)->replacementpoint = (jd)->code->rplpoints;
240 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr) \
241 if ((bptr)->bitflags & BBFLAG_REPLACEMENT) \
242 codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
244 #define REPLACEMENT_POINT_INLINE_START(cd, iptr) \
245 codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
247 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr) \
248 codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
250 #define REPLACEMENT_POINT_RETURN(cd, iptr) \
251 codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
253 #define REPLACEMENT_POINT_INVOKE(cd, iptr) \
254 codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
256 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr) \
257 if (iptr->opc != ICMD_BUILTIN) \
258 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
259 - (ptrint) cd->replacementpoint[-1].pc;
261 #define REPLACEMENT_EMIT_STUBS(jd) \
262 emit_replacement_stubs(jd);
264 /*** prototypes ********************************************************/
266 bool replace_create_replacement_points(jitdata *jd);
267 void replace_free_replacement_points(codeinfo *code);
269 void replace_activate_replacement_points(codeinfo *code, bool mappable);
270 void replace_deactivate_replacement_points(codeinfo *code);
272 void replace_me(rplpoint *rp,executionstate_t *es);
275 void replace_show_replacement_points(codeinfo *code);
276 void replace_replacement_point_println(rplpoint *rp, int depth);
277 void replace_executionstate_println(executionstate_t *es);
278 void replace_sourcestate_println(sourcestate_t *ss);
279 void replace_sourcestate_println_short(sourcestate_t *ss);
280 void replace_source_frame_println(sourceframe_t *frame);
283 /* machine dependent functions (code in ARCH_DIR/md.c) */
285 #if defined(ENABLE_JIT)
286 void md_patch_replacement_point(codeinfo *code, s4 index, rplpoint *rp,
290 #else /* !defined(ENABLE_REPLACEMENT) */
292 /*** macros for the codegens (disabled version) ************************/
294 #define REPLACEMENT_POINTS_INIT(cd, jd)
295 #define REPLACEMENT_POINTS_RESET(cd, jd)
296 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)
297 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)
298 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)
299 #define REPLACEMENT_POINT_RETURN(cd, iptr)
300 #define REPLACEMENT_POINT_INVOKE(cd, iptr)
301 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr)
302 #define REPLACEMENT_EMIT_STUBS(jd)
304 #endif /* defined(ENABLE_REPLACEMENT) */
309 * These are local overrides for various environment variables in Emacs.
310 * Please do not remove this and leave it at the end of the file, where
311 * Emacs will automagically detect them.
312 * ---------------------------------------------------------------------
315 * indent-tabs-mode: t
319 * vim:noexpandtab:sw=4:ts=4: