1 /* src/vmcore/method.c - method functions
3 Copyright (C) 1996-2005, 2006, 2007 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 $Id: method.c 7483 2007-03-08 13:17:40Z michi $
37 #include "mm/memory.h"
39 #include "vm/global.h"
41 #include "vm/jit/methodheader.h"
43 #include "vm/jit_interface.h"
45 #include "vmcore/class.h"
46 #include "vmcore/linker.h"
47 #include "vmcore/loader.h"
48 #include "vmcore/method.h"
49 #include "vmcore/options.h"
52 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
53 #define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0)
55 #define INLINELOG(code)
59 /* method_free *****************************************************************
61 Frees all memory that was allocated for this method.
63 *******************************************************************************/
65 void method_free(methodinfo *m)
68 MFREE(m->jcode, u1, m->jcodelength);
70 if (m->rawexceptiontable)
71 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
73 code_free_code_of_method(m);
76 if (m->flags & ACC_NATIVE) {
77 removenativestub(m->stubroutine);
80 removecompilerstub(m->stubroutine);
86 /* method_canoverwrite *********************************************************
88 Check if m and old are identical with respect to type and
89 name. This means that old can be overwritten with m.
91 *******************************************************************************/
93 bool method_canoverwrite(methodinfo *m, methodinfo *old)
95 if (m->name != old->name)
98 if (m->descriptor != old->descriptor)
101 if (m->flags & ACC_STATIC)
108 /* method_vftbl_lookup *********************************************************
110 Does a method lookup in the passed virtual function table. This
111 function does exactly the same thing as JIT, but additionally
112 relies on the fact, that the methodinfo pointer is at the first
113 data segment slot (even for compiler stubs).
115 *******************************************************************************/
117 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
121 methodinfo *resm; /* pointer to new resolved method */
123 /* If the method is not an instance method, just return it. */
125 if (m->flags & ACC_STATIC)
130 /* Get the method from the virtual function table. Is this an
133 if (m->class->flags & ACC_INTERFACE) {
134 pmptr = vftbl->interfacetable[-(m->class->index)];
135 mptr = pmptr[(m - m->class->methods)];
138 mptr = vftbl->table[m->vftblindex];
141 /* and now get the codeinfo pointer from the first data segment slot */
143 resm = code_get_methodinfo_for_pv(mptr);
149 /* method_count_implementations ************************************************
151 Count the implementations of a method in a class cone (a class and all its
155 m................the method to count
156 c................class at which to start the counting (this class and
157 all its subclasses will be searched)
160 *found...........if found != NULL, *found receives the method
161 implementation that was found. This value is only
162 meaningful if the return value is 1.
165 the number of implementations found
167 *******************************************************************************/
169 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
179 mend = mp + c->methodscount;
181 for (; mp < mend; ++mp) {
182 if (method_canoverwrite(mp, m)) {
190 for (child = c->sub; child != NULL; child = child->nextsub) {
191 count += method_count_implementations(m, child, found);
198 /* method_add_to_worklist ******************************************************
200 Add the method to the given worklist. If the method already occurs in
201 the worklist, the worklist remains unchanged.
203 *******************************************************************************/
205 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
209 for (wi = *wl; wi != NULL; wi = wi->next)
213 wi = NEW(method_worklist);
221 /* method_add_assumption_monomorphic *******************************************
223 Record the assumption that the method is monomorphic.
226 m.................the method
227 caller............the caller making the assumption
229 *******************************************************************************/
231 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
233 method_assumption *as;
235 /* XXX LOCKING FOR THIS FUNCTION? */
237 /* check if we already have registered this assumption */
239 for (as = m->assumptions; as != NULL; as = as->next) {
240 if (as->context == caller)
244 /* register the assumption */
246 as = NEW(method_assumption);
247 as->next = m->assumptions;
248 as->context = caller;
254 /* method_break_assumption_monomorphic *****************************************
256 Break the assumption that this method is monomorphic. All callers that
257 have registered this assumption are added to the worklist.
260 m.................the method
261 wl................worklist where to add invalidated callers
263 *******************************************************************************/
265 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
267 method_assumption *as;
269 /* XXX LOCKING FOR THIS FUNCTION? */
271 for (as = m->assumptions; as != NULL; as = as->next) {
273 printf("ASSUMPTION BROKEN (monomorphism): ");
276 method_println(as->context);
279 method_add_to_worklist(as->context, wl);
284 /* method_printflags ***********************************************************
286 Prints the flags of a method to stdout like.
288 *******************************************************************************/
291 void method_printflags(methodinfo *m)
298 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
299 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
300 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
301 if (m->flags & ACC_STATIC) printf(" STATIC");
302 if (m->flags & ACC_FINAL) printf(" FINAL");
303 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
304 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
305 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
306 if (m->flags & ACC_NATIVE) printf(" NATIVE");
307 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
308 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
309 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
310 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
312 #endif /* !defined(NDEBUG) */
315 /* method_print ****************************************************************
317 Prints a method to stdout like:
319 java.lang.Object.<init>()V
321 *******************************************************************************/
324 void method_print(methodinfo *m)
331 utf_display_printable_ascii_classname(m->class->name);
333 utf_display_printable_ascii(m->name);
334 utf_display_printable_ascii(m->descriptor);
336 method_printflags(m);
338 #endif /* !defined(NDEBUG) */
341 /* method_println **************************************************************
343 Prints a method plus new line to stdout like:
345 java.lang.Object.<init>()V
347 *******************************************************************************/
350 void method_println(methodinfo *m)
352 if (opt_debugcolor) printf("\033[31m"); /* red */
354 if (opt_debugcolor) printf("\033[m");
357 #endif /* !defined(NDEBUG) */
360 /* method_methodref_print ******************************************************
362 Prints a method reference to stdout.
364 *******************************************************************************/
367 void method_methodref_print(constant_FMIref *mr)
370 printf("(constant_FMIref *)NULL");
374 if (IS_FMIREF_RESOLVED(mr)) {
376 method_print(mr->p.method);
379 printf("<methodref> ");
380 utf_display_printable_ascii_classname(mr->p.classref->name);
382 utf_display_printable_ascii(mr->name);
383 utf_display_printable_ascii(mr->descriptor);
386 #endif /* !defined(NDEBUG) */
389 /* method_methodref_println ****************************************************
391 Prints a method reference to stdout, followed by a newline.
393 *******************************************************************************/
396 void method_methodref_println(constant_FMIref *mr)
398 method_methodref_print(mr);
401 #endif /* !defined(NDEBUG) */
405 * These are local overrides for various environment variables in Emacs.
406 * Please do not remove this and leave it at the end of the file, where
407 * Emacs will automagically detect them.
408 * ---------------------------------------------------------------------
411 * indent-tabs-mode: t
415 * vim:noexpandtab:sw=4:ts=4: