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