* Removed all Id tags.
[cacao.git] / src / vm / jit / replace.h
1 /* src/vm/jit/replace.h - on-stack replacement of methods
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25 */
26
27
28 #ifndef _REPLACE_H
29 #define _REPLACE_H
30
31 #include "config.h"
32 #include "vm/types.h"
33
34 #if !defined(ENABLE_REPLACEMENT)
35
36 /*** macros for the codegens (disabled version) ************************/
37
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
47 #else /* defined(ENABLE_REPLACEMENT) */
48
49 /* forward typedefs ***********************************************************/
50
51 typedef struct rplalloc rplalloc;
52 typedef struct rplpoint rplpoint;
53 typedef struct executionstate_t executionstate_t;
54 typedef struct sourcestate_t sourcestate_t;
55 typedef struct sourceframe_t sourceframe_t;
56 typedef struct replace_safestack_t replace_safestack_t;
57 typedef union  replace_val_t replace_val_t;
58
59 #include "arch.h"
60 #include "md-abi.h"
61
62 #include "vm/jit/reg.h"
63 #include "vm/jit/stacktrace.h"
64
65 #include "vmcore/method.h"
66
67
68 /* alignment for the safe stack used during replacement */
69
70 #define REPLACE_STACK_ALIGNMENT  16
71
72 /* the size of the safe stack we use during replacement */
73 /* Must be a multiple of REPLACE_STACK_ALIGNMENT.       */
74
75 #define REPLACE_SAFESTACK_SIZE  16384  /* bytes */
76
77
78 /*** structs *********************************************************/
79
80 #define RPLALLOC_STACK  -1
81 #define RPLALLOC_PARAM  -2
82 #define RPLALLOC_SYNC   -3
83
84 /* `rplalloc` is a compact struct for register allocation info        */
85
86 /* XXX optimize this for space efficiency */
87 struct rplalloc {
88         s4           index;     /* local index, -1 for stack slot         */
89         s4           regoff;    /* register index / stack slot offset     */
90         unsigned int flags:4;   /* OR of (INMEMORY,...)                   */
91         unsigned int type:4;    /* TYPE_... constant                      */
92 };
93
94 #if INMEMORY > 0x08
95 #error value of INMEMORY is too big to fit in rplalloc.flags
96 #endif
97
98
99 /* XXX what to do about overlapping rplpoints? */
100 /* CAUTION: Do not change the numerical values. These are used as     */
101 /*          indices into replace_normalize_type_map.                  */
102 #define RPLPOINT_TYPE_STD     BBTYPE_STD
103 #define RPLPOINT_TYPE_EXH     BBTYPE_EXH
104 #define RPLPOINT_TYPE_SBR     BBTYPE_SBR
105 #define RPLPOINT_TYPE_CALL    3
106 #define RPLPOINT_TYPE_INLINE  4
107 #define RPLPOINT_TYPE_RETURN  5
108 #define RPLPOINT_TYPE_BODY    6
109
110 #define RPLPOINT_FLAG_NOTRAP     0x01  /* rplpoint cannot be trapped */
111 #define RPLPOINT_FLAG_COUNTDOWN  0x02  /* count down hits            */
112 #define RPLPOINT_FLAG_ACTIVE     0x08  /* trap is active             */
113
114
115 #if !defined(NDEBUG)
116 #define RPLPOINT_CHECK(type)     , RPLPOINT_TYPE_##type
117 #define RPLPOINT_CHECK_BB(bptr)  , (bptr)->type
118 #else
119 #define RPLPOINT_CHECK(type)
120 #define RPLPOINT_CHECK_BB(bptr)
121 #endif
122
123
124 /* An `rplpoint` represents a replacement point in a compiled method  */
125
126 struct rplpoint {
127         u1          *pc;           /* machine code PC of this point       */
128         methodinfo  *method;       /* source method this point is in      */
129         rplpoint    *parent;       /* rplpoint of the inlined body        */ /* XXX unify with code */
130         rplalloc    *regalloc;     /* pointer to register index table     */
131         s4           id;           /* id of the rplpoint within method    */
132         s4           callsize;     /* size of call code in bytes          */
133         unsigned int regalloccount:20; /* number of local allocations     */
134         unsigned int type:4;           /* RPLPOINT_TYPE_... constant      */
135         unsigned int flags:8;          /* OR of RPLPOINT_... constants    */
136 };
137
138
139 union replace_val_t {
140         s4             i;
141         s8             l;
142         ptrint         p;
143         struct {
144                 u4 lo;
145                 u4 hi;
146         }              words;
147         float          f;
148         double         d;
149         java_object_t *a;
150 };
151
152
153 /* An `executionsstate` represents the state of a thread as it reached */
154 /* an replacement point or is about to enter one.                      */
155
156 struct executionstate_t {
157         u1           *pc;                               /* program counter */
158         u1           *sp;                   /* stack pointer within method */
159         u1           *pv;                   /* procedure value. NULL means */
160                                             /* search the AVL tree         */
161
162         ptrint        intregs[INT_REG_CNT];             /* register values */
163         double        fltregs[FLT_REG_CNT];             /* register values */
164 #if defined(HAS_ADDRESS_REGISTER_FILE)
165         ptrint        adrregs[ADR_REG_CNT];             /* register values */
166 #endif
167
168         codeinfo     *code;            /* codeinfo corresponding to the pv */
169 };
170
171
172 struct sourceframe_t {
173         sourceframe_t *down;           /* source frame down the call chain */
174
175         methodinfo    *method;                  /* method this frame is in */
176         s4             id;
177         s4             type;
178
179         /* values */
180         replace_val_t  instance;
181
182         replace_val_t *javastack;                  /* values of stack vars */
183         u1            *javastacktype;              /*  types of stack vars */
184         s4             javastackdepth;             /* number of stack vars */
185
186         replace_val_t *javalocals;                 /* values of javalocals */
187         u1            *javalocaltype;              /*  types of javalocals */
188         s4             javalocalcount;             /* number of javalocals */
189
190         replace_val_t *syncslots;
191         s4             syncslotcount; /* XXX do we need more than one? */
192
193         /* mapping info */
194         rplpoint      *fromrp;         /* rplpoint used to read this frame */
195         codeinfo      *fromcode;              /* code this frame was using */
196         rplpoint      *torp;          /* rplpoint this frame was mapped to */
197         codeinfo      *tocode;            /* code this frame was mapped to */
198
199         /* info for native frames */
200         stackframeinfo *sfi;      /* sfi for native frames, otherwise NULL */
201         s4             nativeframesize;    /* size (bytes) of native frame */
202         u1            *nativepc;
203         ptrint         nativesavint[INT_SAV_CNT]; /* XXX temporary */
204         double         nativesavflt[FLT_REG_CNT]; /* XXX temporary */
205 #if defined(HAS_ADDRESS_REGISTER_FILE)
206         ptrint         nativesavadr[ADR_SAV_CNT]; /* XXX temporary */
207 #endif
208 };
209
210 #define REPLACE_IS_NATIVE_FRAME(frame)  ((frame)->sfi != NULL)
211 #define REPLACE_IS_JAVA_FRAME(frame)    ((frame)->sfi == NULL)
212
213
214 struct sourcestate_t {
215         sourceframe_t *frames;    /* list of source frames, from bottom up */
216 };
217
218
219 /* replace_safestack_t *********************************************************
220
221    This struct is used to allocate a safe stack area to be used during the
222    last phase of replacement. It also contains copies of all data needed
223    during this phase. (The data cannot be kept in normal variables, as
224    the C stack may be destroyed during replacement.)
225
226    CAUTION: Do not change the layout of this struct! The assembler code
227             depends on the order of fields. (`stack` must be first,
228                         directly followed by `es`.)
229
230 *******************************************************************************/
231
232 struct replace_safestack_t {
233         u1                stack[REPLACE_SAFESTACK_SIZE];
234         executionstate_t  es;
235         sourcestate_t    *ss;
236         u1               *mem;             /* start of the allocated memory chunk */
237         s4                dumpsize;
238 };
239
240
241 /*** macros for the codegens *******************************************/
242
243 #define REPLACEMENT_POINTS_INIT(cd, jd)                              \
244     if (!replace_create_replacement_points(jd))                      \
245         return false;                                                \
246     (cd)->replacementpoint = (jd)->code->rplpoints;
247
248 #define REPLACEMENT_POINTS_RESET(cd, jd)                             \
249     (cd)->replacementpoint = (jd)->code->rplpoints;
250
251 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)                      \
252     if ((bptr)->bitflags & BBFLAG_REPLACEMENT)                       \
253         codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
254
255 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)                     \
256     codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
257
258 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)                      \
259     codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
260
261 #define REPLACEMENT_POINT_RETURN(cd, iptr)                           \
262     codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
263
264 #define REPLACEMENT_POINT_INVOKE(cd, iptr)                           \
265     codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
266
267 #define REPLACEMENT_POINT_INVOKE_RETURN(cd,  iptr)                   \
268     if (iptr->opc != ICMD_BUILTIN)                                   \
269         cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
270                     - (ptrint) cd->replacementpoint[-1].pc;
271
272 /*** prototypes ********************************************************/
273
274 bool replace_create_replacement_points(jitdata *jd);
275 void replace_free_replacement_points(codeinfo *code);
276
277 void replace_activate_replacement_points(codeinfo *code, bool mappable);
278 void replace_deactivate_replacement_points(codeinfo *code);
279
280 bool replace_me_wrapper(u1 *pc);
281
282 void replace_me(rplpoint *rp,executionstate_t *es);
283
284 #if !defined(NDEBUG)
285 void replace_show_replacement_points(codeinfo *code);
286 void replace_replacement_point_println(rplpoint *rp, int depth);
287 void replace_executionstate_println(executionstate_t *es);
288 void replace_sourcestate_println(sourcestate_t *ss);
289 void replace_sourcestate_println_short(sourcestate_t *ss);
290 void replace_source_frame_println(sourceframe_t *frame);
291 #endif
292
293 /* machine dependent functions (code in ARCH_DIR/md.c) */
294
295 #if defined(ENABLE_JIT)
296 void md_patch_replacement_point(codeinfo *code, s4 index, rplpoint *rp,
297                                                                 u1 *savedmcode);
298 #endif
299
300 #endif /* defined(ENABLE_REPLACEMENT) */
301
302 #endif /* _REPLACE_H */
303
304
305 /*
306  * These are local overrides for various environment variables in Emacs.
307  * Please do not remove this and leave it at the end of the file, where
308  * Emacs will automagically detect them.
309  * ---------------------------------------------------------------------
310  * Local variables:
311  * mode: c
312  * indent-tabs-mode: t
313  * c-basic-offset: 4
314  * tab-width: 4
315  * End:
316  * vim:noexpandtab:sw=4:ts=4:
317  */