* src/vm/jit/verify/typecheck-stackbased.c: New file. Not used, yet.
[cacao.git] / src / vm / jit / verify / typecheck-common.c
1 /* src/vm/jit/verify/typecheck-common.c - shared verifier code
2
3    Copyright (C) 1996-2005, 2006 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    Contact: cacao@cacaojvm.org
26
27    Authors: Edwin Steiner
28
29    Changes: 
30
31    $Id$
32
33 */
34
35
36 #include "config.h"
37 #include "vm/types.h"
38 #include "vm/global.h"
39
40 #include <assert.h>
41
42 #include <vm/jit/show.h>
43 #include <typecheck-common.h>
44
45 /****************************************************************************/
46 /* DEBUG HELPERS                                                            */
47 /****************************************************************************/
48
49 #ifdef TYPECHECK_VERBOSE_OPT
50 bool opt_typecheckverbose = false;
51 #endif
52
53 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
54
55 void typecheck_print_var(FILE *file, jitdata *jd, s4 index)
56 {
57         varinfo *var;
58
59         assert(index >= 0 && index < jd->varcount);
60         var = VAR(index);
61         typeinfo_print_type(file, var->type, &(var->typeinfo));
62 }
63
64 void typecheck_print_vararray(FILE *file, jitdata *jd, s4 *vars, int len)
65 {
66         s4 i;
67
68         for (i=0; i<len; ++i) {
69                 if (i)
70                         fputc(' ', file);
71                 typecheck_print_var(file, jd, *vars++);
72         }
73 }
74
75 #endif /* defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT) */
76
77
78 /****************************************************************************/
79 /* STATISTICS                                                               */
80 /****************************************************************************/
81
82 #if defined(TYPECHECK_STATISTICS)
83 int stat_typechecked = 0;
84 int stat_methods_with_handlers = 0;
85 int stat_methods_maythrow = 0;
86 int stat_iterations[STAT_ITERATIONS+1] = { 0 };
87 int stat_reached = 0;
88 int stat_copied = 0;
89 int stat_merged = 0;
90 int stat_merging_changed = 0;
91 int stat_blocks[STAT_BLOCKS+1] = { 0 };
92 int stat_locals[STAT_LOCALS+1] = { 0 };
93 int stat_ins = 0;
94 int stat_ins_maythrow = 0;
95 int stat_ins_stack = 0;
96 int stat_ins_field = 0;
97 int stat_ins_field_unresolved = 0;
98 int stat_ins_field_uninitialized = 0;
99 int stat_ins_invoke = 0;
100 int stat_ins_invoke_unresolved = 0;
101 int stat_ins_primload = 0;
102 int stat_ins_aload = 0;
103 int stat_ins_builtin = 0;
104 int stat_ins_builtin_gen = 0;
105 int stat_ins_branch = 0;
106 int stat_ins_switch = 0;
107 int stat_ins_primitive_return = 0;
108 int stat_ins_areturn = 0;
109 int stat_ins_areturn_unresolved = 0;
110 int stat_ins_athrow = 0;
111 int stat_ins_athrow_unresolved = 0;
112 int stat_ins_unchecked = 0;
113 int stat_handlers_reached = 0;
114 int stat_savedstack = 0;
115
116 static void print_freq(FILE *file,int *array,int limit)
117 {
118         int i;
119         for (i=0; i<limit; ++i)
120                 fprintf(file,"      %3d: %8d\n",i,array[i]);
121         fprintf(file,"    >=%3d: %8d\n",limit,array[limit]);
122 }
123
124 void typecheck_print_statistics(FILE *file) {
125         fprintf(file,"typechecked methods: %8d\n",stat_typechecked);
126         fprintf(file,"    with handler(s): %8d\n",stat_methods_with_handlers);
127         fprintf(file,"    with throw(s)  : %8d\n",stat_methods_maythrow);
128         fprintf(file,"reached blocks     : %8d\n",stat_reached);
129         fprintf(file,"copied states      : %8d\n",stat_copied);
130         fprintf(file,"merged states      : %8d\n",stat_merged);
131         fprintf(file,"merging changed    : %8d\n",stat_merging_changed);
132         fprintf(file,"handlers reached   : %8d\n",stat_handlers_reached);
133         fprintf(file,"saved stack (times): %8d\n",stat_savedstack);
134         fprintf(file,"instructions       : %8d\n",stat_ins);
135         fprintf(file,"    stack          : %8d\n",stat_ins_stack);
136         fprintf(file,"    field access   : %8d\n",stat_ins_field);
137         fprintf(file,"      (unresolved) : %8d\n",stat_ins_field_unresolved);
138         fprintf(file,"      (uninit.)    : %8d\n",stat_ins_field_uninitialized);
139         fprintf(file,"    invocations    : %8d\n",stat_ins_invoke);
140         fprintf(file,"      (unresolved) : %8d\n",stat_ins_invoke_unresolved);
141         fprintf(file,"    load primitive : (currently not counted) %8d\n",stat_ins_primload);
142         fprintf(file,"    load address   : %8d\n",stat_ins_aload);
143         fprintf(file,"    builtins       : %8d\n",stat_ins_builtin);
144         fprintf(file,"        generic    : %8d\n",stat_ins_builtin_gen);
145         fprintf(file,"    branches       : %8d\n",stat_ins_branch);
146         fprintf(file,"    switches       : %8d\n",stat_ins_switch);
147         fprintf(file,"    prim. return   : %8d\n",stat_ins_primitive_return);
148         fprintf(file,"    areturn        : %8d\n",stat_ins_areturn);
149         fprintf(file,"      (unresolved) : %8d\n",stat_ins_areturn_unresolved);
150         fprintf(file,"    athrow         : %8d\n",stat_ins_athrow);
151         fprintf(file,"      (unresolved) : %8d\n",stat_ins_athrow_unresolved);
152         fprintf(file,"    unchecked      : %8d\n",stat_ins_unchecked);
153         fprintf(file,"    maythrow       : %8d\n",stat_ins_maythrow);
154         fprintf(file,"iterations used:\n");
155         print_freq(file,stat_iterations,STAT_ITERATIONS);
156         fprintf(file,"basic blocks per method / 10:\n");
157         print_freq(file,stat_blocks,STAT_BLOCKS);
158         fprintf(file,"locals:\n");
159         print_freq(file,stat_locals,STAT_LOCALS);
160 }
161 #endif /* defined(TYPECHECK_STATISTICS) */
162
163
164 /* typecheck_init_flags ********************************************************
165  
166    Initialize the basic block flags for the following CFG traversal.
167   
168    IN:
169        state............the current state of the verifier
170        minflags.........minimum flags value of blocks that should be
171                         considered
172
173 *******************************************************************************/
174
175 void typecheck_init_flags(verifier_state *state, s4 minflags)
176 {
177         s4 i;
178         basicblock *block;
179
180     /* set all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
181         
182     i = state->basicblockcount;
183     for (block = state->basicblocks; block; block = block->next) {
184                 
185 #ifdef TYPECHECK_DEBUG
186                 /* check for invalid flags */
187         if (block->flags != BBFINISHED && block->flags != BBDELETED && block->flags != BBUNDEF)
188         {
189             LOGSTR1("block flags: %d\n",block->flags); LOGFLUSH;
190                         TYPECHECK_ASSERT(false);
191         }
192 #endif
193
194         if (block->flags >= minflags) {
195             block->flags = BBTYPECHECK_UNDEF;
196         }
197     }
198
199     /* the first block is always reached */
200         
201     if (state->basicblockcount && state->basicblocks[0].flags == BBTYPECHECK_UNDEF)
202         state->basicblocks[0].flags = BBTYPECHECK_REACHED;
203 }
204
205
206 /* typecheck_reset_flags *******************************************************
207  
208    Reset the flags of basic blocks we have not reached.
209   
210    IN:
211        state............the current state of the verifier
212
213 *******************************************************************************/
214
215 void typecheck_reset_flags(verifier_state *state)
216 {
217         basicblock *block;
218
219         /* check for invalid flags at exit */
220         
221 #ifdef TYPECHECK_DEBUG
222         for (block = state->basicblocks; block; block = block->next) {
223                 if (block->flags != BBDELETED
224                         && block->flags != BBUNDEF
225                         && block->flags != BBFINISHED
226                         && block->flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
227                                                                                                          * some exception handlers,
228                                                                                                          * that's ok. */
229                 {
230                         LOG2("block L%03d has invalid flags after typecheck: %d",
231                                  block->nr,block->flags);
232                         TYPECHECK_ASSERT(false);
233                 }
234         }
235 #endif
236         
237         /* Delete blocks we never reached */
238         
239         for (block = state->basicblocks; block; block = block->next) {
240                 if (block->flags == BBTYPECHECK_UNDEF)
241                         block->flags = BBDELETED;
242         }
243 }
244
245
246 /*
247  * These are local overrides for various environment variables in Emacs.
248  * Please do not remove this and leave it at the end of the file, where
249  * Emacs will automagically detect them.
250  * ---------------------------------------------------------------------
251  * Local variables:
252  * mode: c
253  * indent-tabs-mode: t
254  * c-basic-offset: 4
255  * tab-width: 4
256  * End:
257  * vim:noexpandtab:sw=4:ts=4:
258  */