* src/vm/jit/sparc64/emit.c: Implemented trace enter/exit functions.
[cacao.git] / src / vm / method.c
1 /* src/vm/method.c - method functions
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: Reinhard Grafl
28
29    Changes: Andreas Krall
30             Roman Obermaiser
31             Mark Probst
32             Edwin Steiner
33             Christian Thalinger
34
35    $Id: method.c 5785 2006-10-15 22:25:54Z edwin $
36
37 */
38
39
40 #include "config.h"
41
42 #include <assert.h>
43 #include <stdio.h>
44
45 #include "vm/types.h"
46
47 #include "mm/memory.h"
48 #include "vm/class.h"
49 #include "vm/global.h"
50 #include "vm/linker.h"
51 #include "vm/loader.h"
52 #include "vm/method.h"
53 #include "vm/options.h"
54 #include "vm/jit/methodheader.h"
55
56
57 /* method_free *****************************************************************
58
59    Frees all memory that was allocated for this method.
60
61 *******************************************************************************/
62
63 void method_free(methodinfo *m)
64 {
65         if (m->jcode)
66                 MFREE(m->jcode, u1, m->jcodelength);
67
68         if (m->rawexceptiontable)
69                 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
70
71         code_free_code_of_method(m);
72
73         if (m->stubroutine) {
74                 if (m->flags & ACC_NATIVE) {
75                         removenativestub(m->stubroutine);
76
77                 } else {
78                         removecompilerstub(m->stubroutine);
79                 }
80         }
81 }
82
83
84 /* method_canoverwrite *********************************************************
85
86    Check if m and old are identical with respect to type and
87    name. This means that old can be overwritten with m.
88         
89 *******************************************************************************/
90
91 bool method_canoverwrite(methodinfo *m, methodinfo *old)
92 {
93         if (m->name != old->name)
94                 return false;
95
96         if (m->descriptor != old->descriptor)
97                 return false;
98
99         if (m->flags & ACC_STATIC)
100                 return false;
101
102         return true;
103 }
104
105
106 /* method_vftbl_lookup *********************************************************
107
108    Does a method lookup in the passed virtual function table.  This
109    function does exactly the same thing as JIT, but additionally
110    relies on the fact, that the methodinfo pointer is at the first
111    data segment slot (even for compiler stubs).
112
113 *******************************************************************************/
114
115 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
116 {
117         methodptr   mptr;
118         methodptr  *pmptr;
119         methodinfo *resm;                   /* pointer to new resolved method     */
120         codeinfo   *code;
121
122         /* If the method is not an instance method, just return it. */
123
124         if (m->flags & ACC_STATIC)
125                 return m;
126
127         assert(vftbl);
128
129         /* Get the method from the virtual function table.  Is this an
130            interface method? */
131
132         if (m->class->flags & ACC_INTERFACE) {
133                 pmptr = vftbl->interfacetable[-(m->class->index)];
134                 mptr  = pmptr[(m - m->class->methods)];
135         }
136         else {
137                 mptr = vftbl->table[m->vftblindex];
138         }
139
140         /* and now get the codeinfo pointer from the first data segment slot */
141
142         code = *((codeinfo **) (mptr + CodeinfoPointer));
143
144         resm = code->m;
145
146         return resm;
147 }
148
149
150 /* method_printflags ***********************************************************
151
152    Prints the flags of a method to stdout like.
153
154 *******************************************************************************/
155
156 #if !defined(NDEBUG)
157 void method_printflags(methodinfo *m)
158 {
159         if (m == NULL) {
160                 printf("NULL");
161                 return;
162         }
163
164         if (m->flags & ACC_PUBLIC)       printf(" PUBLIC");
165         if (m->flags & ACC_PRIVATE)      printf(" PRIVATE");
166         if (m->flags & ACC_PROTECTED)    printf(" PROTECTED");
167         if (m->flags & ACC_STATIC)       printf(" STATIC");
168         if (m->flags & ACC_FINAL)        printf(" FINAL");
169         if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
170         if (m->flags & ACC_VOLATILE)     printf(" VOLATILE");
171         if (m->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
172         if (m->flags & ACC_NATIVE)       printf(" NATIVE");
173         if (m->flags & ACC_INTERFACE)    printf(" INTERFACE");
174         if (m->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
175 }
176 #endif /* !defined(NDEBUG) */
177
178
179 /* method_print ****************************************************************
180
181    Prints a method to stdout like:
182
183    java.lang.Object.<init>()V
184
185 *******************************************************************************/
186
187 #if !defined(NDEBUG)
188 void method_print(methodinfo *m)
189 {
190         if (m == NULL) {
191                 printf("NULL");
192                 return;
193         }
194
195         utf_display_printable_ascii_classname(m->class->name);
196         printf(".");
197         utf_display_printable_ascii(m->name);
198         utf_display_printable_ascii(m->descriptor);
199
200         method_printflags(m);
201 }
202 #endif /* !defined(NDEBUG) */
203
204
205 /* method_println **************************************************************
206
207    Prints a method plus new line to stdout like:
208
209    java.lang.Object.<init>()V
210
211 *******************************************************************************/
212
213 #if !defined(NDEBUG)
214 void method_println(methodinfo *m)
215 {
216         if (opt_debugcolor) printf("\033[31m"); /* red */
217         method_print(m);
218         if (opt_debugcolor) printf("\033[m");   
219         printf("\n");
220 }
221 #endif /* !defined(NDEBUG) */
222
223
224 /* method_methodref_print ******************************************************
225
226    Prints a method reference to stdout.
227
228 *******************************************************************************/
229
230 #if !defined(NDEBUG)
231 void method_methodref_print(constant_FMIref *mr)
232 {
233         if (!mr) {
234                 printf("(constant_FMIref *)NULL");
235                 return;
236         }
237
238         if (IS_FMIREF_RESOLVED(mr)) {
239                 printf("<method> ");
240                 method_print(mr->p.method);
241         }
242         else {
243                 printf("<methodref> ");
244                 utf_display_printable_ascii_classname(mr->p.classref->name);
245                 printf(".");
246                 utf_display_printable_ascii(mr->name);
247                 utf_display_printable_ascii(mr->descriptor);
248         }
249 }
250 #endif /* !defined(NDEBUG) */
251
252
253 /* method_methodref_println ****************************************************
254
255    Prints a method reference to stdout, followed by a newline.
256
257 *******************************************************************************/
258
259 #if !defined(NDEBUG)
260 void method_methodref_println(constant_FMIref *mr)
261 {
262         method_methodref_print(mr);
263         printf("\n");
264 }
265 #endif /* !defined(NDEBUG) */
266
267
268 /*
269  * These are local overrides for various environment variables in Emacs.
270  * Please do not remove this and leave it at the end of the file, where
271  * Emacs will automagically detect them.
272  * ---------------------------------------------------------------------
273  * Local variables:
274  * mode: c
275  * indent-tabs-mode: t
276  * c-basic-offset: 4
277  * tab-width: 4
278  * End:
279  * vim:noexpandtab:sw=4:ts=4:
280  */