* Removed all Id tags.
[cacao.git] / src / vm / jit / replace.c
index ed6d9ec6be87787defab72f596ade5d864bc8c8c..03969f4a6125b2fcbb3ce0235002ae29d050b437 100644 (file)
@@ -1,6 +1,6 @@
-/* vm/jit/replace.c - on-stack replacement of methods
+/* src/vm/jit/replace.c - on-stack replacement of methods
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   $Id$
-
 */
 
 #include "config.h"
 #include "arch.h"
 
 #include "mm/memory.h"
+
+#include "threads/threads-common.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/stringlocal.h"
+
 #include "vm/jit/abi.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/replace.h"
-#include "vm/jit/stack.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/disass.h"
-#include "vm/jit/show.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/md.h"
 #include "vm/jit/methodheader.h"
+#include "vm/jit/replace.h"
+#include "vm/jit/show.h"
+#include "vm/jit/stack.h"
+
 #include "vmcore/options.h"
 #include "vmcore/classcache.h"
 
-#include "native/include/java_lang_String.h"
 
 #define REPLACE_PATCH_DYNAMIC_CALL
 /*#define REPLACE_PATCH_ALL*/
 
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
 
 /*** architecture-dependent configuration *************************************/
 
@@ -67,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
 
 
@@ -100,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)
@@ -241,17 +245,17 @@ static void replace_create_replacement_point(jitdata *jd,
                                continue;
 
                        ra->index = i;
-                       if (index < UNUSED) {
-                               ra->regoff = (UNUSED - index) - 1;
-                               ra->type = TYPE_RET;
-                               ra->flags = 0;
-                       }
-                       else {
+                       if (index >= 0) {
                                v = VAR(index);
                                ra->flags = v->flags & (INMEMORY);
                                ra->regoff = v->vv.regoff;
                                ra->type = v->type;
                        }
+                       else {
+                               ra->regoff = RETADDR_FROM_JAVALOCAL(index);
+                               ra->type = TYPE_RET;
+                               ra->flags = 0;
+                       }
                        ra++;
                }
        }
@@ -608,6 +612,9 @@ bool replace_create_replacement_points(jitdata *jd)
                        replace_create_replacement_point(jd, iinfo, rp++,
                                        bptr->type, bptr->iinstr, &ra,
                                        bptr->javalocals, bptr->invars + i, bptr->indepth - i, 0);
+
+                       if (JITDATA_HAS_FLAG_COUNTDOWN(jd))
+                               rp[-1].flags |= RPLPOINT_FLAG_COUNTDOWN;
                }
 
                /* iterate over the instructions */
@@ -704,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;
 
@@ -817,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;
@@ -845,6 +855,23 @@ void replace_deactivate_replacement_points(codeinfo *code)
        s4        count;
        u1       *savedmcode;
 
+       if (code->savedmcode == NULL) {
+               /* disarm countdown points by patching the branches */
+
+               i = code->rplpointcount;
+               rp = code->rplpoints;
+               for (; i--; rp++) {
+                       if ((rp->flags & (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN))
+                                       == RPLPOINT_FLAG_COUNTDOWN)
+                       {
+#if 0
+                               *(s4*) (rp->pc + 9) = 0; /* XXX machine dependent! */
+#endif
+                       }
+               }
+               return;
+       }
+
        assert(code->savedmcode != NULL);
        savedmcode = code->savedmcode;
 
@@ -862,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
 
@@ -891,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
 
@@ -901,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)
 {
@@ -909,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
@@ -926,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) {
@@ -946,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)
 {
@@ -961,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
@@ -984,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;
@@ -992,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
@@ -1023,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
   
 *******************************************************************************/
 
@@ -1077,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 */
 
@@ -1124,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--;
        }
@@ -1149,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) */
@@ -1226,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--;
@@ -1244,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++;
                }
@@ -1254,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
@@ -1296,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 */
 
@@ -1317,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++;
        }
@@ -1374,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;
                }
@@ -1393,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++;
                }
@@ -1502,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;
@@ -1547,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;
@@ -1654,13 +1710,20 @@ struct replace_patch_data_t {
        u1         *entrypoint;
 };
 
+#define CODEINFO_OF_CODE(entrypoint) \
+       (*(codeinfo **)((u1*)(entrypoint) + CodeinfoPointer))
+
+#define METHOD_OF_CODE(entrypoint) \
+       (CODEINFO_OF_CODE(entrypoint)->m)
+
 void replace_patch_callback(classinfo *c, struct replace_patch_data_t *pd)
 {
        vftbl_t *vftbl = c->vftbl;
 
        if (vftbl != NULL
                && vftbl->vftbllength > pd->m->vftblindex
-               && vftbl->table[pd->m->vftblindex] == (methodptr) pd->oldentrypoint)
+               && vftbl->table[pd->m->vftblindex] != &asm_abstractmethoderror
+               && METHOD_OF_CODE(vftbl->table[pd->m->vftblindex]) == pd->m)
        {
                replace_patch_class(c->vftbl, pd->m, pd->oldentrypoint, pd->entrypoint);
        }
@@ -1676,6 +1739,9 @@ void replace_patch_class_hierarchy(methodinfo *m,
        pd.oldentrypoint = oldentrypoint;
        pd.entrypoint = entrypoint;
 
+       DOLOG_SHORT( printf("patching class hierarchy: ");
+                            method_println(m); );
+
        classcache_foreach_loaded_class(
                        (classcache_foreach_functionptr_t) &replace_patch_callback,
                        (void*) &pd);
@@ -1698,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);
@@ -1908,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);
@@ -2105,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
@@ -2119,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 */
@@ -2202,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;
@@ -2246,7 +2351,7 @@ sourcestate_t *replace_recover_source_state(rplpoint *rp,
        /* get the stackframeinfo if none is given */
 
        if (sfi == NULL)
-               sfi = *(STACKFRAMEINFO);
+               sfi = STACKFRAMEINFO;
 
        /* each iteration of the loop recovers one source frame */
 
@@ -2280,6 +2385,10 @@ sourcestate_t *replace_recover_source_state(rplpoint *rp,
 
                replace_read_executionstate(rp, es, ss, ss->frames == NULL);
 
+#if defined(ENABLE_VMLOG)
+               vmlog_cacao_unrol_method(ss->frames->method);
+#endif
+
 #if defined(REPLACE_STATISTICS)
                REPLACE_COUNT(stat_frames);
                depth++;
@@ -2401,6 +2510,12 @@ static bool replace_map_source_state(sourcestate_t *ss)
 #if defined(REPLACE_STATISTICS)
                                oldcode = frame->method->code;
 #endif
+                               /* request optimization of hot methods and their callers */
+
+                               if (frame->method->hitcountdown < 0
+                                       || (frame->down && frame->down->method->hitcountdown < 0))
+                                       jit_request_optimization(frame->method);
+
                                code = jit_get_current_code(frame->method);
 
                                if (code == NULL)
@@ -2493,6 +2608,11 @@ static void replace_build_execution_state_intern(sourcestate_t *ss,
 
                es->code = ss->frames->tocode;
                prevframe = ss->frames;
+
+#if defined(ENABLE_VMLOG)
+               vmlog_cacao_rerol_method(ss->frames->method);
+#endif
+
                replace_write_executionstate(rp, es, ss, ss->frames->down == NULL);
 
                DOLOG( replace_executionstate_println(es); );
@@ -2614,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
@@ -2693,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 */
@@ -2850,6 +3019,8 @@ void replace_replacement_point_println(rplpoint *rp, int depth)
                        replace_type_str[rp->type]);
        if (rp->flags & RPLPOINT_FLAG_NOTRAP)
                printf(" NOTRAP");
+       if (rp->flags & RPLPOINT_FLAG_COUNTDOWN)
+               printf(" COUNTDOWN");
        if (rp->flags & RPLPOINT_FLAG_ACTIVE)
                printf(" ACTIVE");
        printf(" parent:%p\n", (void*)rp->parent);
@@ -2914,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");
@@ -2966,9 +3140,9 @@ void replace_executionstate_println(executionstate_t *es)
                else
                        printf(" ");
 #if SIZEOF_VOID_P == 8
-               printf("%-3s = %016llx",regs[i],(unsigned long long)es->intregs[i]);
+               printf("%-3s = %016llx",abi_registers_integer_name[i],(unsigned long long)es->intregs[i]);
 #else
-               printf("%-3s = %08lx",regs[i],(unsigned long)es->intregs[i]);
+               printf("%-3s = %08lx",abi_registers_integer_name[i],(unsigned long)es->intregs[i]);
 #endif
                if (i%4 == 3)
                        printf("\n");
@@ -2982,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;
@@ -2990,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
@@ -3027,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);
 
@@ -3044,7 +3229,7 @@ static void java_value_print(s4 type, replace_val_t value)
 
                if (obj->vftbl->class == class_java_lang_String) {
                        printf(" \"");
-                       u = javastring_toutf((java_lang_String *)obj, false);
+                       u = javastring_toutf(obj, false);
                        utf_display_printable_ascii(u);
                        printf("\"");
                }
@@ -3080,7 +3265,7 @@ void replace_source_frame_println(sourceframe_t *frame)
                j = 0;
                for (i=0; i<INT_REG_CNT; ++i) {
                        if (nregdescint[i] == REG_SAV)
-                               printf("\t%s = %p\n", regs[i], (void*)frame->nativesavint[j++]);
+                               printf("\t%s = %p\n", abi_registers_integer_name[i], (void*)frame->nativesavint[j++]);
                }
 
                j = 0;