* src/vm/jit/codegen-common.cpp, src/vm/jit/x86_64/codegen.c: Generate
[cacao.git] / src / vm / jit / replace.hpp
1 /* src/vm/jit/replace.hpp - on-stack replacement of methods
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #ifndef _REPLACE_HPP
27 #define _REPLACE_HPP
28
29 #include "config.h"
30 #include "vm/types.h"
31
32 #if !defined(ENABLE_REPLACEMENT)
33
34 /*** macros for the codegens (disabled version) ************************/
35
36 #define REPLACEMENT_POINTS_INIT(cd, jd)
37 #define REPLACEMENT_POINTS_RESET(cd, jd)
38 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)
39 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)
40 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)
41 #define REPLACEMENT_POINT_RETURN(cd, iptr)
42 #define REPLACEMENT_POINT_INVOKE(cd, iptr)
43 #define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr)
44 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
45 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
46
47 #else /* defined(ENABLE_REPLACEMENT) */
48
49 /* forward typedefs ***********************************************************/
50
51 typedef struct rplalloc rplalloc;
52 typedef struct rplpoint rplpoint;
53 typedef struct sourcestate_t sourcestate_t;
54 typedef struct sourceframe_t sourceframe_t;
55 typedef union  replace_val_t replace_val_t;
56
57 #include "arch.h"
58 #include "md-abi.h"
59
60 #include "vm/method.hpp"
61
62 #include "vm/jit/reg.h"
63 #include "vm/jit/stacktrace.hpp"
64
65
66 /*** structs *********************************************************/
67
68 #define RPLALLOC_STACK  -1
69 #define RPLALLOC_PARAM  -2
70 #define RPLALLOC_SYNC   -3
71
72 /* `rplalloc` is a compact struct for register allocation info        */
73
74 /* XXX optimize this for space efficiency */
75 struct rplalloc {
76         s4           index;     /* local index, -1 for stack slot         */
77         s4           regoff;    /* register index / stack slot offset     */
78         unsigned int flags:4;   /* OR of (INMEMORY,...)                   */
79         unsigned int type:4;    /* TYPE_... constant                      */
80 };
81
82 #if INMEMORY > 0x08
83 #error value of INMEMORY is too big to fit in rplalloc.flags
84 #endif
85
86
87 /* XXX what to do about overlapping rplpoints? */
88 /* CAUTION: Do not change the numerical values. These are used as     */
89 /*          indices into replace_normalize_type_map.                  */
90 #define RPLPOINT_TYPE_STD     BBTYPE_STD
91 #define RPLPOINT_TYPE_EXH     BBTYPE_EXH
92 #define RPLPOINT_TYPE_SBR     BBTYPE_SBR
93 #define RPLPOINT_TYPE_CALL    3
94 #define RPLPOINT_TYPE_INLINE  4
95 #define RPLPOINT_TYPE_RETURN  5
96 #define RPLPOINT_TYPE_BODY    6
97
98 #define RPLPOINT_FLAG_NOTRAP     0x01  /* rplpoint cannot be trapped */
99 #define RPLPOINT_FLAG_COUNTDOWN  0x02  /* count down hits            */
100 #define RPLPOINT_FLAG_ACTIVE     0x08  /* trap is active             */
101
102
103 #if !defined(NDEBUG)
104 #define RPLPOINT_CHECK(type)     , RPLPOINT_TYPE_##type
105 #define RPLPOINT_CHECK_BB(bptr)  , (bptr)->type
106 #else
107 #define RPLPOINT_CHECK(type)
108 #define RPLPOINT_CHECK_BB(bptr)
109 #endif
110
111
112 /* An `rplpoint` represents a replacement point in a compiled method  */
113
114 struct rplpoint {
115         u1          *pc;           /* machine code PC of this point       */
116         methodinfo  *method;       /* source method this point is in      */
117         rplpoint    *parent;       /* rplpoint of the inlined body        */ /* XXX unify with code */
118         rplalloc    *regalloc;     /* pointer to register index table     */
119         s4           id;           /* id of the rplpoint within method    */
120         s4           callsize;     /* size of call code in bytes          */
121         unsigned int regalloccount:20; /* number of local allocations     */
122         unsigned int type:4;           /* RPLPOINT_TYPE_... constant      */
123         unsigned int flags:8;          /* OR of RPLPOINT_... constants    */
124 };
125
126
127 union replace_val_t {
128         s4             i;
129         s8             l;
130         ptrint         p;
131         struct {
132                 u4 lo;
133                 u4 hi;
134         }              words;
135         float          f;
136         double         d;
137         java_object_t *a;
138 };
139
140
141 struct sourceframe_t {
142         sourceframe_t *down;           /* source frame down the call chain */
143
144         methodinfo    *method;                  /* method this frame is in */
145         s4             id;
146         s4             type;
147
148         /* values */
149         replace_val_t  instance;
150
151         replace_val_t *javastack;                  /* values of stack vars */
152         u1            *javastacktype;              /*  types of stack vars */
153         s4             javastackdepth;             /* number of stack vars */
154
155         replace_val_t *javalocals;                 /* values of javalocals */
156         u1            *javalocaltype;              /*  types of javalocals */
157         s4             javalocalcount;             /* number of javalocals */
158
159         replace_val_t *syncslots;
160         s4             syncslotcount; /* XXX do we need more than one? */
161
162         /* mapping info */
163         rplpoint      *fromrp;         /* rplpoint used to read this frame */
164         codeinfo      *fromcode;              /* code this frame was using */
165         rplpoint      *torp;          /* rplpoint this frame was mapped to */
166         codeinfo      *tocode;            /* code this frame was mapped to */
167
168         /* info for native frames */
169         stackframeinfo_t *sfi;      /* sfi for native frames, otherwise NULL */
170         s4             nativeframesize;    /* size (bytes) of native frame */
171         u1            *nativepc;
172         ptrint         nativesavint[INT_SAV_CNT]; /* XXX temporary */
173         double         nativesavflt[FLT_REG_CNT]; /* XXX temporary */
174 #if defined(HAS_ADDRESS_REGISTER_FILE)
175         ptrint         nativesavadr[ADR_SAV_CNT]; /* XXX temporary */
176 #endif
177 };
178
179 #define REPLACE_IS_NATIVE_FRAME(frame)  ((frame)->sfi != NULL)
180 #define REPLACE_IS_JAVA_FRAME(frame)    ((frame)->sfi == NULL)
181
182
183 struct sourcestate_t {
184         sourceframe_t *frames;    /* list of source frames, from bottom up */
185 };
186
187
188 /*** macros for the codegens *******************************************/
189
190 #define REPLACEMENT_POINTS_INIT(cd, jd)                              \
191     if (!replace_create_replacement_points(jd))                      \
192         return false;                                                \
193     (cd)->replacementpoint = (jd)->code->rplpoints;
194
195 #define REPLACEMENT_POINTS_RESET(cd, jd)                             \
196     (cd)->replacementpoint = (jd)->code->rplpoints;
197
198 #define REPLACEMENT_POINT_BLOCK_START(cd, bptr)                      \
199     if ((bptr)->bitflags & BBFLAG_REPLACEMENT)                       \
200         codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
201
202 #define REPLACEMENT_POINT_INLINE_START(cd, iptr)                     \
203     codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
204
205 #define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)                      \
206     codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
207
208 #define REPLACEMENT_POINT_RETURN(cd, iptr)                           \
209     codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
210
211 #define REPLACEMENT_POINT_INVOKE(cd, iptr)                           \
212     codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
213
214 #define REPLACEMENT_POINT_INVOKE_RETURN(cd,  iptr)                   \
215     if (iptr->opc != ICMD_BUILTIN)                                   \
216         cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
217                     - (ptrint) cd->replacementpoint[-1].pc;
218
219
220 /*** macros for the codegens (for GC) **********************************/
221
222 #if defined(ENABLE_GC_CACAO)
223
224 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)                    \
225         codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
226
227 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)             \
228         if (iptr->opc == ICMD_BUILTIN)                                   \
229                 cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
230                                         - (ptrint) cd->replacementpoint[-1].pc;
231
232 #else // ENABLE_GC_CACAO
233
234 #define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
235 #define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
236
237 #endif // ENABLE_GC_CACAO
238
239
240 /*** prototypes ********************************************************/
241
242 #ifdef __cplusplus
243 extern "C" {
244 #endif
245
246 bool replace_create_replacement_points(jitdata *jd);
247 void replace_free_replacement_points(codeinfo *code);
248
249 void replace_activate_replacement_points(codeinfo *code, bool mappable);
250 void replace_deactivate_replacement_points(codeinfo *code);
251
252 bool replace_me_wrapper(u1 *pc, void *context);
253
254 #if !defined(NDEBUG)
255 void replace_show_replacement_points(codeinfo *code);
256 void replace_replacement_point_println(rplpoint *rp, int depth);
257 void replace_sourcestate_println(sourcestate_t *ss);
258 void replace_sourcestate_println_short(sourcestate_t *ss);
259 void replace_source_frame_println(sourceframe_t *frame);
260 #endif
261
262 /* machine dependent functions (code in ARCH_DIR/md.c) */
263
264 #if defined(ENABLE_JIT)
265 void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert);
266 #endif
267
268 #ifdef __cplusplus
269 }
270 #endif
271
272 #endif // ENABLE_REPLACEMENT
273
274 #endif // _REPLACE_HPP
275
276
277 /*
278  * These are local overrides for various environment variables in Emacs.
279  * Please do not remove this and leave it at the end of the file, where
280  * Emacs will automagically detect them.
281  * ---------------------------------------------------------------------
282  * Local variables:
283  * mode: c++
284  * indent-tabs-mode: t
285  * c-basic-offset: 4
286  * tab-width: 4
287  * End:
288  * vim:noexpandtab:sw=4:ts=4:
289  */