/* 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 $
-
*/
#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 ***********************************************************/
}
-/* 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;
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 {
}
-/* md_codegen_findmethod *******************************************************
+/* md_codegen_get_pv_from_pc ***************************************************
Machine code:
*******************************************************************************/
-u1 *md_codegen_findmethod(u1 *ra)
+u1 *md_codegen_get_pv_from_pc(u1 *ra)
{
u1 *pv;
u4 mcode;
offset = (s2) (mcode & 0x0000ffff);
pv += offset;
-
- } else {
+ }
+ else {
/* get displacement of first instruction (lda) */
assert((mcode >> 16) == 0x237a);
*******************************************************************************/
-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.