Edwin Steiner
Christian Thalinger
- $Id: method.c 4579 2006-03-11 15:01:35Z edwin $
+ $Id: method.c 5992 2006-11-15 22:46:10Z edwin $
*/
#include "vm/linker.h"
#include "vm/loader.h"
#include "vm/method.h"
+#include "vm/options.h"
#include "vm/jit/methodheader.h"
+#if !defined(NDEBUG) && defined(ENABLE_INLINING)
+extern bool inline_debug_log;
+#define INLINELOG(code) do { if (inline_debug_log) { code } } while (0)
+#else
+#define INLINELOG(code)
+#endif
+
+
/* method_free *****************************************************************
Frees all memory that was allocated for this method.
if (m->jcode)
MFREE(m->jcode, u1, m->jcodelength);
- if (m->exceptiontable)
- MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
+ if (m->rawexceptiontable)
+ MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
- if (m->mcode)
- CFREE((void *) (ptrint) m->mcode, m->mcodelength);
+ code_free_code_of_method(m);
if (m->stubroutine) {
if (m->flags & ACC_NATIVE) {
methodptr mptr;
methodptr *pmptr;
methodinfo *resm; /* pointer to new resolved method */
+ codeinfo *code;
/* If the method is not an instance method, just return it. */
if (m->class->flags & ACC_INTERFACE) {
pmptr = vftbl->interfacetable[-(m->class->index)];
mptr = pmptr[(m - m->class->methods)];
-
- } else {
+ }
+ else {
mptr = vftbl->table[m->vftblindex];
}
- /* and now get the methodinfo* from the first data segment slot */
+ /* and now get the codeinfo pointer from the first data segment slot */
+
+ code = *((codeinfo **) (mptr + CodeinfoPointer));
- resm = *((methodinfo **) (mptr + MethodPointer));
+ resm = code->m;
return resm;
}
+/* method_add_to_worklist ******************************************************
+
+ Add the method to the given worklist. If the method already occurs in
+ the worklist, the worklist remains unchanged.
+
+*******************************************************************************/
+
+static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
+{
+ method_worklist *wi;
+
+ for (wi = *wl; wi != NULL; wi = wi->next)
+ if (wi->m == m)
+ return;
+
+ wi = NEW(method_worklist);
+ wi->next = *wl;
+ wi->m = m;
+
+ *wl = wi;
+}
+
+
+/* method_add_assumption_monomorphic *******************************************
+
+ Record the assumption that the method is monomorphic.
+
+ IN:
+ m.................the method
+ caller............the caller making the assumption
+
+*******************************************************************************/
+
+void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
+{
+ method_assumption *as;
+
+ /* XXX LOCKING FOR THIS FUNCTION? */
+
+ /* check if we already have registered this assumption */
+
+ for (as = m->assumptions; as != NULL; as = as->next) {
+ if (as->context == caller)
+ return;
+ }
+
+ /* register the assumption */
+
+ as = NEW(method_assumption);
+ as->next = m->assumptions;
+ as->context = caller;
+
+ m->assumptions = as;
+}
+
+
+/* method_break_assumption_monomorphic *****************************************
+
+ Break the assumption that this method is monomorphic. All callers that
+ have registered this assumption are added to the worklist.
+
+ IN:
+ m.................the method
+ wl................worklist where to add invalidated callers
+
+*******************************************************************************/
+
+void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
+{
+ method_assumption *as;
+
+ /* XXX LOCKING FOR THIS FUNCTION? */
+
+ for (as = m->assumptions; as != NULL; as = as->next) {
+ INLINELOG(
+ printf("ASSUMPTION BROKEN (monomorphism): ");
+ method_print(m);
+ printf(" in ");
+ method_println(as->context);
+ );
+
+ method_add_to_worklist(as->context, wl);
+ }
+}
+
+
/* method_printflags ***********************************************************
Prints the flags of a method to stdout like.
if (m->flags & ACC_NATIVE) printf(" NATIVE");
if (m->flags & ACC_INTERFACE) printf(" INTERFACE");
if (m->flags & ACC_ABSTRACT) printf(" ABSTRACT");
+ if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
+ if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
}
#endif /* !defined(NDEBUG) */
return;
}
- utf_display_classname(m->class->name);
+ utf_display_printable_ascii_classname(m->class->name);
printf(".");
- utf_display(m->name);
- utf_display(m->descriptor);
+ utf_display_printable_ascii(m->name);
+ utf_display_printable_ascii(m->descriptor);
method_printflags(m);
}
#if !defined(NDEBUG)
void method_println(methodinfo *m)
{
+ if (opt_debugcolor) printf("\033[31m"); /* red */
method_print(m);
+ if (opt_debugcolor) printf("\033[m");
+ printf("\n");
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_methodref_print ******************************************************
+
+ Prints a method reference to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_methodref_print(constant_FMIref *mr)
+{
+ if (!mr) {
+ printf("(constant_FMIref *)NULL");
+ return;
+ }
+
+ if (IS_FMIREF_RESOLVED(mr)) {
+ printf("<method> ");
+ method_print(mr->p.method);
+ }
+ else {
+ printf("<methodref> ");
+ utf_display_printable_ascii_classname(mr->p.classref->name);
+ printf(".");
+ utf_display_printable_ascii(mr->name);
+ utf_display_printable_ascii(mr->descriptor);
+ }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_methodref_println ****************************************************
+
+ Prints a method reference to stdout, followed by a newline.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_methodref_println(constant_FMIref *mr)
+{
+ method_methodref_print(mr);
printf("\n");
}
#endif /* !defined(NDEBUG) */
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/