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 7573 2007-03-25 18:55:02Z twisti $
37 #include "mm/memory.h"
39 #include "vm/builtin.h"
40 #include "vm/global.h"
41 #include "vm/resolve.h"
43 #include "vm/jit/methodheader.h"
45 #include "vm/jit_interface.h"
47 #include "vmcore/class.h"
48 #include "vmcore/linker.h"
49 #include "vmcore/loader.h"
50 #include "vmcore/method.h"
51 #include "vmcore/options.h"
54 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
55 #define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0)
57 #define INLINELOG(code)
61 /* method_free *****************************************************************
63 Frees all memory that was allocated for this method.
65 *******************************************************************************/
67 void method_free(methodinfo *m)
70 MFREE(m->jcode, u1, m->jcodelength);
72 if (m->rawexceptiontable)
73 MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
75 code_free_code_of_method(m);
78 if (m->flags & ACC_NATIVE) {
79 removenativestub(m->stubroutine);
82 removecompilerstub(m->stubroutine);
88 /* method_canoverwrite *********************************************************
90 Check if m and old are identical with respect to type and
91 name. This means that old can be overwritten with m.
93 *******************************************************************************/
95 bool method_canoverwrite(methodinfo *m, methodinfo *old)
97 if (m->name != old->name)
100 if (m->descriptor != old->descriptor)
103 if (m->flags & ACC_STATIC)
110 /* method_vftbl_lookup *********************************************************
112 Does a method lookup in the passed virtual function table. This
113 function does exactly the same thing as JIT, but additionally
114 relies on the fact, that the methodinfo pointer is at the first
115 data segment slot (even for compiler stubs).
117 *******************************************************************************/
119 methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
123 methodinfo *resm; /* pointer to new resolved method */
125 /* If the method is not an instance method, just return it. */
127 if (m->flags & ACC_STATIC)
132 /* Get the method from the virtual function table. Is this an
135 if (m->class->flags & ACC_INTERFACE) {
136 pmptr = vftbl->interfacetable[-(m->class->index)];
137 mptr = pmptr[(m - m->class->methods)];
140 mptr = vftbl->table[m->vftblindex];
143 /* and now get the codeinfo pointer from the first data segment slot */
145 resm = code_get_methodinfo_for_pv(mptr);
151 /* method_get_parametertypearray ***********************************************
153 Use the descriptor of a method to generate a java.lang.Class array
154 which contains the classes of the parametertypes of the method.
156 This function is called by java.lang.reflect.{Constructor,Method}.
158 *******************************************************************************/
160 java_objectarray *method_get_parametertypearray(methodinfo *m)
163 typedesc *paramtypes;
165 java_objectarray *oa;
171 /* is the descriptor fully parsed? */
173 if (m->parseddesc->params == NULL)
174 if (!descriptor_params_from_paramtypes(md, m->flags))
177 paramtypes = md->paramtypes;
178 paramcount = md->paramcount;
180 /* skip `this' pointer */
182 if (!(m->flags & ACC_STATIC)) {
187 /* create class-array */
189 oa = builtin_anewarray(paramcount, class_java_lang_Class);
196 for (i = 0; i < paramcount; i++) {
197 if (!resolve_class_from_typedesc(¶mtypes[i], true, false, &c))
200 oa->data[i] = (java_objectheader *) c;
207 /* method_get_exceptionarray ***************************************************
209 Get the exceptions which can be thrown by a method.
211 *******************************************************************************/
213 java_objectarray *method_get_exceptionarray(methodinfo *m)
215 java_objectarray *oa;
219 /* create class-array */
221 oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
226 /* iterate over all exceptions and store the class in the array */
228 for (i = 0; i < m->thrownexceptionscount; i++) {
229 c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
234 oa->data[i] = (java_objectheader *) c;
241 /* method_count_implementations ************************************************
243 Count the implementations of a method in a class cone (a class and all its
247 m................the method to count
248 c................class at which to start the counting (this class and
249 all its subclasses will be searched)
252 *found...........if found != NULL, *found receives the method
253 implementation that was found. This value is only
254 meaningful if the return value is 1.
257 the number of implementations found
259 *******************************************************************************/
261 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
271 mend = mp + c->methodscount;
273 for (; mp < mend; ++mp) {
274 if (method_canoverwrite(mp, m)) {
282 for (child = c->sub; child != NULL; child = child->nextsub) {
283 count += method_count_implementations(m, child, found);
290 /* method_add_to_worklist ******************************************************
292 Add the method to the given worklist. If the method already occurs in
293 the worklist, the worklist remains unchanged.
295 *******************************************************************************/
297 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
301 for (wi = *wl; wi != NULL; wi = wi->next)
305 wi = NEW(method_worklist);
313 /* method_add_assumption_monomorphic *******************************************
315 Record the assumption that the method is monomorphic.
318 m.................the method
319 caller............the caller making the assumption
321 *******************************************************************************/
323 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
325 method_assumption *as;
327 /* XXX LOCKING FOR THIS FUNCTION? */
329 /* check if we already have registered this assumption */
331 for (as = m->assumptions; as != NULL; as = as->next) {
332 if (as->context == caller)
336 /* register the assumption */
338 as = NEW(method_assumption);
339 as->next = m->assumptions;
340 as->context = caller;
346 /* method_break_assumption_monomorphic *****************************************
348 Break the assumption that this method is monomorphic. All callers that
349 have registered this assumption are added to the worklist.
352 m.................the method
353 wl................worklist where to add invalidated callers
355 *******************************************************************************/
357 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
359 method_assumption *as;
361 /* XXX LOCKING FOR THIS FUNCTION? */
363 for (as = m->assumptions; as != NULL; as = as->next) {
365 printf("ASSUMPTION BROKEN (monomorphism): ");
368 method_println(as->context);
371 method_add_to_worklist(as->context, wl);
376 /* method_printflags ***********************************************************
378 Prints the flags of a method to stdout like.
380 *******************************************************************************/
383 void method_printflags(methodinfo *m)
390 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
391 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
392 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
393 if (m->flags & ACC_STATIC) printf(" STATIC");
394 if (m->flags & ACC_FINAL) printf(" FINAL");
395 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
396 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
397 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
398 if (m->flags & ACC_NATIVE) printf(" NATIVE");
399 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
400 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
401 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
402 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
404 #endif /* !defined(NDEBUG) */
407 /* method_print ****************************************************************
409 Prints a method to stdout like:
411 java.lang.Object.<init>()V
413 *******************************************************************************/
416 void method_print(methodinfo *m)
423 utf_display_printable_ascii_classname(m->class->name);
425 utf_display_printable_ascii(m->name);
426 utf_display_printable_ascii(m->descriptor);
428 method_printflags(m);
430 #endif /* !defined(NDEBUG) */
433 /* method_println **************************************************************
435 Prints a method plus new line to stdout like:
437 java.lang.Object.<init>()V
439 *******************************************************************************/
442 void method_println(methodinfo *m)
444 if (opt_debugcolor) printf("\033[31m"); /* red */
446 if (opt_debugcolor) printf("\033[m");
449 #endif /* !defined(NDEBUG) */
452 /* method_methodref_print ******************************************************
454 Prints a method reference to stdout.
456 *******************************************************************************/
459 void method_methodref_print(constant_FMIref *mr)
462 printf("(constant_FMIref *)NULL");
466 if (IS_FMIREF_RESOLVED(mr)) {
468 method_print(mr->p.method);
471 printf("<methodref> ");
472 utf_display_printable_ascii_classname(mr->p.classref->name);
474 utf_display_printable_ascii(mr->name);
475 utf_display_printable_ascii(mr->descriptor);
478 #endif /* !defined(NDEBUG) */
481 /* method_methodref_println ****************************************************
483 Prints a method reference to stdout, followed by a newline.
485 *******************************************************************************/
488 void method_methodref_println(constant_FMIref *mr)
490 method_methodref_print(mr);
493 #endif /* !defined(NDEBUG) */
497 * These are local overrides for various environment variables in Emacs.
498 * Please do not remove this and leave it at the end of the file, where
499 * Emacs will automagically detect them.
500 * ---------------------------------------------------------------------
503 * indent-tabs-mode: t
507 * vim:noexpandtab:sw=4:ts=4: