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