1 /* src/vm/method.c - method functions
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: Reinhard Grafl
29 Changes: Andreas Krall
35 $Id: method.c 5975 2006-11-12 15:33:16Z edwin $
47 #include "mm/memory.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"
57 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
58 extern bool inline_debug_log;
59 #define INLINELOG(code) do { if (inline_debug_log) { code } } while (0)
61 #define INLINELOG(code)
65 /* method_free *****************************************************************
67 Frees all memory that was allocated for this method.
69 *******************************************************************************/
71 void method_free(methodinfo *m)
74 MFREE(m->jcode, u1, m->jcodelength);
76 if (m->rawexceptiontable)
77 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
79 code_free_code_of_method(m);
82 if (m->flags & ACC_NATIVE) {
83 removenativestub(m->stubroutine);
86 removecompilerstub(m->stubroutine);
92 /* method_canoverwrite *********************************************************
94 Check if m and old are identical with respect to type and
95 name. This means that old can be overwritten with m.
97 *******************************************************************************/
99 bool method_canoverwrite(methodinfo *m, methodinfo *old)
101 if (m->name != old->name)
104 if (m->descriptor != old->descriptor)
107 if (m->flags & ACC_STATIC)
114 /* method_vftbl_lookup *********************************************************
116 Does a method lookup in the passed virtual function table. This
117 function does exactly the same thing as JIT, but additionally
118 relies on the fact, that the methodinfo pointer is at the first
119 data segment slot (even for compiler stubs).
121 *******************************************************************************/
123 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
127 methodinfo *resm; /* pointer to new resolved method */
130 /* If the method is not an instance method, just return it. */
132 if (m->flags & ACC_STATIC)
137 /* Get the method from the virtual function table. Is this an
140 if (m->class->flags & ACC_INTERFACE) {
141 pmptr = vftbl->interfacetable[-(m->class->index)];
142 mptr = pmptr[(m - m->class->methods)];
145 mptr = vftbl->table[m->vftblindex];
148 /* and now get the codeinfo pointer from the first data segment slot */
150 code = *((codeinfo **) (mptr + CodeinfoPointer));
158 /* method_add_to_worklist ******************************************************
160 Add the method to the given worklist. If the method already occurs in
161 the worklist, the worklist remains unchanged.
163 *******************************************************************************/
165 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
169 for (wi = *wl; wi != NULL; wi = wi->next)
173 wi = NEW(method_worklist);
181 /* method_add_assumption_monomorphic *******************************************
183 Record the assumption that the method is monomorphic.
186 m.................the method
187 caller............the caller making the assumption
189 *******************************************************************************/
191 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
193 method_assumption *as;
195 /* XXX LOCKING FOR THIS FUNCTION? */
197 /* check if we already have registered this assumption */
199 for (as = m->assumptions; as != NULL; as = as->next) {
200 if (as->context == caller)
204 /* register the assumption */
206 as = NEW(method_assumption);
207 as->next = m->assumptions;
208 as->context = caller;
214 /* method_break_assumption_monomorphic *****************************************
216 Break the assumption that this method is monomorphic. All callers that
217 have registered this assumption are added to the worklist.
220 m.................the method
221 wl................worklist where to add invalidated callers
223 *******************************************************************************/
225 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
227 method_assumption *as;
229 /* XXX LOCKING FOR THIS FUNCTION? */
231 for (as = m->assumptions; as != NULL; as = as->next) {
233 printf("ASSUMPTION BROKEN (monomorphism): ");
236 method_println(as->context);
239 method_add_to_worklist(as->context, wl);
244 /* method_printflags ***********************************************************
246 Prints the flags of a method to stdout like.
248 *******************************************************************************/
251 void method_printflags(methodinfo *m)
258 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
259 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
260 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
261 if (m->flags & ACC_STATIC) printf(" STATIC");
262 if (m->flags & ACC_FINAL) printf(" FINAL");
263 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
264 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
265 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
266 if (m->flags & ACC_NATIVE) printf(" NATIVE");
267 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
268 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
270 #endif /* !defined(NDEBUG) */
273 /* method_print ****************************************************************
275 Prints a method to stdout like:
277 java.lang.Object.<init>()V
279 *******************************************************************************/
282 void method_print(methodinfo *m)
289 utf_display_printable_ascii_classname(m->class->name);
291 utf_display_printable_ascii(m->name);
292 utf_display_printable_ascii(m->descriptor);
294 method_printflags(m);
296 #endif /* !defined(NDEBUG) */
299 /* method_println **************************************************************
301 Prints a method plus new line to stdout like:
303 java.lang.Object.<init>()V
305 *******************************************************************************/
308 void method_println(methodinfo *m)
310 if (opt_debugcolor) printf("\033[31m"); /* red */
312 if (opt_debugcolor) printf("\033[m");
315 #endif /* !defined(NDEBUG) */
318 /* method_methodref_print ******************************************************
320 Prints a method reference to stdout.
322 *******************************************************************************/
325 void method_methodref_print(constant_FMIref *mr)
328 printf("(constant_FMIref *)NULL");
332 if (IS_FMIREF_RESOLVED(mr)) {
334 method_print(mr->p.method);
337 printf("<methodref> ");
338 utf_display_printable_ascii_classname(mr->p.classref->name);
340 utf_display_printable_ascii(mr->name);
341 utf_display_printable_ascii(mr->descriptor);
344 #endif /* !defined(NDEBUG) */
347 /* method_methodref_println ****************************************************
349 Prints a method reference to stdout, followed by a newline.
351 *******************************************************************************/
354 void method_methodref_println(constant_FMIref *mr)
356 method_methodref_print(mr);
359 #endif /* !defined(NDEBUG) */
363 * These are local overrides for various environment variables in Emacs.
364 * Please do not remove this and leave it at the end of the file, where
365 * Emacs will automagically detect them.
366 * ---------------------------------------------------------------------
369 * indent-tabs-mode: t
373 * vim:noexpandtab:sw=4:ts=4: