* src/vm/jit/code.c (code_get_stack_frame_size): Deal with 4/8-byte
authoredwin <none@none>
Thu, 16 Mar 2006 00:05:18 +0000 (00:05 +0000)
committeredwin <none@none>
Thu, 16 Mar 2006 00:05:18 +0000 (00:05 +0000)
stackslots.

* src/vm/jit/tools/genoffsets.c (main): Offsets of intregs and fltregs.

* src/vm/jit/i386/asmpart.S (asm_replacement_out): Renamed regs to
intregs. Some cleanup.

* src/vm/jit/replace.c (replace_activate_replacement_point)
(replace_deactivate_replacement_point): Enabled on x86_64.
(replace_read_executionstate, replace_write_executionstate):
Deal with 4/8-byte stackslots. Handle float registers.
(replace_executionstate_println, replace_sourcestate_println):
Print register names where possible.

* src/vm/jit/x86_64/md.c (md_patch_replacement_point): Added.
(vim boilerplate): Added.

* src/vm/jit/x86_64/codegen.c (codegen): Handle replacement points.
Generate replacement-out stubs.

* src/vm/jit/x86_64/asmpart.S (asm_replacement_out, asm_replacement_in):
Added.
(vim boilerplate): Added.

* src/vm/jit/replace.h (executionstate): Separate registers into int
and float registers. Some cleanup, use INT_REG_CNT, FLT_REG_CNT macros.

src/vm/jit/code.c
src/vm/jit/i386/asmpart.S
src/vm/jit/replace.c
src/vm/jit/replace.h
src/vm/jit/tools/genoffsets.c
src/vm/jit/x86_64/asmpart.S
src/vm/jit/x86_64/codegen.c
src/vm/jit/x86_64/md.c

index 1325ed5e55cda3912ec8047be9f5b2a9b6239f39..4895589acd8891d05866967baba15f9312f07661 100644 (file)
@@ -41,6 +41,7 @@
 #include "vm/jit/code.h"
 #include "mm/memory.h"
 #include "vm/options.h"
+#include "arch.h"
 
 codeinfo *code_codeinfo_new(methodinfo *m)
 {
@@ -61,12 +62,20 @@ int code_get_stack_frame_size(codeinfo *code)
        
        assert(code);
 
-       /* XXX adapt for 4/8 byte stackslots */
-
+       /* XXX generalize to all archs */
+#ifdef HAS_4BYTE_STACKSLOT
        count = code->memuse + code->savedintcount + 2*code->savedfltcount;
+#else
+       count = code->memuse + code->savedintcount + code->savedfltcount;
+#endif
 
+       /* XXX generalize to all archs */
        if (checksync && (code->m->flags & ACC_SYNCHRONIZED))
+#ifdef HAS_4BYTE_STACKSLOT
                count += (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type)) ? 2 : 1;
+#else
+               count++;
+#endif
 
        return count;
 }
index 580205a99fbbca4adc1c69f7cd89bc19eb070b3e..1967bce77c15b3bbd1c5fa03d62165392414812a 100644 (file)
@@ -31,7 +31,7 @@
    Changes: Joseph Wenninger
             Edwin Steiner
 
-   $Id: asmpart.S 4618 2006-03-15 20:40:57Z edwin $
+   $Id: asmpart.S 4623 2006-03-16 00:05:18Z edwin $
 
 */
 
@@ -65,6 +65,7 @@
        .globl asm_handle_exception
 
        .globl asm_wrapper_patcher
+
        .globl asm_replacement_out
        .globl asm_replacement_in
 
@@ -563,25 +564,25 @@ asm_replacement_out:
        sub     $(sizeexecutionstate + REPLACEMENT_ROOM),sp
 
        /* save registers in execution state */
