* src/vm/jit/parse.c (ICMD_CHECKNULL): Use OP_CHECK_EXCEPTION.
[cacao.git] / src / vm / method.c
index 78793b8a56031938ded0f5d54f57418e95ae182c..53ccb6dd141db0d28c285e6b4b735f3fb3321b63 100644 (file)
@@ -32,7 +32,7 @@
             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.
@@ -64,11 +73,10 @@ void method_free(methodinfo *m)
        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) {
@@ -117,6 +125,7 @@ methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
        methodptr   mptr;
        methodptr  *pmptr;
        methodinfo *resm;                   /* pointer to new resolved method     */
+       codeinfo   *code;
 
        /* If the method is not an instance method, just return it. */
 
@@ -131,19 +140,107 @@ methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
        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.
@@ -169,6 +266,8 @@ void method_printflags(methodinfo *m)
        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) */
 
@@ -189,10 +288,10 @@ void method_print(methodinfo *m)
                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);
 }
@@ -210,7 +309,53 @@ void method_print(methodinfo *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) */
@@ -227,4 +372,5 @@ void method_println(methodinfo *m)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */