Merged with tip.
[cacao.git] / src / vm / jit / emit-common.c
index 243109adc6b2754a6c65a1b6fc428d252d8094de..3a167808265e151f477303cf419a2c7c6c4be292 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/emit-common.c - common code emitter functions
 
-   Copyright (C) 2006, 2007 R. Grafl, A. Krall, C. Kruegel, C. Oates,
-   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
-   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
-   Institut f. Computersprachen - TU Wien
+   Copyright (C) 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 
 #include "vm/types.h"
 
@@ -38,6 +35,7 @@
 
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/patcher-common.h"
 
 #include "vmcore/options.h"
 #include "vmcore/statistics.h"
@@ -247,6 +245,53 @@ void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
 }
 
 
+/* emit_patcher_traps **********************************************************
+
+   Generates the code for the patcher traps.
+
+*******************************************************************************/
+
+void emit_patcher_traps(jitdata *jd)
+{
+       codegendata *cd;
+       codeinfo    *code;
+       patchref_t  *pr;
+       u1          *savedmcodeptr;
+       u1          *tmpmcodeptr;
+       uint32_t     mcode;
+
+       /* get required compiler data */
+
+       cd   = jd->cd;
+       code = jd->code;
+
+       /* generate patcher traps code */
+
+       for (pr = list_first(code->patchers); pr != NULL; pr = list_next(code->patchers, pr)) {
+
+               /* Calculate the patch position where the original machine
+                  code is located and the trap should be placed. */
+
+               tmpmcodeptr = (u1 *) (cd->mcodebase + pr->mpc);
+
+               /* Patch in the trap to call the signal handler (done at
+                  compile time). */
+
+               savedmcodeptr = cd->mcodeptr;   /* save current mcodeptr          */
+               cd->mcodeptr  = tmpmcodeptr;    /* set mcodeptr to patch position */
+
+               mcode = emit_trap(cd);
+
+               cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr   */
+
+               /* Remember the original machine code which is patched
+                  back in later (done at runtime). */
+
+               pr->mcode = mcode;
+       }
+}
+
+
 /* emit_bccz *******************************************************************
 
    Emit conditional and unconditional branch instructions on integer
@@ -270,6 +315,16 @@ void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 opt
                branchmpc = cd->mcodeptr - cd->mcodebase;
                disp      = target->mpc - branchmpc;
 
+#if defined(ENABLE_STATISTICS)
+               count_emit_branch++;
+               if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
+               else if ((int16_t)disp == disp) count_emit_branch_16bit++;
+               else if ((int32_t)disp == disp) count_emit_branch_32bit++;
+# if SIZEOF_VOID_P == 8
+               else if ((int64_t)disp == disp) count_emit_branch_64bit++;
+# endif
+#endif
+
                emit_branch(cd, disp, condition, reg, options);
        }
        else {
@@ -454,7 +509,7 @@ void emit_bnan(codegendata *cd, basicblock *target)
 
 void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
 {
-       list               *list;
+       list_t             *list;
        branch_label_ref_t *br;
        s4                  mpc;
        s4                  disp;
@@ -465,29 +520,14 @@ void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options
 
        /* search if the label is already in the list */
 
-       for (br = list_first_unsynced(list); br != NULL;
-                br = list_next_unsynced(list, br)) {
+       for (br = list_first(list); br != NULL; br = list_next(list, br)) {
                /* is this entry the correct label? */
 
                if (br->label == label)
                        break;
        }
 
-       /* a branch reference was found */
-
-       if (br != NULL) {
-               /* calculate the mpc of the branch instruction */
-
-               mpc  = cd->mcodeptr - cd->mcodebase;
-               disp = br->mpc - mpc;
-
-               emit_branch(cd, disp, condition, reg, options);
-
-               /* now remove the branch reference */
-
-               list_remove_unsynced(list, br);
-       }
-       else {
+       if (br == NULL) {
                /* current mcodeptr is the correct position,
                   afterwards emit the NOPs */
 
@@ -496,7 +536,31 @@ void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options
                /* generate NOPs as placeholder for branch code */
 
                BRANCH_NOPS;
+               return;
        }
+
+       /* Branch reference was found. */
+
+       /* calculate the mpc of the branch instruction */
+
+       mpc  = cd->mcodeptr - cd->mcodebase;
+       disp = br->mpc - mpc;
+
+#if defined(ENABLE_STATISTICS)
+       count_emit_branch++;
+       if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
+       else if ((int16_t)disp == disp) count_emit_branch_16bit++;
+       else if ((int32_t)disp == disp) count_emit_branch_32bit++;
+# if SIZEOF_VOID_P == 8
+       else if ((int64_t)disp == disp) count_emit_branch_64bit++;
+# endif
+#endif
+
+       emit_branch(cd, disp, condition, reg, options);
+
+       /* now remove the branch reference */
+
+       list_remove(list, br);
 }
 
 
@@ -509,7 +573,7 @@ void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options
 
 void emit_label(codegendata *cd, s4 label)
 {
-       list               *list;
+       list_t             *list;
        branch_label_ref_t *br;
        s4                  mpc;
        s4                  disp;
@@ -521,43 +585,52 @@ void emit_label(codegendata *cd, s4 label)
 
        /* search if the label is already in the list */
 
-       for (br = list_first_unsynced(list); br != NULL;
-                br = list_next_unsynced(list, br)) {
+       for (br = list_first(list); br != NULL; br = list_next(list, br)) {
                /* is this entry the correct label? */
 
                if (br->label == label)
                        break;
        }
 
-       /* a branch reference was found */
+       if (br == NULL) {
+               /* No branch reference found, add the label to the list (use
+                  invalid values for condition and register). */
 
-       if (br != NULL) {
-               /* calculate the mpc of the branch instruction */
+               codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
+               return;
+       }
+
+       /* Branch reference was found. */
 
-               mpc  = cd->mcodeptr - cd->mcodebase;
-               disp = mpc - br->mpc;
+       /* calculate the mpc of the branch instruction */
 
-               /* temporary set the mcodeptr */
+       mpc  = cd->mcodeptr - cd->mcodebase;
+       disp = mpc - br->mpc;
 
-               mcodeptr     = cd->mcodeptr;
-               cd->mcodeptr = cd->mcodebase + br->mpc;
+       /* temporary set the mcodeptr */
 
-               emit_branch(cd, disp, br->condition, br->reg, br->options);
+       mcodeptr     = cd->mcodeptr;
+       cd->mcodeptr = cd->mcodebase + br->mpc;
 
-               /* restore mcodeptr */
+#if defined(ENABLE_STATISTICS)
+       count_emit_branch++;
+       if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
+       else if ((int16_t)disp == disp) count_emit_branch_16bit++;
+       else if ((int32_t)disp == disp) count_emit_branch_32bit++;
+# if SIZEOF_VOID_P == 8
+       else if ((int64_t)disp == disp) count_emit_branch_64bit++;
+# endif
+#endif
 
-               cd->mcodeptr = mcodeptr;
+       emit_branch(cd, disp, br->condition, br->reg, br->options);
 
-               /* now remove the branch reference */
+       /* restore mcodeptr */
 
-               list_remove_unsynced(list, br);
-       }
-       else {
-               /* add the label to the list (use invalid values for condition
-                  and register) */
+       cd->mcodeptr = mcodeptr;
 
-               codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
-       }
+       /* now remove the branch reference */
+
+       list_remove(list, br);
 }