* Removed all Id tags.
[cacao.git] / src / vm / jit / replace.c
index 62455f2c76d5ca8c330b53e1f7fc9e782d1cb326..03969f4a6125b2fcbb3ce0235002ae29d050b437 100644 (file)
@@ -22,8 +22,6 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id$
-
 */
 
 #include "config.h"
@@ -72,8 +70,8 @@
 #undef REPLACE_LEAFMETHODS_RA_REGISTER
 #undef REPLACE_REG_RA
 
-/* i386 and x86_64 */
-#if defined(__I386__) || defined(__X86_64__)
+/* i386, x86_64 and m68k */
+#if defined(__I386__) || defined(__X86_64__) || defined(__M68K__)
 #define REPLACE_RA_BETWEEN_FRAMES
 /* alpha */
 #elif defined(__ALPHA__)
 #define REPLACE_RA_LINKAGE_AREA
 #define REPLACE_LEAFMETHODS_RA_REGISTER
 #define REPLACE_REG_RA REG_ITMP3 /* the execution state has the LR in itmp3 */
+/* s390 */
+#elif defined(__S390__)
+#define REPLACE_RA_TOP_OF_FRAME
+#define REPLACE_REG_RA REG_ITMP3
 #endif
 
 
@@ -105,17 +107,14 @@ typedef u8 stackslot_t;
 
 /*** debugging ****************************************************************/
 
-/*#define REPLACE_VERBOSE*/
-
 #if !defined(NDEBUG)
 static void java_value_print(s4 type, replace_val_t value);
 static void replace_stackframeinfo_println(stackframeinfo *sfi);
 #endif
 
-#if !defined(NDEBUG) && defined(REPLACE_VERBOSE)
-int replace_verbose = 0;
-#define DOLOG(code)        do{ if (replace_verbose > 1) { code; } } while(0)
-#define DOLOG_SHORT(code)  do{ if (replace_verbose > 0) { code; } } while(0)
+#if !defined(NDEBUG)
+#define DOLOG(code)        do{ if (opt_TraceReplacement > 1) { code; } } while(0)
+#define DOLOG_SHORT(code)  do{ if (opt_TraceReplacement > 0) { code; } } while(0)
 #else
 #define DOLOG(code)
 #define DOLOG_SHORT(code)
@@ -712,6 +711,9 @@ bool replace_create_replacement_points(jitdata *jd)
        code->globalcount   = 0;
        code->savedintcount = INT_SAV_CNT - rd->savintreguse;
        code->savedfltcount = FLT_SAV_CNT - rd->savfltreguse;
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       code->savedadrcount = ADR_SAV_CNT - rd->savadrreguse;
+#endif
        code->memuse        = rd->memuse;
        code->stackframesize = jd->cd->stackframesize;
 
@@ -825,7 +827,7 @@ void replace_activate_replacement_points(codeinfo *code, bool mappable)
 
                savedmcode -= REPLACEMENT_PATCH_SIZE;
 
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) || defined(__S390__)) && defined(ENABLE_JIT)
                md_patch_replacement_point(code, index, rp, savedmcode);
 #endif
                rp->flags |= RPLPOINT_FLAG_ACTIVE;
@@ -887,7 +889,7 @@ void replace_deactivate_replacement_points(codeinfo *code)
                DOLOG( printf("deactivate replacement point:\n");
                           replace_replacement_point_println(rp, 1); fflush(stdout); );
 
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) || defined(__S390__)) && defined(ENABLE_JIT)
                md_patch_replacement_point(code, -1, rp, savedmcode);
 #endif
 
@@ -916,7 +918,6 @@ void replace_deactivate_replacement_points(codeinfo *code)
    
    IN:
           es...............execution state
-          sp...............stack pointer of the execution state (XXX eliminate?)
           ra...............allocation
           javaval..........where to put the value
 
@@ -926,7 +927,6 @@ void replace_deactivate_replacement_points(codeinfo *code)
 *******************************************************************************/
 
 static void replace_read_value(executionstate_t *es,
-                                                          stackslot_t *sp,
                                                           rplalloc *ra,
                                                           replace_val_t *javaval)
 {
@@ -934,11 +934,11 @@ static void replace_read_value(executionstate_t *es,
                /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
 #ifdef HAS_4BYTE_STACKSLOT
                if (IS_2_WORD_TYPE(ra->type)) {
-                       javaval->l = *(u8*)(sp + ra->regoff);
+                       javaval->l = *(u8*)(es->sp + ra->regoff);
                }
                else {
 #endif
-                       javaval->p = sp[ra->regoff];
+                       javaval->p = *(ptrint*)(es->sp + ra->regoff);
 #ifdef HAS_4BYTE_STACKSLOT
                }
 #endif
@@ -951,6 +951,11 @@ static void replace_read_value(executionstate_t *es,
                        if (ra->type == TYPE_FLT)
                                javaval->f = javaval->d;
                }
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+               else if (IS_ADR_TYPE(ra->type)) {
+                       javaval->p = es->adrregs[ra->regoff];
+               }
+#endif
                else {
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                        if (ra->type == TYPE_LNG) {
@@ -971,14 +976,12 @@ static void replace_read_value(executionstate_t *es,
    
    IN:
           es...............execution state
-          sp...............stack pointer of the execution state (XXX eliminate?)
           ra...............allocation
           *javaval.........the value
 
 *******************************************************************************/
 
 static void replace_write_value(executionstate_t *es,
-                                                           stackslot_t *sp,
                                                            rplalloc *ra,
                                                            replace_val_t *javaval)
 {
@@ -986,11 +989,11 @@ static void replace_write_value(executionstate_t *es,
                /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
 #ifdef HAS_4BYTE_STACKSLOT
                if (IS_2_WORD_TYPE(ra->type)) {
-                       *(u8*)(sp + ra->regoff) = javaval->l;
+                       *(u8*)(es->sp + ra->regoff) = javaval->l;
                }
                else {
 #endif
-                       sp[ra->regoff] = javaval->p;
+                       *(ptrint*)(es->sp + ra->regoff) = javaval->p;
 #ifdef HAS_4BYTE_STACKSLOT
                }
 #endif
@@ -1009,6 +1012,10 @@ static void replace_write_value(executionstate_t *es,
                                es->intregs[GET_LOW_REG(ra->regoff)] = javaval->words.lo;
                                es->intregs[GET_HIGH_REG(ra->regoff)] = javaval->words.hi;
                                break;
+#endif
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+                       case TYPE_ADR:
+                               es->adrregs[ra->regoff] = javaval->p;
 #endif
                        default:
                                es->intregs[ra->regoff] = javaval->p;
@@ -1017,15 +1024,15 @@ static void replace_write_value(executionstate_t *es,
 }
 
 
-/* replace_read_executionstate *************************************************
+/* replace_new_sourceframe *****************************************************
 
-   Read the given executions state and translate it to a source frame.
+   Allocate a new source frame and insert it at the front of the frame list.
    
    IN:
           ss...............the source state
 
    OUT:
-          ss->frames.......set to new frame
+          ss->frames.......set to new frame (the new head of the frame list).
 
    RETURN VALUE:
        returns the new frame
@@ -1048,15 +1055,20 @@ static sourceframe_t *replace_new_sourceframe(sourcestate_t *ss)
 
 /* replace_read_executionstate *************************************************
 
-   Read the given executions state and translate it to a source frame.
+   Read a source frame from the given executions state.
+   The new source frame is pushed to the front of the frame list of the
+   source state.
 
    IN:
        rp...............replacement point at which `es` was taken
           es...............execution state
-          ss...............where to put the source state
+          ss...............the source state to add the source frame to
+          topframe.........true, if the first (top-most) source frame on the
+                           stack is to be read
 
    OUT:
-       *ss..............the source state derived from the execution state
+       *ss..............the source state with the newly created source frame
+                           added
   
 *******************************************************************************/
 
@@ -1102,7 +1114,7 @@ static void replace_read_executionstate(rplpoint *rp,
 
        /* calculate base stack pointer */
 
-       basesp = sp + code_get_stack_frame_size(code);
+       basesp = sp + code->stackframesize;
 
        /* create the source frame */
 
@@ -1149,7 +1161,7 @@ static void replace_read_executionstate(rplpoint *rp,
                if (ra->type == TYPE_RET)
                        frame->javalocals[i].i = ra->regoff;
                else
-                       replace_read_value(es, sp, ra, frame->javalocals + i);
+                       replace_read_value(es, ra, frame->javalocals + i);
                ra++;
                count--;
        }
@@ -1174,12 +1186,12 @@ static void replace_read_executionstate(rplpoint *rp,
                instra.regoff = md->params[0].regoff;
                if (md->params[0].inmemory) {
                        instra.flags = INMEMORY;
-                       instra.regoff += (1 + code->stackframesize);
+                       instra.regoff += (1 + code->stackframesize) * SIZE_OF_STACKSLOT;
                }
                else {
                        instra.flags = 0;
                }
-               replace_read_value(es, sp, &instra, &(frame->instance));
+               replace_read_value(es, &instra, &(frame->instance));
 #endif
        }
 #endif /* defined(REPLACE_PATCH_DYNAMIC_CALL) */
@@ -1251,7 +1263,7 @@ static void replace_read_executionstate(rplpoint *rp,
 
                                calleeframe->syncslotcount = 1;
                                calleeframe->syncslots = DMNEW(replace_val_t, 1);
-                               replace_read_value(es,sp,ra,calleeframe->syncslots);
+                               replace_read_value(es,ra,calleeframe->syncslots);
                        }
 
                        frame->javastackdepth--;
@@ -1269,7 +1281,7 @@ static void replace_read_executionstate(rplpoint *rp,
                        if (ra->type == TYPE_RET)
                                frame->javastack[i].i = ra->regoff;
                        else
-                               replace_read_value(es,sp,ra,frame->javastack + i);
+                               replace_read_value(es,ra,frame->javastack + i);
                        frame->javastacktype[i] = ra->type;
                        i++;
                }
@@ -1279,13 +1291,16 @@ static void replace_read_executionstate(rplpoint *rp,
 
 /* replace_write_executionstate ************************************************
 
-   Translate the given source state into an execution state.
-   
+   Pop a source frame from the front of the frame list of the given source state
+   and write its values into the execution state.
+
    IN:
        rp...............replacement point for which execution state should be
-                           creates
-          es...............where to put the execution state
+                           created
+          es...............the execution state to modify
           ss...............the given source state
+          topframe.........true, if this is the last (top-most) source frame to be
+                           translated
 
    OUT:
        *es..............the execution state derived from the source state
@@ -1321,7 +1336,7 @@ static void replace_write_executionstate(rplpoint *rp,
 
        sp = (stackslot_t *) es->sp;
 
-       basesp = sp + code_get_stack_frame_size(code);
+       basesp = sp + code->stackframesize;
 
        /* in some cases the top stack slot is passed in REG_ITMP1 */
 
@@ -1342,7 +1357,7 @@ static void replace_write_executionstate(rplpoint *rp,
                        /* XXX assert that it matches this rplpoint */
                }
                else
-                       replace_write_value(es, sp, ra, frame->javalocals + i);
+                       replace_write_value(es, ra, frame->javalocals + i);
                count--;
                ra++;
        }
@@ -1399,7 +1414,7 @@ static void replace_write_executionstate(rplpoint *rp,
                                assert(frame->down->syncslotcount == 1); /* XXX need to understand more cases */
                                assert(frame->down->syncslots != NULL);
 
-                               replace_write_value(es,sp,ra,frame->down->syncslots);
+                               replace_write_value(es,ra,frame->down->syncslots);
                        }
                        continue;
                }
@@ -1418,7 +1433,7 @@ static void replace_write_executionstate(rplpoint *rp,
                                /* XXX assert that it matches this rplpoint */
                        }
                        else {
-                               replace_write_value(es,sp,ra,frame->javastack + i);
+                               replace_write_value(es,ra,frame->javastack + i);
                        }
                        i++;
                }
@@ -1527,6 +1542,17 @@ u1* replace_pop_activation_record(executionstate_t *es,
                es->fltregs[reg] = *(double*)basesp;
        }
 
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       /* restore saved adr registers */
+
+       reg = ADR_REG_CNT;
+       for (i=0; i<es->code->savedadrcount; ++i) {
+               while (nregdescadr[--reg] != REG_SAV)
+                       ;
+               es->adrregs[reg] = *--basesp;
+       }
+#endif
+
        /* adjust the stackpointer */
 
        es->sp += SIZE_OF_STACKSLOT * es->code->stackframesize;
@@ -1572,6 +1598,11 @@ u1* replace_pop_activation_record(executionstate_t *es,
        for (i=0; i<FLT_REG_CNT; ++i)
                if (nregdescfloat[i] != REG_SAV)
                        *(u8*)&(es->fltregs[i]) = 0x33dead3333dead33ULL;
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i=0; i<ADR_REG_CNT; ++i)
+               if (nregdescadr[i] != REG_SAV)
+                       es->adrregs[i] = (ptrint) 0x33dead3333dead33ULL;
+# endif
 #endif /* !defined(NDEBUG) */
 
        return (code) ? ra : NULL;
@@ -1733,15 +1764,15 @@ void replace_patch_future_calls(u1 *ra,
                                                                sourceframe_t *callerframe,
                                                                sourceframe_t *calleeframe)
 {
-       u1                *patchpos;
-       methodptr          entrypoint;
-       methodptr          oldentrypoint;
-       bool               atentry;
-       stackframeinfo     sfi;
-       codeinfo          *calleecode;
-       methodinfo        *calleem;
-       java_objectheader *obj;
-       vftbl_t           *vftbl;
+       u1             *patchpos;
+       methodptr       entrypoint;
+       methodptr       oldentrypoint;
+       bool            atentry;
+       stackframeinfo  sfi;
+       codeinfo       *calleecode;
+       methodinfo     *calleem;
+       java_object_t  *obj;
+       vftbl_t        *vftbl;
 
        assert(ra);
        assert(callerframe->down == calleeframe);
@@ -1943,6 +1974,22 @@ void replace_push_activation_record(executionstate_t *es,
 #endif
        }
 
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       /* save adr registers */
+
+       reg = ADR_REG_CNT;
+       for (i=0; i<calleecode->savedadrcount; ++i) {
+               while (nregdescadr[--reg] != REG_SAV)
+                       ;
+               *--basesp = es->adrregs[reg];
+
+               /* XXX may not clobber saved regs used by native code! */
+#if !defined(NDEBUG) && 0
+               es->adrregs[reg] = (ptrint) 0x44dead4444dead44ULL;
+#endif
+       }
+#endif
+
        /* write slots used for synchronization */
 
        count = code_get_sync_slot_count(calleecode);
@@ -2140,6 +2187,14 @@ static void replace_pop_native_frame(executionstate_t *es,
                        frame->nativesavflt[j++] = es->fltregs[i];
        }
 
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       j = 0;
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (nregdescadr[i] == REG_SAV)
+                       frame->nativesavadr[j++] = es->adrregs[i];
+       }
+#endif
+
        /* restore saved registers */
 
 #if 0
@@ -2154,6 +2209,13 @@ static void replace_pop_native_frame(executionstate_t *es,
                if (nregdescfloat[i] == REG_SAV)
                        es->fltregs[i] = 0.0;
        }
+
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (nregdescadr[i] == REG_SAV)
+                       es->adrregs[i] = 0;
+       }
+# endif
 #endif
 
        /* restore pv, pc, and sp */
@@ -2237,6 +2299,14 @@ static void replace_push_native_frame(executionstate_t *es, sourcestate_t *ss)
                        es->fltregs[i] = frame->nativesavflt[j++];
        }
 
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       j = 0;
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (nregdescadr[i] == REG_SAV)
+                       es->adrregs[i] = frame->nativesavadr[j++];
+       }
+#endif
+
        /* skip the native frame on the machine stack */
 
        es->sp -= frame->nativeframesize;
@@ -2664,6 +2734,55 @@ void replace_free_safestack(replace_safestack_t *st, executionstate_t *tmpes)
 }
 
 
+/* replace_me_wrapper **********************************************************
+
+   TODO: Document me!
+
+*******************************************************************************/
+
+bool replace_me_wrapper(u1 *pc)
+{
+       codeinfo         *code;
+       rplpoint         *rp;
+       executionstate_t  es;
+
+       /* search the codeinfo for the given PC */
+
+       code = code_find_codeinfo_for_pc(pc);
+       assert(code);
+
+       /* search for a replacement point at the given PC */
+
+#if 0
+       rp = replace_find_replacement_point_for_pc(code, pc);
+       assert(rp == NULL || rp->pc == pc);
+#else
+       {
+               int i;
+               rplpoint *rp2;
+               rp = NULL;
+               for (i=0,rp2=code->rplpoints; i<code->rplpointcount; i++,rp2++) {
+                       if (rp2->pc == pc)
+                               rp = rp2;
+               }
+       }
+#endif
+
+       /* check if the replacement point is active */
+
+       if (rp != NULL && (rp->flags & RPLPOINT_FLAG_ACTIVE)) {
+
+               /*md_replace_executionstate_read(&es, context);*/
+
+               replace_me(rp, &es);
+
+               return true;
+       }
+       else
+               return false;
+}
+
+
 /* replace_me ******************************************************************
  
    This function is called by asm_replacement_out when a thread reaches
@@ -2743,8 +2862,8 @@ void replace_me(rplpoint *rp, executionstate_t *es)
 
        /* call the assembler code for the last phase of replacement */
 
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT)
-       asm_replacement_in(&(safestack->es), safestack);
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) || defined(__S390__)) && defined(ENABLE_JIT)
+       /*asm_replacement_in(&(safestack->es), safestack);*/
 #endif
 
        abort(); /* NOT REACHED */
@@ -2966,6 +3085,9 @@ void replace_show_replacement_points(codeinfo *code)
        printf("\ttotal allocations : %d\n",code->regalloccount);
        printf("\tsaved int regs    : %d\n",code->savedintcount);
        printf("\tsaved flt regs    : %d\n",code->savedfltcount);
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       printf("\tsaved adr regs    : %d\n",code->savedadrcount);
+#endif
        printf("\tmemuse            : %d\n",code->memuse);
 
        printf("\n");
@@ -3034,6 +3156,17 @@ void replace_executionstate_println(executionstate_t *es)
                if (i%4 == 3)
                        printf("\n");
        }
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (i%4 == 0)
+                       printf("\t");
+               else
+                       printf(" ");
+               printf("A%02d = %016llx",i,(unsigned long long)es->adrregs[i]);
+               if (i%4 == 3)
+                       printf("\n");
+       }
+# endif
 #endif
 
        sp = (stackslot_t *) es->sp;
@@ -3042,7 +3175,7 @@ void replace_executionstate_println(executionstate_t *es)
 
        if (es->code) {
                methoddesc *md = es->code->m->parseddesc;
-               slots = code_get_stack_frame_size(es->code);
+               slots = es->code->stackframesize;
                extraslots = 1 + md->memuse;
        }
        else
@@ -3079,8 +3212,8 @@ void replace_executionstate_println(executionstate_t *es)
 #if !defined(NDEBUG)
 static void java_value_print(s4 type, replace_val_t value)
 {
-       java_objectheader *obj;
-       utf               *u;
+       java_object_t *obj;
+       utf           *u;
 
        printf("%016llx",(unsigned long long) value.l);