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 7246 2007-01-29 18:49:05Z twisti $
37 #include "mm/memory.h"
39 #include "vm/global.h"
41 #include "vm/jit/methodheader.h"
43 #include "vmcore/class.h"
44 #include "vmcore/linker.h"
45 #include "vmcore/loader.h"
46 #include "vmcore/method.h"
47 #include "vmcore/options.h"
50 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
51 extern bool inline_debug_log;
52 #define INLINELOG(code) do { if (inline_debug_log) { code } } while (0)
54 #define INLINELOG(code)
58 /* method_free *****************************************************************
60 Frees all memory that was allocated for this method.
62 *******************************************************************************/
64 void method_free(methodinfo *m)
67 MFREE(m->jcode, u1, m->jcodelength);
69 if (m->rawexceptiontable)
70 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
72 code_free_code_of_method(m);
75 if (m->flags & ACC_NATIVE) {
76 removenativestub(m->stubroutine);
79 removecompilerstub(m->stubroutine);
85 /* method_canoverwrite *********************************************************
87 Check if m and old are identical with respect to type and
88 name. This means that old can be overwritten with m.
90 *******************************************************************************/
92 bool method_canoverwrite(methodinfo *m, methodinfo *old)
94 if (m->name != old->name)
97 if (m->descriptor != old->descriptor)
100 if (m->flags & ACC_STATIC)
107 /* method_vftbl_lookup *********************************************************
109 Does a method lookup in the passed virtual function table. This
110 function does exactly the same thing as JIT, but additionally
111 relies on the fact, that the methodinfo pointer is at the first
112 data segment slot (even for compiler stubs).
114 *******************************************************************************/
116 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
120 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 code = *((codeinfo **) (mptr + CodeinfoPointer));
151 /* method_count_implementations ************************************************
153 Count the implementations of a method in a class cone (a class and all its
157 m................the method to count
158 c................class at which to start the counting (this class and
159 all its subclasses will be searched)
162 *found...........if found != NULL, *found receives the method
163 implementation that was found. This value is only
164 meaningful if the return value is 1.
167 the number of implementations found
169 *******************************************************************************/
171 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
181 mend = mp + c->methodscount;
183 for (; mp < mend; ++mp) {
184 if (method_canoverwrite(mp, m)) {
192 for (child = c->sub; child != NULL; child = child->nextsub) {
193 count += method_count_implementations(m, child, found);
200 /* method_add_to_worklist ******************************************************
202 Add the method to the given worklist. If the method already occurs in
203 the worklist, the worklist remains unchanged.
205 *******************************************************************************/
207 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
211 for (wi = *wl; wi != NULL; wi = wi->next)
215 wi = NEW(method_worklist);
223 /* method_add_assumption_monomorphic *******************************************
225 Record the assumption that the method is monomorphic.
228 m.................the method
229 caller............the caller making the assumption
231 *******************************************************************************/
233 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
235 method_assumption *as;
237 /* XXX LOCKING FOR THIS FUNCTION? */
239 /* check if we already have registered this assumption */
241 for (as = m->assumptions; as != NULL; as = as->next) {
242 if (as->context == caller)
246 /* register the assumption */
248 as = NEW(method_assumption);
249 as->next = m->assumptions;
250 as->context = caller;
256 /* method_break_assumption_monomorphic *****************************************
258 Break the assumption that this method is monomorphic. All callers that
259 have registered this assumption are added to the worklist.
262 m.................the method
263 wl................worklist where to add invalidated callers
265 *******************************************************************************/
267 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
269 method_assumption *as;
271 /* XXX LOCKING FOR THIS FUNCTION? */
273 for (as = m->assumptions; as != NULL; as = as->next) {
275 printf("ASSUMPTION BROKEN (monomorphism): ");
278 method_println(as->context);
281 method_add_to_worklist(as->context, wl);
286 /* method_printflags ***********************************************************
288 Prints the flags of a method to stdout like.
290 *******************************************************************************/
293 void method_printflags(methodinfo *m)
300 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
301 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
302 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
303 if (m->flags & ACC_STATIC) printf(" STATIC");
304 if (m->flags & ACC_FINAL) printf(" FINAL");
305 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
306 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
307 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
308 if (m->flags & ACC_NATIVE) printf(" NATIVE");
309 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
310 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
311 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
312 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
314 #endif /* !defined(NDEBUG) */
317 /* method_print ****************************************************************
319 Prints a method to stdout like:
321 java.lang.Object.<init>()V
323 *******************************************************************************/
326 void method_print(methodinfo *m)
333 utf_display_printable_ascii_classname(m->class->name);
335 utf_display_printable_ascii(m->name);
336 utf_display_printable_ascii(m->descriptor);
338 method_printflags(m);
340 #endif /* !defined(NDEBUG) */
343 /* method_println **************************************************************
345 Prints a method plus new line to stdout like:
347 java.lang.Object.<init>()V
349 *******************************************************************************/
352 void method_println(methodinfo *m)
354 if (opt_debugcolor) printf("\033[31m"); /* red */
356 if (opt_debugcolor) printf("\033[m");
359 #endif /* !defined(NDEBUG) */
362 /* method_methodref_print ******************************************************
364 Prints a method reference to stdout.
366 *******************************************************************************/
369 void method_methodref_print(constant_FMIref *mr)
372 printf("(constant_FMIref *)NULL");
376 if (IS_FMIREF_RESOLVED(mr)) {
378 method_print(mr->p.method);
381 printf("<methodref> ");
382 utf_display_printable_ascii_classname(mr->p.classref->name);
384 utf_display_printable_ascii(mr->name);
385 utf_display_printable_ascii(mr->descriptor);
388 #endif /* !defined(NDEBUG) */
391 /* method_methodref_println ****************************************************
393 Prints a method reference to stdout, followed by a newline.
395 *******************************************************************************/
398 void method_methodref_println(constant_FMIref *mr)
400 method_methodref_print(mr);
403 #endif /* !defined(NDEBUG) */
407 * These are local overrides for various environment variables in Emacs.
408 * Please do not remove this and leave it at the end of the file, where
409 * Emacs will automagically detect them.
410 * ---------------------------------------------------------------------
413 * indent-tabs-mode: t
417 * vim:noexpandtab:sw=4:ts=4: