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 7228 2007-01-19 01:13:48Z 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 #define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0)
60 #define INLINELOG(code)
64 /* method_free *****************************************************************
66 Frees all memory that was allocated for this method.
68 *******************************************************************************/
70 void method_free(methodinfo *m)
73 MFREE(m->jcode, u1, m->jcodelength);
75 if (m->rawexceptiontable)
76 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
78 code_free_code_of_method(m);
81 if (m->flags & ACC_NATIVE) {
82 removenativestub(m->stubroutine);
85 removecompilerstub(m->stubroutine);
91 /* method_canoverwrite *********************************************************
93 Check if m and old are identical with respect to type and
94 name. This means that old can be overwritten with m.
96 *******************************************************************************/
98 bool method_canoverwrite(methodinfo *m, methodinfo *old)
100 if (m->name != old->name)
103 if (m->descriptor != old->descriptor)
106 if (m->flags & ACC_STATIC)
113 /* method_vftbl_lookup *********************************************************
115 Does a method lookup in the passed virtual function table. This
116 function does exactly the same thing as JIT, but additionally
117 relies on the fact, that the methodinfo pointer is at the first
118 data segment slot (even for compiler stubs).
120 *******************************************************************************/
122 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
126 methodinfo *resm; /* pointer to new resolved method */
129 /* If the method is not an instance method, just return it. */
131 if (m->flags & ACC_STATIC)
136 /* Get the method from the virtual function table. Is this an
139 if (m->class->flags & ACC_INTERFACE) {
140 pmptr = vftbl->interfacetable[-(m->class->index)];
141 mptr = pmptr[(m - m->class->methods)];
144 mptr = vftbl->table[m->vftblindex];
147 /* and now get the codeinfo pointer from the first data segment slot */
149 code = *((codeinfo **) (mptr + CodeinfoPointer));
157 /* method_count_implementations ************************************************
159 Count the implementations of a method in a class cone (a class and all its
163 m................the method to count
164 c................class at which to start the counting (this class and
165 all its subclasses will be searched)
168 *found...........if found != NULL, *found receives the method
169 implementation that was found. This value is only
170 meaningful if the return value is 1.
173 the number of implementations found
175 *******************************************************************************/
177 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
187 mend = mp + c->methodscount;
189 for (; mp < mend; ++mp) {
190 if (method_canoverwrite(mp, m)) {
198 for (child = c->sub; child != NULL; child = child->nextsub) {
199 count += method_count_implementations(m, child, found);
206 /* method_add_to_worklist ******************************************************
208 Add the method to the given worklist. If the method already occurs in
209 the worklist, the worklist remains unchanged.
211 *******************************************************************************/
213 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
217 for (wi = *wl; wi != NULL; wi = wi->next)
221 wi = NEW(method_worklist);
229 /* method_add_assumption_monomorphic *******************************************
231 Record the assumption that the method is monomorphic.
234 m.................the method
235 caller............the caller making the assumption
237 *******************************************************************************/
239 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
241 method_assumption *as;
243 /* XXX LOCKING FOR THIS FUNCTION? */
245 /* check if we already have registered this assumption */
247 for (as = m->assumptions; as != NULL; as = as->next) {
248 if (as->context == caller)
252 /* register the assumption */
254 as = NEW(method_assumption);
255 as->next = m->assumptions;
256 as->context = caller;
262 /* method_break_assumption_monomorphic *****************************************
264 Break the assumption that this method is monomorphic. All callers that
265 have registered this assumption are added to the worklist.
268 m.................the method
269 wl................worklist where to add invalidated callers
271 *******************************************************************************/
273 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
275 method_assumption *as;
277 /* XXX LOCKING FOR THIS FUNCTION? */
279 for (as = m->assumptions; as != NULL; as = as->next) {
281 printf("ASSUMPTION BROKEN (monomorphism): ");
284 method_println(as->context);
287 method_add_to_worklist(as->context, wl);
292 /* method_printflags ***********************************************************
294 Prints the flags of a method to stdout like.
296 *******************************************************************************/
299 void method_printflags(methodinfo *m)
306 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
307 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
308 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
309 if (m->flags & ACC_STATIC) printf(" STATIC");
310 if (m->flags & ACC_FINAL) printf(" FINAL");
311 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
312 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
313 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
314 if (m->flags & ACC_NATIVE) printf(" NATIVE");
315 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
316 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
317 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
318 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
320 #endif /* !defined(NDEBUG) */
323 /* method_print ****************************************************************
325 Prints a method to stdout like:
327 java.lang.Object.<init>()V
329 *******************************************************************************/
332 void method_print(methodinfo *m)
339 utf_display_printable_ascii_classname(m->class->name);
341 utf_display_printable_ascii(m->name);
342 utf_display_printable_ascii(m->descriptor);
344 method_printflags(m);
346 #endif /* !defined(NDEBUG) */
349 /* method_println **************************************************************
351 Prints a method plus new line to stdout like:
353 java.lang.Object.<init>()V
355 *******************************************************************************/
358 void method_println(methodinfo *m)
360 if (opt_debugcolor) printf("\033[31m"); /* red */
362 if (opt_debugcolor) printf("\033[m");
365 #endif /* !defined(NDEBUG) */
368 /* method_methodref_print ******************************************************
370 Prints a method reference to stdout.
372 *******************************************************************************/
375 void method_methodref_print(constant_FMIref *mr)
378 printf("(constant_FMIref *)NULL");
382 if (IS_FMIREF_RESOLVED(mr)) {
384 method_print(mr->p.method);
387 printf("<methodref> ");
388 utf_display_printable_ascii_classname(mr->p.classref->name);
390 utf_display_printable_ascii(mr->name);
391 utf_display_printable_ascii(mr->descriptor);
394 #endif /* !defined(NDEBUG) */
397 /* method_methodref_println ****************************************************
399 Prints a method reference to stdout, followed by a newline.
401 *******************************************************************************/
404 void method_methodref_println(constant_FMIref *mr)
406 method_methodref_print(mr);
409 #endif /* !defined(NDEBUG) */
413 * These are local overrides for various environment variables in Emacs.
414 * Please do not remove this and leave it at the end of the file, where
415 * Emacs will automagically detect them.
416 * ---------------------------------------------------------------------
419 * indent-tabs-mode: t
423 * vim:noexpandtab:sw=4:ts=4: