* Removed all Id tags.
[cacao.git] / src / vm / jit / codegen-common.c
index 508b7265f2cd91930090b458993fdacac51abffb..aa7a158fea7f967b7691fe73183e8e0bee8017fd 100644 (file)
@@ -39,8 +39,6 @@
    memory. All functions writing values into the data area return the offset
    relative the begin of the code area (start of procedure).   
 
-   $Id: codegen-common.c 8006 2007-06-05 07:40:49Z twisti $
-
 */
 
 
 # include "codegen.h"
 #endif
 
-#if defined(__ARM__)
-/* this is required for REG_SPLIT */
-# include "md-abi.h"
-#endif
-
 #include "mm/memory.h"
 
 #include "toolbox/avl.h"
@@ -68,6 +61,7 @@
 #include "toolbox/logging.h"
 
 #include "native/jni.h"
+#include "native/localref.h"
 #include "native/native.h"
 
 #include "threads/threads-common.h"
@@ -87,6 +81,7 @@
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/md.h"
+#include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 #if defined(ENABLE_SSA)
 # include "vm/jit/optimizing/lsra.h"
@@ -268,6 +263,11 @@ static void codegen_reset(jitdata *jd)
                bptr->branchrefs = NULL;
        }
 
+       /* We need to clear all the patcher references from the codeinfo
+          since they all will be regenerated */
+
+       patcher_list_reset(code);
+
 #if defined(ENABLE_REPLACEMENT)
        code->rplpoints     = NULL;
        code->rplpointcount = 0;
@@ -379,7 +379,8 @@ void codegen_increase(codegendata *cd)
 
        cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
 
-#if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP)
+#if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
+ || defined(__SPARC_64__)
        /* adjust the pointer to the last patcher position */
 
        if (cd->lastmcodeptr != NULL)
@@ -549,15 +550,8 @@ void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref,
        if (opt_shownops)
                PATCHER_NOPS;
 
-       /* If the codegen provides a PACHER_LONGBRANCHES_NOPS macro, honour it. */
-
-#if defined(PATCHER_LONGBRANCHES_NOPS)
-       if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
-               PATCHER_LONGBRANCHES_NOPS;
-       }
-#endif
-
-#if defined(ENABLE_JIT) && (defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__))
+#if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__MIPS__) \
+ || defined(__SPARC_64__) || defined(__X86_64__))
 
        /* On some architectures the patcher stub call instruction might
           be longer than the actual instruction generated.  On this
@@ -836,6 +830,7 @@ u1 *codegen_get_pv_from_pc(u1 *pc)
                log_println("PC=0x%08x", pc);
 #endif
                log_println("");
+               assert(0);
                log_println("Dumping the current stacktrace:");
 
 #if defined(ENABLE_THREADS)
@@ -947,6 +942,7 @@ void codegen_finish(jitdata *jd)
 #endif
        s4           alignedmcodelen;
        jumpref     *jr;
+       patchref_t  *pr;
        u1          *epoint;
        s4           alignedlen;
 
@@ -1066,14 +1062,21 @@ void codegen_finish(jitdata *jd)
                *((ptrint *) ((ptrint) epoint + cd->linenumbertablesizepos)) = lrtlen;
        }
 
+       /* patcher resolving */
+
+       pr = list_first_unsynced(code->patchers);
+       while (pr) {
+               pr->mpc += (ptrint) epoint;
+               pr->datap = (ptrint) (pr->disp + epoint);
+               pr = list_next_unsynced(code->patchers, pr);
+       }
+
 #if defined(ENABLE_REPLACEMENT)
        /* replacement point resolving */
        {
                int i;
                rplpoint *rp;
 
-               code->replacementstubs += (ptrint) epoint;
-
                rp = code->rplpoints;
                for (i=0; i<code->rplpointcount; ++i, ++rp) {
                        rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
@@ -1391,16 +1394,7 @@ void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra)
 #if defined(ENABLE_JNI)
        /* add current JNI local references table to this thread */
 
-       lrt->capacity    = LOCALREFTABLE_CAPACITY;
-       lrt->used        = 0;
-       lrt->localframes = 1;
-       lrt->prev        = LOCALREFTABLE;
-
-       /* clear the references array (memset is faster the a for-loop) */
-
-       MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
-
-       LOCALREFTABLE = lrt;
+       localref_table_add(lrt);
 #endif
 }
 
@@ -1413,16 +1407,11 @@ void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra)
 
 *******************************************************************************/
 
-java_objectheader *codegen_finish_native_call(u1 *datasp)
+java_object_t *codegen_finish_native_call(u1 *datasp)
 {
-       stackframeinfo     *sfi;
-       stackframeinfo    **psfi;
-#if defined(ENABLE_JNI)
-       localref_table     *lrt;
-       localref_table     *plrt;
-       s4                  localframes;
-#endif
-       java_objectheader  *e;
+       stackframeinfo  *sfi;
+       stackframeinfo **psfi;
+       java_handle_t   *e;
 
        /* get data structures from stack */
 
@@ -1435,33 +1424,10 @@ java_objectheader *codegen_finish_native_call(u1 *datasp)
        *psfi = sfi->prev;
 
 #if defined(ENABLE_JNI)
-       /* release JNI local references tables for this thread */
-
-       lrt = LOCALREFTABLE;
-
-       /* release all current local frames */
+       /* release JNI local references table for this thread */
 
-       for (localframes = lrt->localframes; localframes >= 1; localframes--) {
-               /* get previous frame */
-
-               plrt = lrt->prev;
-
-               /* Clear all reference entries (only for tables allocated on
-                  the Java heap). */
-
-               if (localframes > 1)
-                       MSET(&lrt->refs[0], 0, java_objectheader*, lrt->capacity);
-
-               lrt->prev = NULL;
-
-               /* set new local references table */
-
-               lrt = plrt;
-       }
-
-       /* now store the previous local frames in the thread structure */
-
-       LOCALREFTABLE = lrt;
+       localref_frame_pop_all();
+       localref_table_remove();
 #endif
 
        /* get the exception and return it */
@@ -1509,11 +1475,6 @@ void removenativestub(u1 *stub)
    spilled) this function returns tempregnum.  If not already done,
    regoff and flags are set in the stack location.
        
-   On ARM we have to check if a long/double variable is splitted
-   across reg/stack (HIGH_REG == REG_SPLIT). We return the actual
-   register of v for LOW_REG and the tempregnum for HIGH_REG in such
-   cases.  (michi 2005/07/24)
-
 *******************************************************************************/
 
 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
@@ -1528,28 +1489,13 @@ s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
                return tempregnum;
 #endif
 
-       if (!(v->flags & INMEMORY)) {
-#if defined(__ARM__) && defined(__ARMEL__)
-               if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(v->vv.regoff) == REG_SPLIT))
-                       return PACK_REGS(GET_LOW_REG(v->vv.regoff),
-                                                        GET_HIGH_REG(tempregnum));
-#endif
-#if defined(__ARM__) && defined(__ARMEB__)
-               if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(v->vv.regoff) == REG_SPLIT))
-                       return PACK_REGS(GET_LOW_REG(tempregnum),
-                                                        GET_HIGH_REG(v->vv.regoff));
-#endif
+       if (!(v->flags & INMEMORY))
                return v->vv.regoff;
-       }
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_spills_read++;
-#endif
 
        return tempregnum;
 }
 
+
 /* codegen_reg_of_dst **********************************************************
 
    This function determines a register, to which the result of an
@@ -1559,11 +1505,6 @@ s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
    spilled) this function returns tempregnum.  If not already done,
    regoff and flags are set in the stack location.
        
-   On ARM we have to check if a long/double variable is splitted
-   across reg/stack (HIGH_REG == REG_SPLIT). We return the actual
-   register of dst.var for LOW_REG and the tempregnum for HIGH_REG in such
-   cases.  (michi 2005/07/24)
-
 *******************************************************************************/
 
 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
@@ -1571,6 +1512,7 @@ s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
        return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
 }
 
+
 /* codegen_emit_phi_moves ****************************************************
 
    Emits phi moves at the end of the basicblock.