/* 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 4838 2006-04-25 15:46:06Z edwin $
-
*/
#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
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
*******************************************************************************/
/* 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). */
/* add the offset to the method pointer */
pa = mptr + offset;
-
- } else {
+ }
+ else {
/* catch any problems */
pa = NULL; /* avoid warnings */
- assert(0);
+
+ 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;
}
*******************************************************************************/
-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);
/* XXX if required asm_cacheflush(rp->pc,8); */
}
+#endif /* defined(ENABLE_REPLACEMENT) */
/*
* These are local overrides for various environment variables in Emacs.