Merged revisions 8245-8298 via svnmerge from
[cacao.git] / src / vm / jit / i386 / md.c
index a11eee4e40d16cf157a93ee89b25193c9a57ed6f..7051bb72c3cd11f8fac5e1e79105ba576bf282be 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/i386/md.c - machine dependent i386 functions
 
-   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: Christian Thalinger
-
-   Changes: Edwin Steiner
-
-   $Id: md.c 4806 2006-04-21 11:07:43Z twisti $
+   $Id: md.c 8247 2007-07-31 12:06:44Z michi $
 
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
 
+#include "vm/types.h"
+
 #include "vm/global.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
+#include "vm/jit/md.h"
 
 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
-#include "vm/options.h" /* XXX debug */
+#include "vmcore/options.h" /* XXX debug */
 #include "vm/jit/disass.h" /* XXX debug */
 #endif
 
@@ -93,15 +90,15 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
    INVOKEVIRTUAL:
 
    8b 08                      mov    (%eax),%ecx
-   8b 81 00 00 00 00          mov    0x0(%ecx),%eax
-   ff d0                      call   *%eax
+   8b 91 00 00 00 00          mov    0x0(%ecx),%edx
+   ff d2                      call   *%edx
 
    INVOKEINTERFACE:
 
-   8b 00                      mov    (%eax),%eax
-   8b 88 00 00 00 00          mov    0x0(%eax),%ecx
-   8b 81 00 00 00 00          mov    0x0(%ecx),%eax
-   ff d0                      call   *%eax
+   8b 08                      mov    (%eax),%ecx
+   8b 89 00 00 00 00          mov    0x0(%ecx),%ecx
+   8b 91 00 00 00 00          mov    0x0(%ecx),%edx
+   ff d2                      call   *%edx
 
 *******************************************************************************/
 
@@ -121,16 +118,21 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 
        /* check for the different calls */
 
-       /* INVOKESTATIC/SPECIAL */
-
        if (mcode == 0xd1) {
-               /* patch address is 8-bytes before the call instruction */
+               /* INVOKESTATIC/SPECIAL */
 
-               pa = ra - 4;
+               /* patch address is 4-bytes before the call instruction */
 
-       } else if (mcode == 0xd0) {
+               pa = ra - 4;
+       }
+       else if (mcode == 0xd2) {
                /* INVOKEVIRTUAL/INTERFACE */
 
+               /* return NULL if no mptr was specified (used for replacement) */
+
+               if (mptr == NULL)
+                       return NULL;
+
                /* Get the offset from the instruction (the offset address is
                   4-bytes before the call instruction). */
 
@@ -139,31 +141,34 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
                /* add the offset to the method pointer */
 
                pa = mptr + offset;
-
-       else {
+       }
+       else {
                /* catch any problems */
 
-               assert(0);
+               pa = NULL; /* avoid warnings */
+
+               vm_abort("couldn't find a proper call instruction sequence");
        }
 
        return pa;
 }
 
 
-/* md_codegen_findmethod *******************************************************
+/* md_codegen_get_pv_from_pc ***************************************************
 
-   On this architecture just a wrapper function to codegen_findmethod.
+   On this architecture just a wrapper function to
+   codegen_get_pv_from_pc.
 
 *******************************************************************************/
 
-u1 *md_codegen_findmethod(u1 *ra)
+u1 *md_codegen_get_pv_from_pc(u1 *ra)
 {
        u1 *pv;
 
-       /* the the start address of the function which contains this
-       address from the method table */
+       /* Get the start address of the function which contains this
+       address from the method table. */
 
-       pv = codegen_findmethod(ra);
+       pv = codegen_get_pv_from_pc(ra);
 
        return pv;
 }
@@ -212,28 +217,43 @@ void md_dcacheflush(u1 *addr, s4 nbytes)
 
 *******************************************************************************/
 
-void md_patch_replacement_point(rplpoint *rp)
+#if defined(ENABLE_REPLACEMENT)
+void md_patch_replacement_point(codeinfo *code, s4 index, rplpoint *rp, u1 *savedmcode)
 {
-    u8 mcode;
+       u8 mcode;
 
        /* XXX this is probably unsafe! */
 
-       /* save the current machine code */
-       mcode = *(u8*)rp->pc;
+       if (index < 0) {
+               /* write spinning instruction */
+               *(u2*)(rp->pc) = 0xebfe;
 
-       /* write spinning instruction */
-       *(u2*)(rp->pc) = 0xebfe;
+               /* write 5th byte */
+               rp->pc[4] = savedmcode[4];
 
-       /* write 5th byte */
-       rp->pc[4] = (rp->mcode >> 32);
+               /* write first word */
+               *(u4*)(rp->pc) = *(u4*)(savedmcode);
+       }
+       else {
+               /* save the current machine code */
+               *(u4*)(savedmcode) = *(u4*)(rp->pc);
+               savedmcode[4] = rp->pc[4];
 
-       /* write first word */
-    *(u4*)(rp->pc) = (u4) rp->mcode;
+               /* build the machine code for the patch */
+               assert(0); /* XXX build trap instruction below */
+               mcode = 0;
 
-       /* store saved mcode */
-       rp->mcode = mcode;
-       
-#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
+               /* write spinning instruction */
+               *(u2*)(rp->pc) = 0xebfe;
+
+               /* write 5th byte */
+               rp->pc[4] = (mcode >> 32);
+
+               /* write first word */
+               *(u4*)(rp->pc) = (u4) mcode;
+       }
+
+#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) && 0
        {
                u1* u1ptr = rp->pc;
                DISASSINSTR(u1ptr);
@@ -243,6 +263,7 @@ void md_patch_replacement_point(rplpoint *rp)
                        
     /* XXX if required asm_cacheflush(rp->pc,8); */
 }
+#endif /* defined(ENABLE_REPLACEMENT) */
 
 /*
  * These are local overrides for various environment variables in Emacs.