* src/vm/jit/jit.c: Moved to .cpp.
[cacao.git] / src / vm / jit / verify / typecheck-common.h
1 /* src/vm/jit/verify/typecheck-common.h - internal header for the type checker
2
3    Copyright (C) 1996-2005, 2006, 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 _TYPECHECK_COMMON_H
27 #define _TYPECHECK_COMMON_H
28
29 #include "config.h"
30 #include "vm/types.h"
31 #include "vm/global.h"
32
33 #include <assert.h>
34
35 #include "vm/jit/jit.hpp"
36
37
38 /****************************************************************************/
39 /* DEBUG HELPERS                                                            */
40 /****************************************************************************/
41
42 #ifdef TYPECHECK_DEBUG
43 #define TYPECHECK_ASSERT(cond)  assert(cond)
44 #else
45 #define TYPECHECK_ASSERT(cond)
46 #endif
47
48 #ifdef TYPECHECK_VERBOSE_OPT
49 extern bool opt_typecheckverbose;
50 #define DOLOG(action)  do { if (opt_typecheckverbose) {action;} } while(0)
51 #else
52 #define DOLOG(action)
53 #endif
54
55 #ifdef TYPECHECK_VERBOSE
56 #define TYPECHECK_VERBOSE_IMPORTANT
57 #define LOGNL              DOLOG(puts(""))
58 #define LOG(str)           DOLOG(puts(str);)
59 #define LOG1(str,a)        DOLOG(printf(str,a); LOGNL)
60 #define LOG2(str,a,b)      DOLOG(printf(str,a,b); LOGNL)
61 #define LOG3(str,a,b,c)    DOLOG(printf(str,a,b,c); LOGNL)
62 #define LOGIF(cond,str)    DOLOG(do {if (cond) { puts(str); }} while(0))
63 #ifdef  TYPEINFO_DEBUG
64 #define LOGINFO(info)      DOLOG(do {typeinfo_print_short(stdout,(info)); LOGNL;} while(0))
65 #else
66 #define LOGINFO(info)
67 #define typevector_print(x,y,z)
68 #endif
69 #define LOGFLUSH           DOLOG(fflush(stdout))
70 #define LOGSTR(str)        DOLOG(printf("%s", str))
71 #define LOGSTR1(str,a)     DOLOG(printf(str,a))
72 #define LOGSTR2(str,a,b)   DOLOG(printf(str,a,b))
73 #define LOGSTR3(str,a,b,c) DOLOG(printf(str,a,b,c))
74 #define LOGNAME(c)         DOLOG(class_classref_or_classinfo_print(c))
75 #define LOGMETHOD(str,m)   DOLOG(printf("%s", str); method_println(m);)
76 #else
77 #define LOG(str)
78 #define LOG1(str,a)
79 #define LOG2(str,a,b)
80 #define LOG3(str,a,b,c)
81 #define LOGIF(cond,str)
82 #define LOGINFO(info)
83 #define LOGFLUSH
84 #define LOGNL
85 #define LOGSTR(str)
86 #define LOGSTR1(str,a)
87 #define LOGSTR2(str,a,b)
88 #define LOGSTR3(str,a,b,c)
89 #define LOGNAME(c)
90 #define LOGMETHOD(str,m)
91 #endif
92
93 #ifdef TYPECHECK_VERBOSE_IMPORTANT
94 #define LOGimp(str)     DOLOG(puts(str);LOGNL)
95 #define LOGimpSTR(str)  DOLOG(puts(str))
96 #else
97 #define LOGimp(str)
98 #define LOGimpSTR(str)
99 #endif
100
101 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
102 #include <stdio.h>
103 void typecheck_print_var(FILE *file, jitdata *jd, s4 index);
104 void typecheck_print_vararray(FILE *file, jitdata *jd, s4 *vars, int len);
105 #endif
106
107
108 /****************************************************************************/
109 /* STATISTICS                                                               */
110 /****************************************************************************/
111
112 #if defined(TYPECHECK_DEBUG) && !defined(TYPECHECK_NO_STATISTICS)
113 /*#define TYPECHECK_STATISTICS*/
114 #endif
115
116 #ifdef TYPECHECK_STATISTICS
117 #define STAT_ITERATIONS  10
118 #define STAT_BLOCKS      10
119 #define STAT_LOCALS      16
120
121 extern int stat_typechecked;
122 extern int stat_methods_with_handlers;
123 extern int stat_methods_maythrow;
124 extern int stat_iterations[STAT_ITERATIONS+1];
125 extern int stat_reached;
126 extern int stat_copied;
127 extern int stat_merged;
128 extern int stat_merging_changed;
129 extern int stat_blocks[STAT_BLOCKS+1];
130 extern int stat_locals[STAT_LOCALS+1];
131 extern int stat_ins;
132 extern int stat_ins_maythrow;
133 extern int stat_ins_stack;
134 extern int stat_ins_field;
135 extern int stat_ins_field_unresolved;
136 extern int stat_ins_field_uninitialized;
137 extern int stat_ins_invoke;
138 extern int stat_ins_invoke_unresolved;
139 extern int stat_ins_primload;
140 extern int stat_ins_aload;
141 extern int stat_ins_builtin;
142 extern int stat_ins_builtin_gen;
143 extern int stat_ins_branch;
144 extern int stat_ins_switch;
145 extern int stat_ins_primitive_return;
146 extern int stat_ins_areturn;
147 extern int stat_ins_areturn_unresolved;
148 extern int stat_ins_athrow;
149 extern int stat_ins_athrow_unresolved;
150 extern int stat_ins_unchecked;
151 extern int stat_handlers_reached;
152 extern int stat_savedstack;
153
154 #define TYPECHECK_MARK(var)   ((var) = true)
155 #define TYPECHECK_COUNT(cnt)  (cnt)++
156 #define TYPECHECK_COUNTIF(cond,cnt)  do{if(cond) (cnt)++;} while(0)
157 #define TYPECHECK_COUNT_FREQ(array,val,limit) \
158         do {                                                                      \
159                 if ((val) < (limit)) (array)[val]++;  \
160                 else (array)[limit]++;                            \
161         } while (0)
162
163 void typecheck_print_statistics(FILE *file);
164
165 #else /* !defined(TYPECHECK_STATISTICS) */
166                                                    
167 #define TYPECHECK_COUNT(cnt)
168 #define TYPECHECK_MARK(var)
169 #define TYPECHECK_COUNTIF(cond,cnt)
170 #define TYPECHECK_COUNT_FREQ(array,val,limit)
171
172 #endif /* defined(TYPECHECK_STATISTICS) */
173
174
175 /****************************************************************************/
176 /* MACROS FOR THROWING EXCEPTIONS                                           */
177 /****************************************************************************/
178
179 #define TYPECHECK_VERIFYERROR_ret(m,msg,retval)                      \
180     do {                                                             \
181         exceptions_throw_verifyerror((m), (msg));                    \
182         return (retval);                                             \
183     } while (0)
184
185 #define TYPECHECK_VERIFYERROR_main(msg)  TYPECHECK_VERIFYERROR_ret(state.m,(msg),NULL)
186 #define TYPECHECK_VERIFYERROR_bool(msg)  TYPECHECK_VERIFYERROR_ret(state->m,(msg),false)
187
188
189 /****************************************************************************/
190 /* MISC MACROS                                                              */
191 /****************************************************************************/
192
193 #define COPYTYPE(source,dest)                                        \
194     {if (VAROP(source)->type == TYPE_ADR)                            \
195             TYPEINFO_COPY(VAROP(source)->typeinfo,VAROP(dest)->typeinfo);}
196
197
198 /****************************************************************************/
199 /* JSR VERIFICATION (stack-based verifier)                                  */
200 /****************************************************************************/
201
202 typedef struct typecheck_jsr_t typecheck_jsr_t;
203 typedef struct typecheck_jsr_caller_t typecheck_jsr_caller_t;
204
205 struct typecheck_jsr_caller_t {
206         typecheck_jsr_caller_t *next;                   /* next in linked list */
207         basicblock *callblock;             /* block containing the calling JSR */
208 };
209
210 struct typecheck_jsr_t {
211         typecheck_jsr_t *next;               /* next (lower) in the call chain */
212         basicblock  *start;                                   /* for debugging */
213         typecheck_jsr_caller_t *callers;  /* list of callers (blocks with JSR) */
214         basicblock  *retblock;              /* block with the RET for this sub */
215         bool         active;           /* true if this sub is currently active */
216         char        *blockflags;   /* saved block flags when JSR was traversed */
217         char        *usedlocals;       /* != 0 for each local used in this sub */
218         typedescriptor_t *retlocals;                 /* locals on the RET edge */
219         typedescriptor_t *retstack;                   /* stack on the RET edge */
220         s4              retdepth;               /* stack depth on the RET edge */
221 };
222
223 /****************************************************************************/
224 /* VERIFIER STATE STRUCT                                                    */
225 /****************************************************************************/
226
227 /* verifier_state - This structure keeps the current state of the      */
228 /* bytecode verifier for passing it between verifier functions.        */
229
230 typedef struct verifier_state {
231     instruction *iptr;               /* pointer to current instruction */
232     basicblock *bptr;                /* pointer to current basic block */
233
234         methodinfo *m;                               /* the current method */
235         jitdata *jd;                         /* jitdata for current method */
236         codegendata *cd;                 /* codegendata for current method */
237
238         basicblock *basicblocks;
239         s4 basicblockcount;
240         
241         s4 numlocals;                         /* number of local variables */
242         s4 validlocals;                /* number of Java-accessible locals */
243         
244         typedescriptor_t returntype;  /* return type of the current method */
245
246         s4 *savedindices;
247         s4 *savedinvars;                            /* saved invar pointer */
248
249         s4 exinvars;
250         
251     exception_entry **handlers;           /* active exception handlers */
252         
253     bool repeat;            /* if true, blocks are iterated over again */
254     bool initmethod;             /* true if this is an "<init>" method */
255
256 #ifdef TYPECHECK_STATISTICS
257         bool stat_maythrow;          /* at least one instruction may throw */
258 #endif
259
260         /* the following fields are used by the stackbased verifier only:  */
261
262         typedescriptor_t *locals;               /* current local variables */
263         typedescriptor_t *startlocals;/* locals at the start of each block */
264         typedescriptor_t *startstack;  /* stack at the start of each block */
265         s4               *indepth;                /* stack depth at --''-- */
266         typedescriptor_t *stackceiling;    /* upper edge of verifier stack */
267
268         typecheck_jsr_t *topjsr;        /* most recently called subroutine */
269         typecheck_jsr_t **jsrinfos;      /* subroutine info for each block */
270 } verifier_state;
271
272 void typecheck_init_flags(verifier_state *state, s4 minflags);
273 void typecheck_reset_flags(verifier_state *state);
274
275 bool typecheck_copy_types(verifier_state *state,
276                                                   s4 *srcvars, s4 *dstvars, s4 n);
277
278 typecheck_result typecheck_merge_types(verifier_state *state,
279                                                                            s4 *srcvars,
280                                                                            s4 *dstvars,
281                                                                            s4 n);
282
283 typecheck_result typestate_merge(verifier_state *state,
284                                                  s4 *srcvars, varinfo *srclocals,
285                                                  s4 *dstvars, varinfo *dstlocals,
286                                                  s4 n);
287
288 bool typestate_reach(verifier_state *state,
289                                          basicblock *destblock,
290                                          s4 *srcvars, varinfo *srclocals, s4 n);
291
292 bool typecheck_init_locals(verifier_state *state, bool newthis);
293
294 #endif /* _TYPECHECK_COMMON_H */
295
296 /*
297  * These are local overrides for various environment variables in Emacs.
298  * Please do not remove this and leave it at the end of the file, where
299  * Emacs will automagically detect them.
300  * ---------------------------------------------------------------------
301  * Local variables:
302  * mode: c
303  * indent-tabs-mode: t
304  * c-basic-offset: 4
305  * tab-width: 4
306  * End:
307  * vim:noexpandtab:sw=4:ts=4:
308  */