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