* Merged executionstate branch.
[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 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
47 #define REPLACEMENT_POINT_FORGC_BUILTIN_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 sourcestate_t sourcestate_t;
56 typedef struct sourceframe_t sourceframe_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 /*** structs *********************************************************/
69
70 #define RPLALLOC_STACK  -1
71 #define RPLALLOC_PARAM  -2
72 #define RPLALLOC_SYNC   -3
73
74 /* `rplalloc` is a compact struct for register allocation info        */
75
76 /* XXX optimize this for space efficiency */
77 struct rplalloc {
78         s4           index;     /* local index, -1 for stack slot         */
79         s4           regoff;    /* register index / stack slot offset     */
80         unsigned int flags:4;   /* OR of (INMEMORY,...)                   */
81         unsigned int type:4;    /* TYPE_... constant                      */
82 };
83
84 #if INMEMORY > 0x08
85 #error value of INMEMORY is too big to fit in rplalloc.flags
86 #endif
87
88
89 /* XXX what to do about overlapping rplpoints? */
90 /* CAUTION: Do not change the numerical values. These are used as     */
91 /*          indices into replace_normalize_type_map.                  */
92 #define RPLPOINT_TYPE_STD     BBTYPE_STD
93 #define RPLPOINT_TYPE_EXH     BBTYPE_EXH
94 #define RPLPOINT_TYPE_SBR     BBTYPE_SBR
95 #define RPLPOINT_TYPE_CALL    3
96 #define RPLPOINT_TYPE_INLINE  4
97 #define RPLPOINT_TYPE_RETURN  5
98 #define RPLPOINT_TYPE_BODY    6
99
100 #define RPLPOINT_FLAG_NOTRAP     0x01  /* rplpoint cannot be trapped */
101 #define RPLPOINT_FLAG_COUNTDOWN  0x02  /* count down hits            */
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 union replace_val_t {
130         s4             i;
131         s8             l;
132         ptrint         p;
133         struct {
134                 u4 lo;
135                 u4 hi;
136         }              words;
137         float          f;
138         double         d;
139         java_object_t *a;
140 };
141
142
143         u1           *ra;                /* return address / link register */
144 struct sourceframe_t {
145         sourceframe_t *down;           /* source frame down the call chain */
146
147         methodinfo    *method;                  /* method this frame is in */
148         s4             id;
149         s4             type;
150
151         /* values */
152         replace_val_t  instance;
153
154         replace_val_t *javastack;                  /* values of stack vars */
155         u1            *javastacktype;              /*  types of stack vars */
156         s4             javastackdepth;             /* number of stack vars */
157
158         replace_val_t *javalocals;                 /* values of javalocals */
159         u1            *javalocaltype;              /*  types of javalocals */
160         s4             javalocalcount;             /* number of javalocals */
161
162         replace_val_t *syncslots;
163         s4             syncslotcount; /* XXX do we need more than one? */
164
165         /* mapping info */
166         rplpoint      *fromrp;         /* rplpoint used to read this frame */
167         codeinfo      *fromcode;              /* code this frame was using */
168         rplpoint      *torp;          /* rplpoint this frame was mapped to */
169         codeinfo      *tocode;            /* code this frame was mapped to */
170
171         /* info for native frames */
172         stackframeinfo_t *sfi;      /* sfi for native frames, otherwise NULL */
173         s4             nativeframesize;    /* size (bytes) of native frame */
174         u1            *nativepc;
175         ptrint         nativesavint[INT_SAV_CNT]; /* XXX temporary */
176         double         nativesavflt[FLT_REG_CNT]; /* XXX temporary */
177 #if defined(HAS_ADDRESS_REGISTER_FILE)
178         ptrint         nativesavadr[ADR_SAV_CNT]; /* XXX temporary */
179 #endif
180 };
181
182 #define REPLACE_IS_NATIVE_FRAME(frame)  ((frame)->sfi != NULL)
183 #define REPLACE_IS_JAVA_FRAME(frame)    ((frame)->sfi == NULL)
184
185
186 struct sourcestate_t {
187         sourceframe_t *frames;    /* list of source frames, from bottom up */
188 };
189
190
191 /*** macros for the codegens *******************************************/
192
193 #define REPLACEMENT_POINTS_INIT(cd, jd)                              \
194     if (!replace_create_replacement_points(jd))                      \
195         return false;                                                \
196     (cd)->replacementpoint = (jd)->code->rplpoints;
197
198 #define REPLACEMENT_POINTS_RESET(cd, jd)                             \
199     (cd)->replacementpoint = (jd)->code->rplpoints;
200
201 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)                      \
202     if ((bptr)->bitflags & BBFLAG_REPLACEMENT)                       \
203         codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
204
205 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)                     \
206     codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
207
208 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)                      \
209     codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
210
211 #define REPLACEMENT_POINT_RETURN(cd, iptr)                           \
212     codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
213
214 #define REPLACEMENT_POINT_INVOKE(cd, iptr)                           \
215     codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
216
217 #define REPLACEMENT_POINT_INVOKE_RETURN(cd,  iptr)                   \
218     if (iptr->opc != ICMD_BUILTIN)                                   \
219         cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
220                     - (ptrint) cd->replacementpoint[-1].pc;
221
222
223 /*** macros for the codegens (for GC) **********************************/
224
225 #if defined(ENABLE_GC_CACAO)
226
227 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)                    \
228         codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
229
230 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)             \
231         if (iptr->opc == ICMD_BUILTIN)                                   \
232                 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
233                                         - (ptrint) cd->replacementpoint[-1].pc;
234
235 #else /* defined(ENABLE_GC_CACAO) */
236
237 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
238 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
239
240 #endif /* defined(ENABLE_GC_CACAO) */
241
242
243 /*** prototypes ********************************************************/
244
245 bool replace_create_replacement_points(jitdata *jd);
246 void replace_free_replacement_points(codeinfo *code);
247
248 void replace_activate_replacement_points(codeinfo *code, bool mappable);
249 void replace_deactivate_replacement_points(codeinfo *code);
250
251 bool replace_me_wrapper(u1 *pc, void *context);
252
253 #if !defined(NDEBUG)
254 void replace_show_replacement_points(codeinfo *code);
255 void replace_replacement_point_println(rplpoint *rp, int depth);
256 void replace_sourcestate_println(sourcestate_t *ss);
257 void replace_sourcestate_println_short(sourcestate_t *ss);
258 void replace_source_frame_println(sourceframe_t *frame);
259 #endif
260
261 /* machine dependent functions (code in ARCH_DIR/md.c) */
262
263 #if defined(ENABLE_JIT)
264 void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert);
265 #endif
266
267 #endif /* defined(ENABLE_REPLACEMENT) */
268
269 #endif /* _REPLACE_H */
270
271
272 /*
273  * These are local overrides for various environment variables in Emacs.
274  * Please do not remove this and leave it at the end of the file, where
275  * Emacs will automagically detect them.
276  * ---------------------------------------------------------------------
277  * Local variables:
278  * mode: c
279  * indent-tabs-mode: t
280  * c-basic-offset: 4
281  * tab-width: 4
282  * End:
283  * vim:noexpandtab:sw=4:ts=4:
284  */