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 8123 2007-06-20 23:50:55Z michi $
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_returntype_get *******************************************************
243 Get the return type of the method.
245 *******************************************************************************/
247 classinfo *method_returntype_get(methodinfo *m)
252 td = &(m->parseddesc->returntype);
254 if (!resolve_class_from_typedesc(td, true, false, &c))
261 /* method_count_implementations ************************************************
263 Count the implementations of a method in a class cone (a class and all its
267 m................the method to count
268 c................class at which to start the counting (this class and
269 all its subclasses will be searched)
272 *found...........if found != NULL, *found receives the method
273 implementation that was found. This value is only
274 meaningful if the return value is 1.
277 the number of implementations found
279 *******************************************************************************/
281 s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
291 mend = mp + c->methodscount;
293 for (; mp < mend; ++mp) {
294 if (method_canoverwrite(mp, m)) {
302 for (child = c->sub; child != NULL; child = child->nextsub) {
303 count += method_count_implementations(m, child, found);
310 /* method_add_to_worklist ******************************************************
312 Add the method to the given worklist. If the method already occurs in
313 the worklist, the worklist remains unchanged.
315 *******************************************************************************/
317 static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
321 for (wi = *wl; wi != NULL; wi = wi->next)
325 wi = NEW(method_worklist);
333 /* method_add_assumption_monomorphic *******************************************
335 Record the assumption that the method is monomorphic.
338 m.................the method
339 caller............the caller making the assumption
341 *******************************************************************************/
343 void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
345 method_assumption *as;
347 /* XXX LOCKING FOR THIS FUNCTION? */
349 /* check if we already have registered this assumption */
351 for (as = m->assumptions; as != NULL; as = as->next) {
352 if (as->context == caller)
356 /* register the assumption */
358 as = NEW(method_assumption);
359 as->next = m->assumptions;
360 as->context = caller;
366 /* method_break_assumption_monomorphic *****************************************
368 Break the assumption that this method is monomorphic. All callers that
369 have registered this assumption are added to the worklist.
372 m.................the method
373 wl................worklist where to add invalidated callers
375 *******************************************************************************/
377 void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
379 method_assumption *as;
381 /* XXX LOCKING FOR THIS FUNCTION? */
383 for (as = m->assumptions; as != NULL; as = as->next) {
385 printf("ASSUMPTION BROKEN (monomorphism): ");
388 method_println(as->context);
391 method_add_to_worklist(as->context, wl);
396 /* method_printflags ***********************************************************
398 Prints the flags of a method to stdout like.
400 *******************************************************************************/
403 void method_printflags(methodinfo *m)
410 if (m->flags & ACC_PUBLIC) printf(" PUBLIC");
411 if (m->flags & ACC_PRIVATE) printf(" PRIVATE");
412 if (m->flags & ACC_PROTECTED) printf(" PROTECTED");
413 if (m->flags & ACC_STATIC) printf(" STATIC");
414 if (m->flags & ACC_FINAL) printf(" FINAL");
415 if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
416 if (m->flags & ACC_VOLATILE) printf(" VOLATILE");
417 if (m->flags & ACC_TRANSIENT) printf(" TRANSIENT");
418 if (m->flags & ACC_NATIVE) printf(" NATIVE");
419 if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
420 if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
421 if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
422 if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
424 #endif /* !defined(NDEBUG) */
427 /* method_print ****************************************************************
429 Prints a method to stdout like:
431 java.lang.Object.<init>()V
433 *******************************************************************************/
436 void method_print(methodinfo *m)
443 utf_display_printable_ascii_classname(m->class->name);
445 utf_display_printable_ascii(m->name);
446 utf_display_printable_ascii(m->descriptor);
448 method_printflags(m);
450 #endif /* !defined(NDEBUG) */
453 /* method_println **************************************************************
455 Prints a method plus new line to stdout like:
457 java.lang.Object.<init>()V
459 *******************************************************************************/
462 void method_println(methodinfo *m)
464 if (opt_debugcolor) printf("\033[31m"); /* red */
466 if (opt_debugcolor) printf("\033[m");
469 #endif /* !defined(NDEBUG) */
472 /* method_methodref_print ******************************************************
474 Prints a method reference to stdout.
476 *******************************************************************************/
479 void method_methodref_print(constant_FMIref *mr)
482 printf("(constant_FMIref *)NULL");
486 if (IS_FMIREF_RESOLVED(mr)) {
488 method_print(mr->p.method);
491 printf("<methodref> ");
492 utf_display_printable_ascii_classname(mr->p.classref->name);
494 utf_display_printable_ascii(mr->name);
495 utf_display_printable_ascii(mr->descriptor);
498 #endif /* !defined(NDEBUG) */
501 /* method_methodref_println ****************************************************
503 Prints a method reference to stdout, followed by a newline.
505 *******************************************************************************/
508 void method_methodref_println(constant_FMIref *mr)
510 method_methodref_print(mr);
513 #endif /* !defined(NDEBUG) */
517 * These are local overrides for various environment variables in Emacs.
518 * Please do not remove this and leave it at the end of the file, where
519 * Emacs will automagically detect them.
520 * ---------------------------------------------------------------------
523 * indent-tabs-mode: t
527 * vim:noexpandtab:sw=4:ts=4: