* m4/assertion.m4: Fixed copyright header.
[cacao.git] / src / vm / jit / exceptiontable.c
1 /* src/vm/jit/exceptiontable.c - method exception table
2
3    Copyright (C) 2007
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 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30
31 #include "mm/memory.h"
32
33 #include "vm/jit/code.h"
34 #include "vm/jit/exceptiontable.h"
35 #include "vm/jit/jit.h"
36
37
38 /* exceptiontable_create *******************************************************
39
40    Builds the exception table for the currently compiled method.
41
42    IN:
43        jd ... JIT data of the currently compiled method
44
45 *******************************************************************************/
46
47 void exceptiontable_create(jitdata *jd)
48 {
49         codeinfo               *code;
50         exceptiontable_t       *et;
51         exceptiontable_entry_t *ete;
52         exception_entry        *ex;
53         uint8_t                *pv;
54
55         /* Get required compiler data. */
56
57         code = jd->code;
58
59         /* Don't allocate an exception table if we don't need one. */
60
61         if (jd->exceptiontablelength == 0)
62                 return;
63
64         /* Allocate the exception table and the entries array. */
65
66         et  = NEW(exceptiontable_t);
67         ete = MNEW(exceptiontable_entry_t, jd->exceptiontablelength);
68
69         /* Fill the exception table. */
70
71         et->length  = jd->exceptiontablelength;
72         et->entries = ete;
73
74         /* Fill the exception table entries. */
75
76         pv = code->entrypoint;
77
78         for (ex = jd->exceptiontable; ex != NULL; ex = ex->down, ete++) {
79                 /* Resolve basicblock relative start PCs to absolute
80                    addresses. */
81
82                 ete->startpc       = pv + ex->start->mpc;
83                 ete->endpc         = pv + ex->end->mpc;
84                 ete->handlerpc     = pv + ex->handler->mpc;
85
86                 /* Store the catch type. */
87
88                 ete->catchtype.any = ex->catchtype.any;
89         }
90
91         /* Store the exception table in the codeinfo. */
92
93         code->exceptiontable = et;
94
95 #if 0
96         exceptiontable_print(code);
97 #endif
98 }
99
100
101 /* exceptiontable_free *********************************************************
102
103    Frees the memory allocated by the exception table stored in the
104    codeinfo.
105
106    IN:
107        code ... codeinfo of a method realization
108
109 *******************************************************************************/
110
111 void exceptiontable_free(codeinfo *code)
112 {
113         exceptiontable_t       *et;
114         exceptiontable_entry_t *ete;
115
116         /* Sanity check. */
117
118         assert(code != NULL);
119
120         /* Free the exception table memory. */
121
122         et = code->exceptiontable;
123  
124         if (et != NULL) {
125                 ete = et->entries;
126
127                 if (ete != NULL) {
128                         MFREE(ete, exceptiontable_entry_t, et->length);
129
130                         /* Clear the pointer. */
131
132                         et->entries = NULL;
133                 }
134
135                 FREE(et, exceptiontable_t);
136
137                 /* Clear the pointer. */
138
139                 code->exceptiontable = NULL;
140         }
141 }
142
143
144 /* exceptiontable_print ********************************************************
145
146    Print the exception table.
147
148    IN:
149        code ... codeinfo of a method realization
150
151 *******************************************************************************/
152
153 #if !defined(NDEBUG)
154 void exceptiontable_print(codeinfo *code)
155 {
156         exceptiontable_t       *et;
157         exceptiontable_entry_t *ete;
158         int                     i;
159
160         et = code->exceptiontable;
161
162         /* Print the exception table. */
163
164         log_start();
165         log_print("[exceptiontable: m=%p, code=%p, exceptiontable=%p, length=%d, method=",
166                           code->m, code, et, (et != NULL) ? et->length : 0);
167         method_print(code->m);
168         log_print("]");
169         log_finish();
170
171         if (et == NULL)
172                 return;
173
174         /* Iterate over all entries. */
175
176         for (i = 0, ete = et->entries; i < et->length; i++, ete++) {
177                 log_start();
178                 log_print("[exceptiontable entry %3d: startpc=%p, endpc=%p, handlerpc=%p, catchtype=%p (",
179                                   i, ete->startpc, ete->endpc, ete->handlerpc, ete->catchtype.any);
180
181                 if (ete->catchtype.any != NULL)
182                         if (IS_CLASSREF(ete->catchtype))
183                                 class_classref_print(ete->catchtype.ref);
184                         else
185                                 class_print(ete->catchtype.cls);
186                 else
187                         log_print("ANY");
188
189                 log_print(")]");
190                 log_finish();
191         }
192 }
193 #endif
194
195
196 /*
197  * These are local overrides for various environment variables in Emacs.
198  * Please do not remove this and leave it at the end of the file, where
199  * Emacs will automagically detect them.
200  * ---------------------------------------------------------------------
201  * Local variables:
202  * mode: c
203  * indent-tabs-mode: t
204  * c-basic-offset: 4
205  * tab-width: 4
206  * End:
207  * vim:noexpandtab:sw=4:ts=4:
208  */