1 /* src/vm/jit/replace.hpp - on-stack replacement of methods
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 #if !defined(ENABLE_REPLACEMENT)
34 /*** macros for the codegens (disabled version) ************************/
36 #define REPLACEMENT_POINTS_INIT(cd, jd)
37 #define REPLACEMENT_POINTS_RESET(cd, jd)
38 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)
39 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)
40 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)
41 #define REPLACEMENT_POINT_RETURN(cd, iptr)
42 #define REPLACEMENT_POINT_INVOKE(cd, iptr)
43 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr)
44 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
45 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
47 #else /* defined(ENABLE_REPLACEMENT) */
49 /* forward typedefs ***********************************************************/
51 typedef struct rplalloc rplalloc;
52 typedef struct rplpoint rplpoint;
53 typedef struct sourcestate_t sourcestate_t;
54 typedef struct sourceframe_t sourceframe_t;
55 typedef union replace_val_t replace_val_t;
60 #include "vm/method.hpp"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/stacktrace.hpp"
66 /*** structs *********************************************************/
68 #define RPLALLOC_STACK -1
69 #define RPLALLOC_PARAM -2
70 #define RPLALLOC_SYNC -3
72 /* `rplalloc` is a compact struct for register allocation info */
74 /* XXX optimize this for space efficiency */
76 s4 index; /* local index, -1 for stack slot */
77 s4 regoff; /* register index / stack slot offset */
78 unsigned int flags:4; /* OR of (INMEMORY,...) */
79 unsigned int type:4; /* TYPE_... constant */
83 #error value of INMEMORY is too big to fit in rplalloc.flags
87 /* XXX what to do about overlapping rplpoints? */
88 /* CAUTION: Do not change the numerical values. These are used as */
89 /* indices into replace_normalize_type_map. */
90 #define RPLPOINT_TYPE_STD BBTYPE_STD
91 #define RPLPOINT_TYPE_EXH BBTYPE_EXH
92 #define RPLPOINT_TYPE_SBR BBTYPE_SBR
93 #define RPLPOINT_TYPE_CALL 3
94 #define RPLPOINT_TYPE_INLINE 4
95 #define RPLPOINT_TYPE_RETURN 5
96 #define RPLPOINT_TYPE_BODY 6
98 #define RPLPOINT_FLAG_NOTRAP 0x01 /* rplpoint cannot be trapped */
99 #define RPLPOINT_FLAG_COUNTDOWN 0x02 /* count down hits */
100 #define RPLPOINT_FLAG_ACTIVE 0x08 /* trap is active */
104 #define RPLPOINT_CHECK(type) , RPLPOINT_TYPE_##type
105 #define RPLPOINT_CHECK_BB(bptr) , (bptr)->type
107 #define RPLPOINT_CHECK(type)
108 #define RPLPOINT_CHECK_BB(bptr)
112 /* An `rplpoint` represents a replacement point in a compiled method */
115 u1 *pc; /* machine code PC of this point */
116 methodinfo *method; /* source method this point is in */
117 rplpoint *parent; /* rplpoint of the inlined body */ /* XXX unify with code */
118 rplalloc *regalloc; /* pointer to register index table */
119 s4 id; /* id of the rplpoint within method */
120 s4 callsize; /* size of call code in bytes */
121 unsigned int regalloccount:20; /* number of local allocations */
122 unsigned int type:4; /* RPLPOINT_TYPE_... constant */
123 unsigned int flags:8; /* OR of RPLPOINT_... constants */
127 union replace_val_t {
141 struct sourceframe_t {
142 sourceframe_t *down; /* source frame down the call chain */
144 methodinfo *method; /* method this frame is in */
149 replace_val_t instance;
151 replace_val_t *javastack; /* values of stack vars */
152 u1 *javastacktype; /* types of stack vars */
153 s4 javastackdepth; /* number of stack vars */
155 replace_val_t *javalocals; /* values of javalocals */
156 u1 *javalocaltype; /* types of javalocals */
157 s4 javalocalcount; /* number of javalocals */
159 replace_val_t *syncslots;
160 s4 syncslotcount; /* XXX do we need more than one? */
163 rplpoint *fromrp; /* rplpoint used to read this frame */
164 codeinfo *fromcode; /* code this frame was using */
165 rplpoint *torp; /* rplpoint this frame was mapped to */
166 codeinfo *tocode; /* code this frame was mapped to */
168 /* info for native frames */
169 stackframeinfo_t *sfi; /* sfi for native frames, otherwise NULL */
170 s4 nativeframesize; /* size (bytes) of native frame */
172 ptrint nativesavint[INT_SAV_CNT]; /* XXX temporary */
173 double nativesavflt[FLT_REG_CNT]; /* XXX temporary */
174 #if defined(HAS_ADDRESS_REGISTER_FILE)
175 ptrint nativesavadr[ADR_SAV_CNT]; /* XXX temporary */
179 #define REPLACE_IS_NATIVE_FRAME(frame) ((frame)->sfi != NULL)
180 #define REPLACE_IS_JAVA_FRAME(frame) ((frame)->sfi == NULL)
183 struct sourcestate_t {
184 sourceframe_t *frames; /* list of source frames, from bottom up */
188 /*** macros for the codegens *******************************************/
190 #define REPLACEMENT_POINTS_INIT(cd, jd) \
191 if (!replace_create_replacement_points(jd)) \
193 (cd)->replacementpoint = (jd)->code->rplpoints;
195 #define REPLACEMENT_POINTS_RESET(cd, jd) \
196 (cd)->replacementpoint = (jd)->code->rplpoints;
198 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr) \
199 if ((bptr)->bitflags & BBFLAG_REPLACEMENT) \
200 codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
202 #define REPLACEMENT_POINT_INLINE_START(cd, iptr) \
203 codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
205 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr) \
206 codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
208 #define REPLACEMENT_POINT_RETURN(cd, iptr) \
209 codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
211 #define REPLACEMENT_POINT_INVOKE(cd, iptr) \
212 codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
214 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr) \
215 if (iptr->opc != ICMD_BUILTIN) \
216 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
217 - (ptrint) cd->replacementpoint[-1].pc;
220 /*** macros for the codegens (for GC) **********************************/
222 #if defined(ENABLE_GC_CACAO)
224 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr) \
225 codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
227 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr) \
228 if (iptr->opc == ICMD_BUILTIN) \
229 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
230 - (ptrint) cd->replacementpoint[-1].pc;
232 #else // ENABLE_GC_CACAO
234 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
235 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
237 #endif // ENABLE_GC_CACAO
240 /*** prototypes ********************************************************/
246 bool replace_create_replacement_points(jitdata *jd);
247 void replace_free_replacement_points(codeinfo *code);
249 void replace_activate_replacement_points(codeinfo *code, bool mappable);
250 void replace_deactivate_replacement_points(codeinfo *code);
252 bool replace_me_wrapper(u1 *pc, void *context);
255 void replace_show_replacement_points(codeinfo *code);
256 void replace_replacement_point_println(rplpoint *rp, int depth);
257 void replace_sourcestate_println(sourcestate_t *ss);
258 void replace_sourcestate_println_short(sourcestate_t *ss);
259 void replace_source_frame_println(sourceframe_t *frame);
262 /* machine dependent functions (code in ARCH_DIR/md.c) */
264 #if defined(ENABLE_JIT)
265 void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert);
272 #endif // ENABLE_REPLACEMENT
274 #endif // _REPLACE_HPP
278 * These are local overrides for various environment variables in Emacs.
279 * Please do not remove this and leave it at the end of the file, where
280 * Emacs will automagically detect them.
281 * ---------------------------------------------------------------------
284 * indent-tabs-mode: t
288 * vim:noexpandtab:sw=4:ts=4: