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