* Removed all Id tags.
[cacao.git] / src / vm / jit / patcher-common.c
index 38573277cc0a6a1f5ffd201c9831aeaacce9763f..7a91ce246f94800e11ad4fbadae1be9d801efc27 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id$
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 
 #include "codegen.h"                   /* for PATCHER_NOPS */
 
@@ -62,13 +61,13 @@ void patcher_list_create(codeinfo *code)
 }
 
 
-/* patcher_list_free ***********************************************************
+/* patcher_list_reset **********************************************************
 
    TODO
 
 *******************************************************************************/
 
-void patcher_list_free(codeinfo *code)
+void patcher_list_reset(codeinfo *code)
 {
        patchref_t *pr;
 
@@ -84,6 +83,19 @@ void patcher_list_free(codeinfo *code)
                        size_patchref -= sizeof(patchref_t);
 #endif
        }
+}
+
+/* patcher_list_free ***********************************************************
+
+   TODO
+
+*******************************************************************************/
+
+void patcher_list_free(codeinfo *code)
+{
+       /* free all elements of the list */
+
+       patcher_list_reset(code);
 
        /* free the list itself */
 
@@ -137,6 +149,11 @@ void patcher_add_patch_ref(jitdata *jd, functionptr patcher, voidptr ref,
     code     = jd->code;
     patchmpc = cd->mcodeptr - cd->mcodebase;
 
+#if !defined(NDEBUG)
+       if (patcher_list_find(code, (u1 *) (intptr_t) patchmpc) != NULL)
+               vm_abort("patcher_add_patch_ref: different patchers at same position.");
+#endif
+
     /* allocate patchref on heap (at least freed together with codeinfo) */
 
        pr = NEW(patchref_t);
@@ -169,12 +186,24 @@ void patcher_add_patch_ref(jitdata *jd, functionptr patcher, voidptr ref,
 
 *******************************************************************************/
 
-java_objectheader *patcher_handler(u1 *pc)
+/*#define TRACE_PATCHER*/
+
+#ifdef TRACE_PATCHER
+/* XXX this indent is not thread safe! */
+/* XXX if you want it thread safe, place patcher_depth in threadobject! */
+static int patcher_depth = 0;
+# define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
+#endif
+
+java_handle_t *patcher_handler(u1 *pc)
 {
-       codeinfo          *code;
-       patchref_t        *pr;
-       bool               result;
-       java_objectheader *e;
+       codeinfo      *code;
+       patchref_t    *pr;
+       bool           result;
+       java_handle_t *e;
+#ifdef TRACE_PATCHER
+       int            i;
+#endif
 
        /* define the patcher function */
 
@@ -198,10 +227,18 @@ java_objectheader *patcher_handler(u1 *pc)
 
        if (pr->done) {
                log_println("patcher_handler: double-patching detected!");
-               LOCK_MONITOR_ENTER(code->patchers);
+               LOCK_MONITOR_EXIT(code->patchers);
                return NULL;
        }
 
+#ifdef TRACE_PATCHER
+       TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf("\n");
+       TRACE_PATCHER_INDENT; printf("\texception program counter = %p\n", (void *) pr->mpc);
+       TRACE_PATCHER_INDENT; printf("\tmcodes before = "); for (i=0; i<5; i++) printf("0x%08x ", *((u4 *) pr->mpc + i)); printf("\n");
+       patcher_depth++;
+       assert(patcher_depth > 0);
+#endif
+
        /* cast the passed function to a patcher function */
 
        patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
@@ -210,6 +247,15 @@ java_objectheader *patcher_handler(u1 *pc)
 
        result = (patcher_function)(pr);
 
+#ifdef TRACE_PATCHER
+       assert(patcher_depth > 0);
+       patcher_depth--;
+       TRACE_PATCHER_INDENT; printf("\tmcodes after  = "); for (i=0; i<5; i++) printf("0x%08x ", *((u4 *) pr->mpc + i)); printf("\n");
+       if (result == false) {
+               TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
+       }
+#endif
+
        /* check for return value and exit accordingly */
 
        if (result == false) {