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