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