b27ae9b4367d4701fe6f936e7e93ca274246d169
[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    $Id$
26
27 */
28
29
30 #ifndef _REPLACE_H
31 #define _REPLACE_H
32
33 #include "config.h"
34 #include "vm/types.h"
35
36 #if !defined(ENABLE_REPLACEMENT)
37
38 /*** macros for the codegens (disabled version) ************************/
39
40 #define REPLACEMENT_POINTS_INIT(cd, jd)
41 #define REPLACEMENT_POINTS_RESET(cd, jd)
42 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)
43 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)
44 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)
45 #define REPLACEMENT_POINT_RETURN(cd, iptr)
46 #define REPLACEMENT_POINT_INVOKE(cd, iptr)
47 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr)
48
49 #else /* defined(ENABLE_REPLACEMENT) */
50
51 /* forward typedefs ***********************************************************/
52
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;
60
61 #include "arch.h"
62 #include "md-abi.h"
63
64 #include "vm/jit/reg.h"
65 #include "vm/jit/stacktrace.h"
66
67 #include "vmcore/method.h"
68
69
70 /* alignment for the safe stack used during replacement */
71
72 #define REPLACE_STACK_ALIGNMENT  16
73
74 /* the size of the safe stack we use during replacement */
75 /* Must be a multiple of REPLACE_STACK_ALIGNMENT.       */
76
77 #define REPLACE_SAFESTACK_SIZE  16384  /* bytes */
78
79
80 /*** structs *********************************************************/
81
82 #define RPLALLOC_STACK  -1
83 #define RPLALLOC_PARAM  -2
84 #define RPLALLOC_SYNC   -3
85
86 /* `rplalloc` is a compact struct for register allocation info        */
87
88 /* XXX optimize this for space efficiency */
89 struct rplalloc {
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                      */
94 };
95
96 #if INMEMORY > 0x08
97 #error value of INMEMORY is too big to fit in rplalloc.flags
98 #endif
99
100
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
111
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             */
115
116
117 #if !defined(NDEBUG)
118 #define RPLPOINT_CHECK(type)     , RPLPOINT_TYPE_##type
119 #define RPLPOINT_CHECK_BB(bptr)  , (bptr)->type
120 #else
121 #define RPLPOINT_CHECK(type)
122 #define RPLPOINT_CHECK_BB(bptr)
123 #endif
124
125
126 /* An `rplpoint` represents a replacement point in a compiled method  */
127
128 struct rplpoint {
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    */
138 };
139
140
141 union replace_val_t {
142         s4             i;
143         s8             l;
144         ptrint         p;
145         struct {
146                 u4 lo;
147                 u4 hi;
148         }              words;
149         float          f;
150         double         d;
151         java_object_t *a;
152 };
153
154
155 /* An `executionsstate` represents the state of a thread as it reached */
156 /* an replacement point or is about to enter one.                      */
157
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         */
163
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 */
168 #endif
169
170         codeinfo     *code;            /* codeinfo corresponding to the pv */
171 };
172
173
174 struct sourceframe_t {
175         sourceframe_t *down;           /* source frame down the call chain */
176
177         methodinfo    *method;                  /* method this frame is in */
178         s4             id;
179         s4             type;
180
181         /* values */
182         replace_val_t  instance;
183
184         replace_val_t *javastack;                  /* values of stack vars */
185         u1            *javastacktype;              /*  types of stack vars */
186         s4             javastackdepth;             /* number of stack vars */
187
188         replace_val_t *javalocals;                 /* values of javalocals */
189         u1            *javalocaltype;              /*  types of javalocals */
190         s4             javalocalcount;             /* number of javalocals */
191
192         replace_val_t *syncslots;
193         s4             syncslotcount; /* XXX do we need more than one? */
194
195         /* mapping info */
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 */
200
201         /* info for native frames */
202         stackframeinfo *sfi;      /* sfi for native frames, otherwise NULL */
203         s4             nativeframesize;    /* size (bytes) of native frame */
204         u1            *nativepc;
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 */
209 #endif
210 };
211
212 #define REPLACE_IS_NATIVE_FRAME(frame)  ((frame)->sfi != NULL)
213 #define REPLACE_IS_JAVA_FRAME(frame)    ((frame)->sfi == NULL)
214
215
216 struct sourcestate_t {
217         sourceframe_t *frames;    /* list of source frames, from bottom up */
218 };
219
220
221 /* replace_safestack_t *********************************************************
222
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.)
227
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`.)
231
232 *******************************************************************************/
233
234 struct replace_safestack_t {
235         u1                stack[REPLACE_SAFESTACK_SIZE];
236         executionstate_t  es;
237         sourcestate_t    *ss;
238         u1               *mem;             /* start of the allocated memory chunk */
239         s4                dumpsize;
240 };
241
242
243 /*** macros for the codegens *******************************************/
244
245 #define REPLACEMENT_POINTS_INIT(cd, jd)                              \
246     if (!replace_create_replacement_points(jd))                      \
247         return false;                                                \
248     (cd)->replacementpoint = (jd)->code->rplpoints;
249
250 #define REPLACEMENT_POINTS_RESET(cd, jd)                             \
251     (cd)->replacementpoint = (jd)->code->rplpoints;
252
253 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)                      \
254     if ((bptr)->bitflags & BBFLAG_REPLACEMENT)                       \
255         codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
256
257 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)                     \
258     codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
259
260 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)                      \
261     codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
262
263 #define REPLACEMENT_POINT_RETURN(cd, iptr)                           \
264     codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
265
266 #define REPLACEMENT_POINT_INVOKE(cd, iptr)                           \
267     codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
268
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;
273
274 /*** prototypes ********************************************************/
275
276 bool replace_create_replacement_points(jitdata *jd);
277 void replace_free_replacement_points(codeinfo *code);
278
279 void replace_activate_replacement_points(codeinfo *code, bool mappable);
280 void replace_deactivate_replacement_points(codeinfo *code);
281
282 bool replace_me_wrapper(u1 *pc);
283
284 void replace_me(rplpoint *rp,executionstate_t *es);
285
286 #if !defined(NDEBUG)
287 void replace_show_replacement_points(codeinfo *code);
288 void replace_replacement_point_println(rplpoint *rp, int depth);
289 void replace_executionstate_println(executionstate_t *es);
290 void replace_sourcestate_println(sourcestate_t *ss);
291 void replace_sourcestate_println_short(sourcestate_t *ss);
292 void replace_source_frame_println(sourceframe_t *frame);
293 #endif
294
295 /* machine dependent functions (code in ARCH_DIR/md.c) */
296
297 #if defined(ENABLE_JIT)
298 void md_patch_replacement_point(codeinfo *code, s4 index, rplpoint *rp,
299                                                                 u1 *savedmcode);
300 #endif
301
302 #endif /* defined(ENABLE_REPLACEMENT) */
303
304 #endif /* _REPLACE_H */
305
306
307 /*
308  * These are local overrides for various environment variables in Emacs.
309  * Please do not remove this and leave it at the end of the file, where
310  * Emacs will automagically detect them.
311  * ---------------------------------------------------------------------
312  * Local variables:
313  * mode: c
314  * indent-tabs-mode: t
315  * c-basic-offset: 4
316  * tab-width: 4
317  * End:
318  * vim:noexpandtab:sw=4:ts=4:
319  */