* src/vm/jit/replace.cpp (replace_handler): Adapted replacement handler to take
[cacao.git] / src / vm / jit / replace.cpp
index a4ea93b19b7deb217a3e33d6efbebfecb93f86c6..395ad1d792236b20551798082333a4bb6e322454 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/replace.cpp - on-stack replacement of methods
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 # include "mm/cacao-gc/gc.h"
 #endif
 
-#include "mm/memory.h"
+#include "mm/dumpmemory.hpp"
+#include "mm/memory.hpp"
 
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
-#include "vm/classcache.h"
+#include "vm/classcache.hpp"
 #include "vm/globals.hpp"
 #include "vm/options.h"
 #include "vm/string.hpp"
@@ -59,7 +60,7 @@
 #include "vm/jit/jit.hpp"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/replace.hpp"
-#include "vm/jit/show.h"
+#include "vm/jit/show.hpp"
 #include "vm/jit/stack.h"
 
 
 /*** architecture-dependent configuration *************************************/
 
 /* first unset the macros (default) */
-#undef REPLACE_RA_BETWEEN_FRAMES
-#undef REPLACE_RA_TOP_OF_FRAME
 #undef REPLACE_RA_LINKAGE_AREA
-#undef REPLACE_LEAFMETHODS_RA_REGISTER
-
-/* 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_TOP_OF_FRAME
-#define REPLACE_LEAFMETHODS_RA_REGISTER
+
 /* powerpc */
-#elif defined(__POWERPC__)
-#define REPLACE_RA_LINKAGE_AREA
-#define REPLACE_LEAFMETHODS_RA_REGISTER
-/* s390 */
-#elif defined(__S390__)
-#define REPLACE_RA_TOP_OF_FRAME
+#if defined(__POWERPC__)
+# define REPLACE_RA_LINKAGE_AREA
 #endif
 
 
 
 /* XXX this should be in md-abi.h files, probably */
 
-#if defined(HAS_4BYTE_STACKSLOT)
-#define SIZE_OF_STACKSLOT      4
-#define STACK_SLOTS_PER_FLOAT  2
-typedef u4 stackslot_t;
-#else
 #define SIZE_OF_STACKSLOT      8
 #define STACK_SLOTS_PER_FLOAT  1
 typedef u8 stackslot_t;
-#endif
 
 
 /*** debugging ****************************************************************/
@@ -446,7 +427,7 @@ bool replace_create_replacement_points(jitdata *jd)
        count = 0;
        alloccount = 0;
 
-       javalocals = DMNEW(s4, jd->maxlocals);
+       javalocals = (s4*) DumpMemory::allocate(sizeof(s4) * jd->maxlocals);
 
        for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
 
@@ -733,13 +714,7 @@ bool replace_create_replacement_points(jitdata *jd)
        code->regalloc      = regalloc;
        code->regalloccount = alloccount;
        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;
 
        REPLACE_COUNT_DIST(stat_dist_method_rplpoints, count);
        REPLACE_COUNT_INC(stat_regallocs, alloccount);
@@ -1082,7 +1057,7 @@ static sourceframe_t *replace_new_sourceframe(sourcestate_t *ss)
 {
        sourceframe_t *frame;
 
-       frame = DNEW(sourceframe_t);
+       frame = (sourceframe_t*) DumpMemory::allocate(sizeof(sourceframe_t));
        MZERO(frame, sourceframe_t, 1);
 
        frame->down = ss->frames;
@@ -1169,8 +1144,8 @@ static void replace_read_executionstate(rplpoint *rp,
 
        count = m->maxlocals;
        frame->javalocalcount = count;
-       frame->javalocals = DMNEW(replace_val_t, count);
-       frame->javalocaltype = DMNEW(u1, count);
+       frame->javalocals = (replace_val_t*) DumpMemory::allocate(sizeof(replace_val_t) * count);
+       frame->javalocaltype = (u1*) DumpMemory::allocate(sizeof(u1) * count);
 
        /* mark values as undefined */
        for (i=0; i<count; ++i) {
@@ -1244,8 +1219,8 @@ static void replace_read_executionstate(rplpoint *rp,
        /* read stack slots */
 
        frame->javastackdepth = count;
-       frame->javastack = DMNEW(replace_val_t, count);
-       frame->javastacktype = DMNEW(u1, count);
+       frame->javastack = (replace_val_t*) DumpMemory::allocate(sizeof(replace_val_t) * count);
+       frame->javastacktype = (u1*) DumpMemory::allocate(sizeof(u1) * count);
 
 #if !defined(NDEBUG)
        /* mark values as undefined */
@@ -1307,7 +1282,7 @@ static void replace_read_executionstate(rplpoint *rp,
                                assert(calleeframe->syncslots == NULL);
 
                                calleeframe->syncslotcount = 1;
-                               calleeframe->syncslots = DMNEW(replace_val_t, 1);
+                               calleeframe->syncslots = (replace_val_t*) DumpMemory::allocate(sizeof(replace_val_t));
                                replace_read_value(es,ra,calleeframe->syncslots);
                        }
 
@@ -1517,7 +1492,7 @@ static void replace_write_executionstate(rplpoint *rp,
 void md_pop_stackframe(executionstate_t *es)
 {
        u1 *ra;
-       s4 ra_align_off;
+       s4 framesize;
        s4 reg;
        s4 i;
        stackslot_t *basesp;
@@ -1525,23 +1500,18 @@ void md_pop_stackframe(executionstate_t *es)
 
        assert(es->code);
 
-       /* alignment offset of RA */
+       /* calculate the size of the stackframe */
 
-       ra_align_off = 0;
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-    if (es->code->stackframesize)
-               ra_align_off = SIZE_OF_STACKSLOT - SIZEOF_VOID_P;
-#endif
+       framesize = md_stacktrace_get_framesize(es->code);
 
        /* read the return address */
 
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+#if STACKFRAME_LEAFMETHODS_RA_REGISTER
        if (code_is_leafmethod(es->code))
                ra = es->ra;
        else
 #endif
-               ra = (u1*) md_stacktrace_get_returnaddress(es->sp,
-                          SIZE_OF_STACKSLOT * es->code->stackframesize + ra_align_off);
+               ra = (u1*) md_stacktrace_get_returnaddress(es->sp, framesize);
 
        /* calculate the base of the stack frame */
 
@@ -1550,17 +1520,17 @@ void md_pop_stackframe(executionstate_t *es)
 
        /* restore return address, if part of frame */
 
-#if defined(REPLACE_RA_TOP_OF_FRAME)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+#if STACKFRAME_RA_TOP_OF_FRAME
+# if STACKFRAME_LEAFMETHODS_RA_REGISTER
        if (!code_is_leafmethod(es->code))
-#endif
+# endif
                es->ra = (u1*) (ptrint) *--basesp;
-#endif /* REPLACE_RA_TOP_OF_FRAME */
+#endif /* STACKFRAME_RA_TOP_OF_FRAME */
 
 #if defined(REPLACE_RA_LINKAGE_AREA)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+# if STACKFRAME_LEAFMETHODS_RA_REGISTER
        if (!code_is_leafmethod(es->code))
-#endif
+# endif
                es->ra = (u1*) (ptrint) basesp[LA_LR_OFFSET / sizeof(stackslot_t)];
 #endif /* REPLACE_RA_LINKAGE_AREA */
 
@@ -1597,10 +1567,9 @@ void md_pop_stackframe(executionstate_t *es)
 
        /* adjust the stackpointer */
 
-       es->sp += SIZE_OF_STACKSLOT * es->code->stackframesize;
-
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp += ra_align_off + SIZEOF_VOID_P; /* skip return address */
+       es->sp += framesize;
+#if STACKFRMAE_RA_BETWEEN_FRAMES
+       es->sp += SIZEOF_VOID_P; /* skip return address */
 #endif
 
        /* set the program counter to the return address */
@@ -1657,12 +1626,12 @@ void md_push_stackframe(executionstate_t *es, codeinfo *calleecode, u1 *ra)
 
        /* write the return address */
 
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
+#if STACKFRMAE_RA_BETWEEN_FRAMES
        es->sp -= SIZEOF_VOID_P;
        *((void **)es->sp) = (void *) ra;
        if (calleecode->stackframesize)
                es->sp -= (SIZE_OF_STACKSLOT - SIZEOF_VOID_P);
-#endif /* REPLACE_RA_BETWEEN_FRAMES */
+#endif /* STACKFRAME_RA_BETWEEN_FRAMES */
 
        es->ra = (u1*) (ptrint) ra;
 
@@ -1697,17 +1666,17 @@ void md_push_stackframe(executionstate_t *es, codeinfo *calleecode, u1 *ra)
 
        /* save the return address register */
 
-#if defined(REPLACE_RA_TOP_OF_FRAME)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+#if STACKFRAME_RA_TOP_OF_FRAME
+# if STACKFRAME_LEAFMETHODS_RA_REGISTER
        if (!code_is_leafmethod(calleecode))
-#endif
+# endif
                *--basesp = (ptrint) ra;
-#endif /* REPLACE_RA_TOP_OF_FRAME */
+#endif /* STACKFRAME_RA_TOP_OF_FRAME */
 
 #if defined(REPLACE_RA_LINKAGE_AREA)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+# if STACKFRAME_LEAFMETHODS_RA_REGISTER
        if (!code_is_leafmethod(calleecode))
-#endif
+# endif
                basesp[LA_LR_OFFSET / sizeof(stackslot_t)] = (ptrint) ra;
 #endif /* REPLACE_RA_LINKAGE_AREA */
 
@@ -1797,7 +1766,7 @@ u1* replace_pop_activation_record(executionstate_t *es,
        assert(frame->syncslots == NULL);
        count = code_get_sync_slot_count(es->code);
        frame->syncslotcount = count;
-       frame->syncslots = DMNEW(replace_val_t, count);
+       frame->syncslots = (replace_val_t*) DumpMemory::allocate(sizeof(replace_val_t) * count);
        for (i=0; i<count; ++i) {
                frame->syncslots[i].p = sp[es->code->memuse + i]; /* XXX md_ function */
        }
@@ -2376,11 +2345,9 @@ static void replace_pop_native_frame(executionstate_t *es,
 
        /* restore sp, pv, pc and codeinfo of the parent method */
 
-       /* XXX michi: use this instead:
-       es->sp = sfi->sp + code->stackframesize; */
-       es->sp   = (uint8_t*) (((uintptr_t) sfi->sp) + (*(s4 *) (((uintptr_t) sfi->pv) + FrameSize)));
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp  += SIZE_OF_STACKSLOT; /* skip return address */
+       es->sp   = (uint8_t*) (((uintptr_t) sfi->sp) + md_stacktrace_get_framesize(code));
+#if STACKFRMAE_RA_BETWEEN_FRAMES
+       es->sp  += SIZEOF_VOID_P; /* skip return address */
 #endif
        es->pv   = (uint8_t*) md_codegen_get_pv_from_pc(sfi->ra);
        es->pc   = (uint8_t*) (((uintptr_t) ((sfi->xpc) ? sfi->xpc : sfi->ra)) - 1);
@@ -2427,9 +2394,9 @@ static void replace_push_native_frame(executionstate_t *es, sourcestate_t *ss)
 
        /* skip sp for the native stub */
 
-       es->sp -= (*(s4 *) (((uintptr_t) frame->sfi->pv) + FrameSize));
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp -= SIZE_OF_STACKSLOT; /* skip return address */
+       es->sp -= md_stacktrace_get_framesize(frame->sfi->code);
+#if STACKFRMAE_RA_BETWEEN_FRAMES
+       es->sp -= SIZEOF_VOID_P; /* skip return address */
 #endif
 
        /* assert that the native frame has not moved */
@@ -2515,7 +2482,7 @@ sourcestate_t *replace_recover_source_state(rplpoint *rp,
 
        /* create the source frame structure in dump memory */
 
-       ss = DNEW(sourcestate_t);
+       ss = (sourcestate_t*) DumpMemory::allocate(sizeof(sourcestate_t));
        ss->frames = NULL;
 
        /* each iteration of the loop recovers one source frame */
@@ -2865,7 +2832,6 @@ static void replace_me(rplpoint *rp, executionstate_t *es)
 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
        threadobject        *thread;
 #endif
-       int32_t              dumpmarker;
 
        origcode = es->code;
        origrp   = rp;
@@ -2885,9 +2851,8 @@ static void replace_me(rplpoint *rp, executionstate_t *es)
 
        REPLACE_COUNT(stat_replacements);
 
-       /* mark start of dump memory area */
-
-       DMARKER;
+       // Create new dump memory area.
+       DumpMemoryArea dma;
 
        /* Get the stackframeinfo for the current thread. */
 
@@ -2967,14 +2932,10 @@ static void replace_me(rplpoint *rp, executionstate_t *es)
        if (opt_TestReplacement)
                es->pc += REPLACEMENT_PATCH_SIZE;
 #endif
-
-       /* release dump area */
-
-       DRELEASE;
 }
 
 
-/* replace_me_wrapper **********************************************************
+/* replace_handler *************************************************************
 
    This function is called by the signal handler. It determines if there
    is an active replacement point pending at the given PC and returns
@@ -2984,23 +2945,22 @@ static void replace_me(rplpoint *rp, executionstate_t *es)
 
    IN:
        pc...............the program counter that triggered the replacement.
-       context..........the context (machine state) to which the
+       es...............the execution state (machine state) to which the
                            replacement should be applied.
 
    OUT:
-       context..........the context after replacement finished.
+       es...............the execution state after replacement finished.
 
    RETURN VALUE:
        true.............replacement done, everything went ok
-       false............no replacement done, context unchanged
+       false............no replacement done, execution state unchanged
 
 *******************************************************************************/
 
-bool replace_me_wrapper(u1 *pc, void *context)
+bool replace_handler(u1 *pc, executionstate_t *es)
 {
        codeinfo         *code;
        rplpoint         *rp;
-       executionstate_t  es;
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start, time_end;
 #endif
@@ -3021,20 +2981,9 @@ bool replace_me_wrapper(u1 *pc, void *context)
 
                DOLOG( printf("valid replacement point\n"); );
 
-#if !defined(NDEBUG)
-               executionstate_sanity_check(context);
-#endif
-
                /* set codeinfo pointer in execution state */
 
-               es.code = code;
-
-               /* read execution state from current context */
-
-               md_executionstate_read(&es, context);
-
-               DOLOG( printf("REPLACEMENT READ: ");
-                          executionstate_println(&es); );
+               es->code = code;
 
                /* do the actual replacement */
 
@@ -3042,20 +2991,13 @@ bool replace_me_wrapper(u1 *pc, void *context)
                RT_TIMING_GET_TIME(time_start);
 #endif
 
-               replace_me(rp, &es);
+               replace_me(rp, es);
 
 #if defined(ENABLE_RT_TIMING)
                RT_TIMING_GET_TIME(time_end);
                RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_REPLACE);
 #endif
 
-               /* write execution state to current context */
-
-               md_executionstate_write(&es, context);
-
-               DOLOG( printf("REPLACEMENT WRITE: ");
-                          executionstate_println(&es); );
-
                /* new code is entered after returning */
 
                DOLOG( printf("JUMPING IN!\n"); fflush(stdout); );
@@ -3084,7 +3026,7 @@ void replace_gc_from_native(threadobject *thread, u1 *pc, u1 *sp)
        sfi = threads_get_current_stackframeinfo();
 
        /* create the execution state */
-       es = DNEW(executionstate_t);
+       es = (executionstate_t*) DumpMemory::allocate(sizeof(executionstate_t));
        es->pc = pc;
        es->sp = sp;
        es->pv = 0;      /* since we are in a native, PV is invalid! */
@@ -3471,12 +3413,7 @@ void replace_source_frame_println(sourceframe_t *frame)
        if (frame->syncslotcount) {
                printf("\tsynchronization slots (%d):\n",frame->syncslotcount);
                for (i=0; i<frame->syncslotcount; ++i) {
-                       printf("\tslot[%2d] = ",i);
-#ifdef HAS_4BYTE_STACKSLOT
-                       printf("%08lx\n",(unsigned long) frame->syncslots[i].p);
-#else
-                       printf("%016llx\n",(unsigned long long) frame->syncslots[i].p);
-#endif
+                       printf("\tslot[%2d] = %016llx\n",i,(unsigned long long) frame->syncslots[i].p);
                }
                printf("\n");
        }