1 /* src/vm/jit/verify/typecheck-common.c - shared verifier code
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
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@cacaojvm.org
27 Authors: Edwin Steiner
38 #include "vm/global.h"
42 #include <vm/jit/show.h>
43 #include <typecheck-common.h>
45 /****************************************************************************/
47 /****************************************************************************/
49 #ifdef TYPECHECK_VERBOSE_OPT
50 bool opt_typecheckverbose = false;
53 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
55 void typecheck_print_var(FILE *file, jitdata *jd, s4 index)
59 assert(index >= 0 && index < jd->varcount);
61 typeinfo_print_type(file, var->type, &(var->typeinfo));
64 void typecheck_print_vararray(FILE *file, jitdata *jd, s4 *vars, int len)
68 for (i=0; i<len; ++i) {
71 typecheck_print_var(file, jd, *vars++);
75 #endif /* defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT) */
78 /****************************************************************************/
80 /****************************************************************************/
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 };
90 int stat_merging_changed = 0;
91 int stat_blocks[STAT_BLOCKS+1] = { 0 };
92 int stat_locals[STAT_LOCALS+1] = { 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;
116 static void print_freq(FILE *file,int *array,int limit)
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]);
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);
161 #endif /* defined(TYPECHECK_STATISTICS) */
164 /* typecheck_init_flags ********************************************************
166 Initialize the basic block flags for the following CFG traversal.
169 state............the current state of the verifier
170 minflags.........minimum flags value of blocks that should be
173 *******************************************************************************/
175 void typecheck_init_flags(verifier_state *state, s4 minflags)
180 /* set all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
182 i = state->basicblockcount;
183 for (block = state->basicblocks; block; block = block->next) {
185 #ifdef TYPECHECK_DEBUG
186 /* check for invalid flags */
187 if (block->flags != BBFINISHED && block->flags != BBDELETED && block->flags != BBUNDEF)
189 LOGSTR1("block flags: %d\n",block->flags); LOGFLUSH;
190 TYPECHECK_ASSERT(false);
194 if (block->flags >= minflags) {
195 block->flags = BBTYPECHECK_UNDEF;
199 /* the first block is always reached */
201 if (state->basicblockcount && state->basicblocks[0].flags == BBTYPECHECK_UNDEF)
202 state->basicblocks[0].flags = BBTYPECHECK_REACHED;
206 /* typecheck_reset_flags *******************************************************
208 Reset the flags of basic blocks we have not reached.
211 state............the current state of the verifier
213 *******************************************************************************/
215 void typecheck_reset_flags(verifier_state *state)
219 /* check for invalid flags at exit */
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,
230 LOG2("block L%03d has invalid flags after typecheck: %d",
231 block->nr,block->flags);
232 TYPECHECK_ASSERT(false);
237 /* Delete blocks we never reached */
239 for (block = state->basicblocks; block; block = block->next) {
240 if (block->flags == BBTYPECHECK_UNDEF)
241 block->flags = BBDELETED;
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 * ---------------------------------------------------------------------
253 * indent-tabs-mode: t
257 * vim:noexpandtab:sw=4:ts=4: