* Removed all Id tags.
[cacao.git] / src / vm / jit / alpha / md.c
index 8ebd9428f78d6b9d921bef8c0a579fb122272acf..c069ebbe32371fd01d2d1a56b21a55f1550c1c61 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/alpha/md.c - machine dependent Alpha 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: Andreas Krall
-            Reinhard Grafl
-
-   Changes: Joseph Wenninger
-            Christian Thalinger
-                       Edwin Steiner
-
-   $Id: md.c 4651 2006-03-16 21:12:33Z edwin $
-
 */
 
 
@@ -54,10 +43,14 @@ extern void ieee_set_fp_control(unsigned long fp_control);
 
 #include "vm/exceptions.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.h"
-#include "vm/options.h" /* XXX debug */
+
+#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
+#include "vmcore/options.h" /* XXX debug */
 #include "vm/jit/disass.h" /* XXX debug */
+#endif
 
 
 /* global variables ***********************************************************/
@@ -113,25 +106,33 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
 }
 
 
-/* md_assembler_get_patch_address **********************************************
+/* md_get_method_patch_address *************************************************
 
    Gets the patch address of the currently compiled method. The offset
    is extracted from the load instruction(s) before the jump and added
    to the right base address (PV or REG_METHODPTR).
 
-   Machine code:
+   INVOKESTATIC/SPECIAL:
 
    a77bffb8    ldq     pv,-72(pv)
    6b5b4000    jsr     (pv)
 
-   or
+   INVOKEVIRTUAL:
 
+   a7900000    ldq     at,0(a0)
    a77c0000    ldq     pv,0(at)
    6b5b4000    jsr     (pv)
 
+   INVOKEINTERFACE:
+
+   a7900000    ldq     at,0(a0)
+   a79cff98    ldq     at,-104(at)
+   a77c0018    ldq     pv,24(at)
+   6b5b4000    jsr     (pv)
+
 *******************************************************************************/
 
-u1 *md_assembler_get_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
+u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 {
        u4  mcode;
        s4  offset;
@@ -177,6 +178,11 @@ u1 *md_assembler_get_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
                if ((mcode >> 16) == 0xa77c) {
                        /* in this case we use the passed method pointer */
 
+                       /* return NULL if no mptr was specified (used for replacement) */
+
+                       if (mptr == NULL)
+                               return NULL;
+
                        pa = mptr + offset;
 
                } else {
@@ -194,7 +200,7 @@ u1 *md_assembler_get_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 }
 
 
-/* md_codegen_findmethod *******************************************************
+/* md_codegen_get_pv_from_pc ***************************************************
 
    Machine code:
 
@@ -204,7 +210,7 @@ u1 *md_assembler_get_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 
 *******************************************************************************/
 
-u1 *md_codegen_findmethod(u1 *ra)
+u1 *md_codegen_get_pv_from_pc(u1 *ra)
 {
        u1 *pv;
        u4  mcode;
@@ -232,8 +238,8 @@ u1 *md_codegen_findmethod(u1 *ra)
 
                offset = (s2) (mcode & 0x0000ffff);
                pv += offset;
-
-       else {
+       }
+       else {
                /* get displacement of first instruction (lda) */
 
                assert((mcode >> 16) == 0x237a);
@@ -277,28 +283,39 @@ void md_icacheflush(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;
+       u4 mcode;
 
-       /* save the current machine code */
-       mcode = *(u4*)rp->pc;
+       if (index < 0) {
+               /* restore the patched-over instruction */
+               *(u4*)(rp->pc) = *(u4*)(savedmcode);
+       }
+       else {
+               /* save the current machine code */
+               *(u4*)(savedmcode) = *(u4*)(rp->pc);
 
-       /* write the new machine code */
-    *(u4*)(rp->pc) = (u4) rp->mcode;
+               /* build the machine code for the patch */
+               mcode = (0xa41f0000 | (EXCEPTION_HARDWARE_PATCHER));
 
-       /* store saved mcode */
-       rp->mcode = mcode;
+               /* write the new machine code */
+               *(u4*)(rp->pc) = mcode;
+       }
        
+#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) && 0
        {
                u1* u1ptr = rp->pc;
                DISASSINSTR(u1ptr);
                fflush(stdout);
        }
+#endif
                        
        /* flush instruction cache */
     md_icacheflush(rp->pc,4);
 }
+#endif /* defined(ENABLE_REPLACEMENT) */
+
 
 /*
  * These are local overrides for various environment variables in Emacs.