-       mov     %eax,(EAX*8+offes_regs)(sp)
-       mov     %ebx,(EBX*8+offes_regs)(sp)
-       mov     %ecx,(ECX*8+offes_regs)(sp)
-       mov     %edx,(EDX*8+offes_regs)(sp)
-       mov     %esi,(ESI*8+offes_regs)(sp)
-       mov     %edi,(EDI*8+offes_regs)(sp)
-       mov     %ebp,(EBP*8+offes_regs)(sp)
-       movl    $0  ,(ESP*8+offes_regs)(sp) /* XXX */
+       mov     %eax,(EAX*8+offes_intregs)(sp)
+       mov     %ebx,(EBX*8+offes_intregs)(sp)
+       mov     %ecx,(ECX*8+offes_intregs)(sp)
+       mov     %edx,(EDX*8+offes_intregs)(sp)
+       mov     %esi,(ESI*8+offes_intregs)(sp)
+       mov     %edi,(EDI*8+offes_intregs)(sp)
+       mov     %ebp,(EBP*8+offes_intregs)(sp)
+       movl    $0  ,(ESP*8+offes_intregs)(sp) /* not used */
 
 #ifndef NDEBUG
        /* clear high 32bit */
-       movl    $0,(4+0*8+offes_regs)(sp)
-       movl    $0,(4+1*8+offes_regs)(sp)
-       movl    $0,(4+2*8+offes_regs)(sp)
-       movl    $0,(4+3*8+offes_regs)(sp)
-       movl    $0,(4+4*8+offes_regs)(sp)
-       movl    $0,(4+5*8+offes_regs)(sp)
-       movl    $0,(4+6*8+offes_regs)(sp)
-       movl    $0,(4+7*8+offes_regs)(sp)
+       movl    $0,(4+0*8+offes_intregs)(sp)
+       movl    $0,(4+1*8+offes_intregs)(sp)
+       movl    $0,(4+2*8+offes_intregs)(sp)
+       movl    $0,(4+3*8+offes_intregs)(sp)
+       movl    $0,(4+4*8+offes_intregs)(sp)
+       movl    $0,(4+5*8+offes_intregs)(sp)
+       movl    $0,(4+6*8+offes_intregs)(sp)
+       movl    $0,(4+7*8+offes_intregs)(sp)
 #endif
 
        /* calculate sp of method */
@@ -609,9 +610,7 @@ asm_replacement_out:
 *******************************************************************************/
 
 asm_replacement_in:
-       mov     %esp,%ebp                   /* save stackptr                      */
-
-       mov     (4+0)(%ebp),%ebp            /* executionstate *es                 */
+       mov     4(sp),%ebp                  /* executionstate *es                 */
 
        /* set new sp */
        mov     (offes_sp)(%ebp),%esp
@@ -620,13 +619,14 @@ asm_replacement_in:
        push    (offes_pc)(%ebp)
        
        /* copy registers from execution state */
-       mov     (EAX*8+offes_regs)(%ebp),%eax
-       mov     (EBX*8+offes_regs)(%ebp),%ebx
-       mov     (ECX*8+offes_regs)(%ebp),%ecx
-       mov     (EDX*8+offes_regs)(%ebp),%edx
-       mov     (ESI*8+offes_regs)(%ebp),%esi
-       mov     (EDI*8+offes_regs)(%ebp),%edi
-       mov     (EBP*8+offes_regs)(%ebp),%ebp
+       mov     (EAX*8+offes_intregs)(%ebp),%eax
+       mov     (EBX*8+offes_intregs)(%ebp),%ebx
+       mov     (ECX*8+offes_intregs)(%ebp),%ecx
+       mov     (EDX*8+offes_intregs)(%ebp),%edx
+       mov     (ESI*8+offes_intregs)(%ebp),%esi
+       mov     (EDI*8+offes_intregs)(%ebp),%edi
+
+       mov     (EBP*8+offes_intregs)(%ebp),%ebp
 
        /* jump to new code */
        ret
index 3f7f3f398928b717c661e0d520415001490aa428..bc14495cf74576fcfec02a52c2679116eefc33a9 100644 (file)
@@ -42,6 +42,8 @@
 #include "vm/options.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/asmpart.h"
+#include "vm/jit/disass.h"
+#include "arch.h"
 
 /* replace_create_replacement_points *******************************************
  
@@ -271,7 +273,7 @@ void replace_activate_replacement_point(rplpoint *rp,rplpoint *target)
        
        rp->target = target;
        
-#if defined(__I386__) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__)) && defined(ENABLE_JIT)
        md_patch_replacement_point(rp);
 #endif
 }
@@ -299,7 +301,7 @@ void replace_deactivate_replacement_point(rplpoint *rp)
        
        rp->target = NULL;
        
-#if defined(__I386__) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__)) && defined(ENABLE_JIT)
        md_patch_replacement_point(rp);
 #endif
 }
@@ -328,9 +330,14 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
        int t;
        int allocs;
        rplalloc *ra;
-       u4 *sp; /* XXX configure stack slot size */
-       u4 *basesp;
        methoddesc *md;
+#ifdef HAS_4BYTE_STACKSLOT
+       u4 *sp;
+       u4 *basesp;
+#else
+       u8 *sp;
+       u8 *basesp;
+#endif
 
        code = rp->code;
        m = code->m;
@@ -338,7 +345,11 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
 
        /* calculate stack pointers */
 
+#ifdef HAS_4BYTE_STACKSLOT
        sp = (u4*) es->sp;
+#else
+       sp = (u8*) es->sp;
+#endif
        basesp = sp + code_get_stack_frame_size(code);
 
        /* read local variables */
@@ -367,7 +378,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
                        ss->javalocals[i*5+t] = sp[ra->index];
                }
                else {
-                       ss->javalocals[i*5+t] = es->regs[ra->index];
+                       ss->javalocals[i*5+t] = es->intregs[ra->index];
                }
        }
 
@@ -386,7 +397,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
                        ss->javastack[i] = sp[ra->index];
                }
                else {
-                       ss->javastack[i] = es->regs[ra->index];
+                       ss->javastack[i] = es->intregs[ra->index];
                }
        }
 
@@ -396,7 +407,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
        for (i=0; count > code->savedintcount; ++i) {
                assert(i < INT_REG_CNT);
                if (nregdescint[i] == REG_SAV)
-                       ss->savedintregs[--count] = es->regs[i];
+                       ss->savedintregs[--count] = es->intregs[i];
        }
 
        /* read saved int regs */
@@ -408,14 +419,22 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
        /* read saved flt regs */
 
        for (i=0; i<code->savedfltcount; ++i) {
+#ifdef HAS_4BYTE_STACKSLOT
                basesp -= 2;
+#else
+               basesp--;
+#endif
                ss->savedfltregs[i] = *(u8*)basesp;
        }
-#ifndef NDEBUG
-       /* XXX */
-       for (; i<FLT_SAV_CNT; ++i)
-               ss->savedfltregs[i] = (u8) 0x00dead0000dead00ULL;
-#endif
+
+       /* read unused callee saved flt regs */
+       
+       count = FLT_SAV_CNT;
+       for (i=0; count > code->savedfltcount; ++i) {
+               assert(i < FLT_REG_CNT);
+               if (nregdescfloat[i] == REG_SAV)
+                       ss->savedfltregs[--count] = es->fltregs[i];
+       }
 }
 
 /* replace_write_executionstate ************************************************
@@ -442,9 +461,14 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,sources
        int t;
        int allocs;
        rplalloc *ra;
-       u4 *sp; /* XXX configure stack slot size */
-       u4 *basesp; /* XXX configure stack slot size */
        methoddesc *md;
+#ifdef HAS_4BYTE_STACKSLOT
+       u4 *sp;
+       u4 *basesp;
+#else
+       u8 *sp;
+       u8 *basesp;
+#endif
 
        code = rp->code;
        m = code->m;
@@ -452,12 +476,13 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,sources
        
        /* calculate stack pointers */
 
+#ifdef HAS_4BYTE_STACKSLOT
        sp = (u4*) es->sp;
+#else
+       sp = (u8*) es->sp;
+#endif
        basesp = sp + code_get_stack_frame_size(code);
 
-       if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               basesp += (IS_2_WORD_TYPE(md->returntype.type)) ? 2 : 1;
-
        /* in debug mode, invalidate stack frame first */
 
 #ifndef NDEBUG
@@ -487,7 +512,7 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,sources
                        sp[ra->index] = ss->javalocals[i*5+t];
                }
                else {
-                       es->regs[ra->index] = ss->javalocals[i*5+t];
+                       es->intregs[ra->index] = ss->javalocals[i*5+t];
                }
        }
 
@@ -504,7 +529,7 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,sources
                        sp[ra->index] = ss->javastack[i];
                }
                else {
-                       es->regs[ra->index] = ss->javastack[i];
+                       es->intregs[ra->index] = ss->javastack[i];
                }
        }
        
@@ -514,7 +539,7 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,sources
        for (i=0; count > code->savedintcount; ++i) {
                assert(i < INT_REG_CNT);
                if (nregdescint[i] == REG_SAV)
-                       es->regs[i] = ss->savedintregs[--count];
+                       es->intregs[i] = ss->savedintregs[--count];
        }
 
        /* write saved int regs */
@@ -523,10 +548,23 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,sources
                *--basesp = ss->savedintregs[i];
        }
 
+       /* write unused callee saved flt regs */
+       
+       count = FLT_SAV_CNT;
+       for (i=0; count > code->savedfltcount; ++i) {
+               assert(i < FLT_REG_CNT);
+               if (nregdescfloat[i] == REG_SAV)
+                       es->fltregs[i] = ss->savedfltregs[--count];
+       }
+
        /* write saved flt regs */
 
        for (i=0; i<code->savedfltcount; ++i) {
+#ifdef HAS_4BYTE_STACKSLOT
                basesp -= 2;
+#else
+               basesp--;
+#endif
                *(u8*)basesp = ss->savedfltregs[i];
        }
 
@@ -592,7 +630,7 @@ void replace_me(rplpoint *rp,executionstate *es)
 
        /* enter new code */
 
-#if defined(__I386__) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__)) && defined(ENABLE_JIT)
        asm_replacement_in(es);
 #endif
        abort();
@@ -703,8 +741,12 @@ void replace_show_replacement_points(codeinfo *code)
 void replace_executionstate_println(executionstate *es,codeinfo *code)
 {
        int i;
-       u4 *slotptr; /* XXX configure stack slot size */
        int slots;
+#ifdef HAS_4BYTE_STACKSLOT
+       u4 *sp;
+#else
+       u8 *sp;
+#endif
 
        if (!es) {
                printf("(executionstate *)NULL\n");
@@ -714,11 +756,18 @@ void replace_executionstate_println(executionstate *es,codeinfo *code)
        printf("executionstate %p:\n",(void*)es);
        printf("\tpc = %p\n",(void*)es->pc);
        printf("\tsp = %p\n",(void*)es->sp);
-       for (i=0; i<MD_EXCSTATE_NREGS; ++i) {
-               printf("\tregs[%2d] = %016llx\n",i,(unsigned long long)es->regs[i]);
+       for (i=0; i<INT_REG_CNT; ++i) {
+               printf("\t%-3s = %016llx\n",regs[i],(unsigned long long)es->intregs[i]);
+       }
+       for (i=0; i<FLT_REG_CNT; ++i) {
+               printf("\tfltregs[%2d] = %016llx\n",i,(unsigned long long)es->fltregs[i]);
        }
 
-       slotptr = (u4*) es->sp;
+#ifdef HAS_4BYTE_STACKSLOT
+       sp = (u4*) es->sp;
+#else
+       sp = (u8*) es->sp;
+#endif
 
        if (code)
                slots = code_get_stack_frame_size(code);
@@ -727,7 +776,11 @@ void replace_executionstate_println(executionstate *es,codeinfo *code)
 
        printf("\tstack slots at sp:\n");
        for (i=0; i<slots; ++i) {
-               printf("\t\t%08lx\n",(unsigned long)*slotptr++);
+#ifdef HAS_4BYTE_STACKSLOT
+               printf("\t\t%08lx\n",(unsigned long)*sp++);
+#else
+               printf("\t\t%016llx\n",(unsigned long long)*sp++);
+#endif
        }
 
        printf("\n");
@@ -748,6 +801,7 @@ void replace_sourcestate_println(sourcestate *ss)
 {
        int i;
        int t;
+       int reg;
 
        if (!ss) {
                printf("(sourcestate *)NULL\n");
@@ -777,9 +831,12 @@ void replace_sourcestate_println(sourcestate *ss)
        printf("\n");
 
        printf("\tsaved int registers (%d):\n",INT_SAV_CNT);
+       reg = INT_REG_CNT;
        for (i=0; i<INT_SAV_CNT; ++i) {
+               while (nregdescint[--reg] != REG_SAV)
+                       ;
                if (ss->savedintregs[i] != 0x00dead0000dead00ULL) {
-                       printf("\tsavedintreg[%2d] = ",i);
+                       printf("\t%-3s = ",regs[reg]);
                        printf("%016llx\n",(unsigned long long) ss->savedintregs[i]);
                }
        }
index 8f8deda731989879bb65477206b18d12aa7151b7..9042a170840fe4163d2e538f9fa526e5acb0faa8 100644 (file)
@@ -73,15 +73,12 @@ struct rplpoint {
 /* An `executionsstate` represents the state of a thread as it reached */
 /* an replacement point or is about to enter one.                      */
 
-#define MD_EXCSTATE_NREGS         (8)
-#define MD_EXCSTATE_INT_NSAVED     3
-#define MD_EXCSTATE_FLT_NSAVED     0
-
 struct executionstate {
        u1           *pc;                               /* program counter */
        u1           *sp;                   /* stack pointer within method */
 
-       u8            regs[MD_EXCSTATE_NREGS];          /* register values */
+       u8            intregs[INT_REG_CNT];             /* register values */
+       u8            fltregs[FLT_REG_CNT];             /* register values */
 };
 
 /* `sourcestate` will probably only be used for debugging              */
index 1bbe3b7c73ce612464362d4739a4c5acf2fed8d0..9228601fdf86e31f13e5f4e9ad6890774cea3883 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: genoffsets.c 4617 2006-03-15 20:38:30Z edwin $
+   $Id: genoffsets.c 4623 2006-03-16 00:05:18Z edwin $
 
 */
 
@@ -84,7 +84,8 @@ int main(int argc, char **argv)
 
        printf("#define offes_pc                   %3d\n", (s4) OFFSET(executionstate, pc));
        printf("#define offes_sp                   %3d\n", (s4) OFFSET(executionstate, sp));
-       printf("#define offes_regs                 %3d\n", (s4) OFFSET(executionstate, regs));
+       printf("#define offes_intregs              %3d\n", (s4) OFFSET(executionstate, intregs));
+       printf("#define offes_fltregs              %3d\n", (s4) OFFSET(executionstate, fltregs));
 
        /* everything is ok */
 
index 2cf1b3292b857a796382b5808e88b9a746bc37f3..e73e7548fa6e9e8e8f030121724b8f525fee8b3e 100644 (file)
@@ -28,9 +28,9 @@
             Reinhard Grafl
             Christian Thalinger
 
-   Changes:
+   Changes: Edwin Steiner
 
-   $Id: asmpart.S 4559 2006-03-05 23:24:50Z twisti $
+   $Id: asmpart.S 4623 2006-03-16 00:05:18Z edwin $
 
 */
 
@@ -64,6 +64,9 @@
 
        .globl asm_wrapper_patcher
 
+       .globl asm_replacement_out
+       .globl asm_replacement_in
+
        .globl asm_builtin_f2i
        .globl asm_builtin_f2l
        .globl asm_builtin_d2i
@@ -616,6 +619,134 @@ L_asm_wrapper_patcher_exception:
        jmp     L_asm_handle_exception
 
 
+/* asm_replacement_out *********************************************************
+
+   This code is jumped to from the replacement-out stubs that are executed
+   when a thread reaches an activated replacement point.
+
+   The purpose of asm_replacement_out is to read out the parts of the
+   execution state that cannot be accessed from C code, store this state,
+   and then call the C function replace_me.
+
+   Stack layout:
+      8                 start of stack inside method to replace
+      0   rplpoint *    info on the replacement point that was reached
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+       /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM  512
+
+asm_replacement_out:
+    /* create stack frame */
+       sub     $(sizeexecutionstate + REPLACEMENT_ROOM),sp
+
+       /* save registers in execution state */
+       mov     %rax,(RAX*8+offes_intregs)(sp)
+       mov     %rbx,(RBX*8+offes_intregs)(sp)
+       mov     %rcx,(RCX*8+offes_intregs)(sp)
+       mov     %rdx,(RDX*8+offes_intregs)(sp)
+       mov     %rsi,(RSI*8+offes_intregs)(sp)
+       mov     %rdi,(RDI*8+offes_intregs)(sp)
+       mov     %rbp,(RBP*8+offes_intregs)(sp)
+       movq    $0  ,(RSP*8+offes_intregs)(sp) /* not used */
+       mov     %r8 ,(R8 *8+offes_intregs)(sp)
+       mov     %r9 ,(R9 *8+offes_intregs)(sp)
+       mov     %r10,(R10*8+offes_intregs)(sp)
+       mov     %r11,(R11*8+offes_intregs)(sp)
+       mov     %r12,(R12*8+offes_intregs)(sp)
+       mov     %r13,(R13*8+offes_intregs)(sp)
+       mov     %r14,(R14*8+offes_intregs)(sp)
+       mov     %r15,(R15*8+offes_intregs)(sp)
+
+       movq    %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
+       movq    %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
+       movq    %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
+       movq    %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
+       movq    %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
+       movq    %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
+       movq    %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
+       movq    %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
+       movq    %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
+       movq    %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
+       movq    %xmm10,(XMM10*8+offes_fltregs)(sp)
+       movq    %xmm11,(XMM11*8+offes_fltregs)(sp)
+       movq    %xmm12,(XMM12*8+offes_fltregs)(sp)
+       movq    %xmm13,(XMM13*8+offes_fltregs)(sp)
+       movq    %xmm14,(XMM14*8+offes_fltregs)(sp)
+       movq    %xmm15,(XMM15*8+offes_fltregs)(sp)
+
+       /* calculate sp of method */
+       mov     sp,itmp1
+       add     $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
+       mov     itmp1,(offes_sp)(sp)
+
+       /* call replace_me */
+       mov     -8(itmp1),a0                /* rplpoint *                         */
+    mov     sp,a1                       /* arg1: execution state              */
+    call    replace_me@PLT              /* call C function replace_me         */
+    call    abort@PLT                   /* NEVER REACHED                      */
+
+/* asm_replacement_in **********************************************************
+
+   This code writes the given execution state and jumps to the replacement
+   code.
+
+   This function never returns!
+
+   C prototype:
+      void asm_replacement_in(executionstate *es);
+
+*******************************************************************************/
+
+asm_replacement_in:
+       mov     a0,%rbp                     /* executionstate *es                 */
+
+       /* set new sp */
+       mov     (offes_sp)(%rbp),%rsp
+       
+       /* store address of new code */
+       push    (offes_pc)(%rbp)
+       
+       /* copy registers from execution state */
+       movq    (XMM0 *8+offes_fltregs)(%rbp),%xmm0
+       movq    (XMM1 *8+offes_fltregs)(%rbp),%xmm1
+       movq    (XMM2 *8+offes_fltregs)(%rbp),%xmm2
+       movq    (XMM3 *8+offes_fltregs)(%rbp),%xmm3
+       movq    (XMM4 *8+offes_fltregs)(%rbp),%xmm4
+       movq    (XMM5 *8+offes_fltregs)(%rbp),%xmm5
+       movq    (XMM6 *8+offes_fltregs)(%rbp),%xmm6
+       movq    (XMM7 *8+offes_fltregs)(%rbp),%xmm7
+       movq    (XMM8 *8+offes_fltregs)(%rbp),%xmm8
+       movq    (XMM9 *8+offes_fltregs)(%rbp),%xmm9
+       movq    (XMM10*8+offes_fltregs)(%rbp),%xmm10
+       movq    (XMM11*8+offes_fltregs)(%rbp),%xmm11
+       movq    (XMM12*8+offes_fltregs)(%rbp),%xmm12
+       movq    (XMM13*8+offes_fltregs)(%rbp),%xmm13
+       movq    (XMM14*8+offes_fltregs)(%rbp),%xmm14
+       movq    (XMM15*8+offes_fltregs)(%rbp),%xmm15
+
+       mov     (RAX*8+offes_intregs)(%rbp),%rax
+       mov     (RBX*8+offes_intregs)(%rbp),%rbx
+       mov     (RCX*8+offes_intregs)(%rbp),%rcx
+       mov     (RDX*8+offes_intregs)(%rbp),%rdx
+       mov     (RSI*8+offes_intregs)(%rbp),%rsi
+       mov     (RDI*8+offes_intregs)(%rbp),%rdi
+       mov     (R8 *8+offes_intregs)(%rbp),%r8
+       mov     (R9 *8+offes_intregs)(%rbp),%r9
+       mov     (R10*8+offes_intregs)(%rbp),%r10
+       mov     (R11*8+offes_intregs)(%rbp),%r11
+       mov     (R12*8+offes_intregs)(%rbp),%r12
+       mov     (R13*8+offes_intregs)(%rbp),%r13
+       mov     (R14*8+offes_intregs)(%rbp),%r14
+       mov     (R15*8+offes_intregs)(%rbp),%r15
+
+       mov     (RBP*8+offes_intregs)(%rbp),%rbp
+
+       /* jump to new code */
+       ret
+
 /* asm_builtin_x2x *************************************************************
 *                                                                              *
 *   Wrapper functions for float to int corner cases                            *
@@ -815,4 +946,5 @@ asm_criticalsections:
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */
index aa84bf42c5c3981fa334d72e0d1c600996bbed81..e490b645010db77ae2d63e8c6c88cf1d30bdbc96 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen.c 4615 2006-03-15 16:36:43Z twisti $
+   $Id: codegen.c 4623 2006-03-16 00:05:18Z edwin $
 
 */
 
@@ -65,6 +65,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/reg.h"
+#include "vm/jit/replace.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
@@ -93,6 +94,7 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
        methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
        builtintable_entry *bte;
        methoddesc         *md;
+       rplpoint           *replacementpoint;
 
        /* prevent compiler warnings */
 
@@ -374,6 +376,8 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
        /* end of header generation */
 
+       replacementpoint = cd->code->rplpoints;
+
        /* walk through all basic blocks */
 
        for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
@@ -391,6 +395,14 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                                                  bptr->mpc);
                        }
 
+               /* handle replacement points */
+
+               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
+                       replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
+                       
+                       replacementpoint++;
+               }
+
                /* copy interface registers to their destination */
 
                src = bptr->instack;
@@ -3954,6 +3966,39 @@ gen_method:
                }
        }
 
+       /* generate replacement-out stubs */
+
+       {
+               int i;
+               s4 displacement;
+
+               replacementpoint = cd->code->rplpoints;
+               for (i=0; i<cd->code->rplpointcount; ++i, ++replacementpoint) {
+                       /* check code segment size */
+
+                       MCODECHECK(512);
+
+                       /* note start of stub code */
+
+                       replacementpoint->outcode = (u1*) (ptrint)(cd->mcodeptr - cd->mcodebase);
+
+                       /* make machine code for patching */
+
+                       displacement = (ptrint)(replacementpoint->outcode - replacementpoint->pc) - 5;
+                       replacementpoint->mcode = 0xe9 | ((u8)displacement << 8);
+
+                       /* push address of `rplpoint` struct */
+                       
+                       M_MOV_IMM(replacementpoint, REG_ITMP3);
+                       M_PUSH(REG_ITMP3);
+
+                       /* jump to replacement function */
+
+                       M_MOV_IMM(asm_replacement_out, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
+               }
+       }
+       
        codegen_finish(m, cd, (s4) ((u1 *) cd->mcodeptr - cd->mcodebase));
 
        /* everything's ok */
index af77eeaa1b0499ffeb9cbb07c257511d48101a73..555ea37c3a32adb46714287399f7ee8cf1429fee 100644 (file)
@@ -26,9 +26,9 @@
 
    Authors: Christian Thalinger
 
-   Changes:
+   Changes: Edwin Steiner
 
-   $Id: md.c 4357 2006-01-22 23:33:38Z twisti $
+   $Id: md.c 4623 2006-03-16 00:05:18Z edwin $
 
 */
 
@@ -46,6 +46,8 @@
 #include "vm/signallocal.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/options.h" /* XXX debug */
+#include "vm/jit/disass.h" /* XXX debug */
 
 
 /* md_init *********************************************************************
@@ -177,6 +179,42 @@ u1 *md_codegen_findmethod(u1 *ra)
 }
 
 
+/* md_patch_replacement_point **************************************************
+
+   Patch the given replacement point.
+
+*******************************************************************************/
+
+void md_patch_replacement_point(rplpoint *rp)
+{
+    u8 mcode;
+
+       /* XXX this is probably unsafe! */
+
+       /* save the current machine code */
+       mcode = *(u8*)rp->pc;
+
+       /* write spinning instruction */
+       *(u2*)(rp->pc) = 0xebfe;
+
+       /* write 5th byte */
+       rp->pc[4] = (rp->mcode >> 32);
+
+       /* write first word */
+    *(u4*)(rp->pc) = (u4) rp->mcode;
+
+       /* store saved mcode */
+       rp->mcode = mcode;
+       
+       {
+               u1* u1ptr = rp->pc;
+               DISASSINSTR(u1ptr);
+               fflush(stdout);
+       }
+                       
+    /* XXX if required asm_cacheflush(rp->pc,8); */
+}
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
@@ -188,4 +226,5 @@ u1 *md_codegen_findmethod(u1 *ra)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */