/* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
- Copyright (C) 1996-2005 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
+ Copyright (C) 1996-2005, 2006 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
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Authors: Andreas Krall
Reinhard Grafl
Changes: Joseph Wenninger
Christian Thalinger
Christian Ullrich
+ Edwin Steiner
- $Id: codegen.c 3719 2005-11-19 02:04:39Z edwin $
+ $Id: codegen.c 4653 2006-03-18 04:14:17Z edwin $
*/
+#include "config.h"
+
+#include <assert.h>
#include <stdio.h>
-#include "config.h"
#include "vm/types.h"
#include "md.h"
#include "md-abi.h"
-#include "md-abi.inc"
#include "vm/jit/alpha/arch.h"
#include "vm/jit/alpha/codegen.h"
-#include "cacao/cacao.h"
#include "native/jni.h"
#include "native/native.h"
#include "vm/builtin.h"
+#include "vm/exceptions.h"
#include "vm/global.h"
#include "vm/loader.h"
+#include "vm/options.h"
#include "vm/stringlocal.h"
-#include "vm/tables.h"
+#include "vm/vm.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen.inc"
+#include "vm/jit/codegen-common.h"
+#include "vm/jit/dseg.h"
#include "vm/jit/jit.h"
-
-#if defined(LSRA)
-# include "vm/jit/lsra.h"
-# include "vm/jit/lsra.inc"
-#endif
-
#include "vm/jit/parse.h"
#include "vm/jit/patcher.h"
#include "vm/jit/reg.h"
-#include "vm/jit/reg.inc"
+#include "vm/jit/replace.h"
+
+#if defined(ENABLE_LSRA)
+# include "vm/jit/allocator/lsra.h"
+#endif
/* codegen *********************************************************************
methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
builtintable_entry *bte;
methoddesc *md;
+ rplpoint *replacementpoint;
/* prevent compiler warnings */
parentargs_base = rd->memuse + savedregs_num;
#if defined(USE_THREADS) /* space to save argument of monitor_enter */
-
if (checksync && (m->flags & ACC_SYNCHRONIZED))
parentargs_base++;
-
#endif
/* create method header */
(void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
#if defined(USE_THREADS)
-
/* IsSync contains the offset relative to the stack pointer for the
argument of monitor_exit used in the exception handler. Since the
offset could be zero and give a wrong meaning of the flag it is
*/
if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
+ (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
else
-
#endif
-
- (void) dseg_adds4(cd, 0); /* IsSync */
+ (void) dseg_adds4(cd, 0); /* IsSync */
(void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
- (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);/* IntSave */
- (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);/* FltSave */
+ (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
+ (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
dseg_addlinenumbertablesize(cd);
/* initialize mcode variables */
- mcodeptr = (s4 *) cd->mcodebase;
- cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
- MCODECHECK(128 + m->paramcount);
+ mcodeptr = (s4 *) cd->mcodeptr;
/* create stack frame (if necessary) */
- if (parentargs_base) {
+ if (parentargs_base)
M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
- }
/* save return address and used callee saved registers */
s1 = rd->memuse;
- if (runverbose) {
+ if (opt_verbosecall) {
M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
for (p = 0; p < INT_ARG_CNT; p++)
if (m->flags & ACC_STATIC) {
disp = dseg_addaddress(cd, m->class);
- M_ALD(REG_ITMP1, REG_PV, disp);
- M_AST(REG_ITMP1, REG_SP, s1 * 8);
- M_INTMOVE(REG_ITMP1, rd->argintregs[0]);
+ M_ALD(rd->argintregs[0], REG_PV, disp);
+ M_AST(rd->argintregs[0], REG_SP, s1 * 8);
disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
M_ALD(REG_PV, REG_PV, disp);
M_JSR(REG_RA, REG_PV);
} else {
M_BEQZ(rd->argintregs[0], 0);
- codegen_addxnullrefs(cd, mcodeptr);
+ codegen_add_nullpointerexception_ref(cd, mcodeptr);
M_AST(rd->argintregs[0], REG_SP, s1 * 8);
disp = dseg_addaddress(cd, BUILTIN_monitorenter);
M_ALD(REG_PV, REG_PV, disp);
M_LDA(REG_PV, REG_RA, disp);
}
- if (runverbose) {
+ if (opt_verbosecall) {
for (p = 0; p < INT_ARG_CNT; p++)
M_LLD(rd->argintregs[p], REG_SP, p * 8);
/* call trace function */
- if (runverbose) {
+ if (opt_verbosecall) {
M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
M_AST(REG_RA, REG_SP, 1 * 8);
/* end of header generation */
+ replacementpoint = cd->code->rplpoints;
+
/* walk through all basic blocks */
for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
}
}
+ /* handle replacement points */
+
+ if (bptr->bitflags & BBFLAG_REPLACEMENT) {
+ replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
+
+ replacementpoint++;
+ }
+
/* copy interface registers to their destination */
src = bptr->instack;
len = bptr->indepth;
MCODECHECK(64+len);
-#ifdef LSRA
+#if defined(ENABLE_LSRA)
if (opt_lsra) {
while (src != NULL) {
len--;
}
src = src->prev;
}
-#ifdef LSRA
+#if defined(ENABLE_LSRA)
}
#endif
var_to_reg_int(s1, src, REG_ITMP1);
M_BEQZ(s1, 0);
- codegen_addxnullrefs(cd, mcodeptr);
+ codegen_add_nullpointerexception_ref(cd, mcodeptr);
break;
/* constant operations ************************************************/
var_to_reg_int(s2, src, REG_ITMP2);
d = reg_of_var(rd, iptr->dst, REG_RESULT);
M_BEQZ(s2, 0);
- codegen_addxdivrefs(cd, mcodeptr);
+ codegen_add_arithmeticexception_ref(cd, mcodeptr);
M_MOV(s1, rd->argintregs[0]);
M_MOV(s2, rd->argintregs[1]);
var_to_reg_int(s2, src, REG_ITMP2);
d = reg_of_var(rd, iptr->dst, REG_RESULT);
M_BEQZ(s2, 0);
- codegen_addxdivrefs(cd, mcodeptr);
+ codegen_add_arithmeticexception_ref(cd, mcodeptr);
M_MOV(s1, rd->argintregs[0]);
M_MOV(s2, rd->argintregs[1]);
M_LDA(REG_PV, REG_RA, -disp);
M_BEQZ(REG_RESULT, 0);
- codegen_addxstorerefs(cd, mcodeptr);
+ codegen_add_arraystoreexception_ref(cd, mcodeptr);
var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
var_to_reg_int(s2, src->prev, REG_ITMP2);
case ICMD_GETSTATIC: /* ... ==> ..., value */
/* op1 = type, val.a = field address */
- if (!iptr->val.a) {
+ if (iptr->val.a == NULL) {
disp = dseg_addaddress(cd, 0);
codegen_addpatchref(cd, mcodeptr,
disp = dseg_addaddress(cd, &(fi->value));
- if (!fi->class->initialized) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
codegen_addpatchref(cd, mcodeptr,
PATCHER_clinit, fi->class, 0);
case ICMD_PUTSTATIC: /* ..., value ==> ... */
/* op1 = type, val.a = field address */
- if (!iptr->val.a) {
+ if (iptr->val.a == NULL) {
disp = dseg_addaddress(cd, 0);
codegen_addpatchref(cd, mcodeptr,
disp = dseg_addaddress(cd, &(fi->value));
- if (!fi->class->initialized) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
codegen_addpatchref(cd, mcodeptr,
PATCHER_clinit, fi->class, 0);
/* op1 = type, val.a = field address (in */
/* following NOP) */
- if (!iptr[1].val.a) {
+ if (iptr[1].val.a == NULL) {
disp = dseg_addaddress(cd, 0);
codegen_addpatchref(cd, mcodeptr,
disp = dseg_addaddress(cd, &(fi->value));
- if (!fi->class->initialized) {
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
codegen_addpatchref(cd, mcodeptr,
PATCHER_clinit, fi->class, 0);
var_to_reg_int(s1, src, REG_ITMP1);
gen_nullptr_check(s1);
- if (!iptr->val.a) {
+ if (iptr->val.a == NULL) {
codegen_addpatchref(cd, mcodeptr,
PATCHER_get_putfield,
(unresolved_field *) iptr->target, 0);
var_to_reg_flt(s2, src, REG_FTMP2);
}
- if (!iptr->val.a) {
+ if (iptr->val.a == NULL) {
codegen_addpatchref(cd, mcodeptr,
PATCHER_get_putfield,
(unresolved_field *) iptr->target, 0);
var_to_reg_int(s1, src, REG_ITMP1);
gen_nullptr_check(s1);
- if (!iptr[1].val.a) {
+ if (iptr[1].val.a == NULL) {
codegen_addpatchref(cd, mcodeptr,
PATCHER_get_putfield,
(unresolved_field *) iptr[1].target, 0);
var_to_reg_int(s1, src, REG_ITMP1);
M_INTMOVE(s1, REG_ITMP1_XPTR);
+#ifdef ENABLE_VERIFIER
if (iptr->val.a) {
codegen_addpatchref(cd, mcodeptr,
PATCHER_athrow_areturn,
if (opt_showdisassemble)
M_NOP;
}
+#endif /* ENABLE_VERIFIER */
disp = dseg_addaddress(cd, asm_handle_exception);
M_ALD(REG_ITMP2, REG_PV, disp);
var_to_reg_int(s1, src, REG_RESULT);
M_INTMOVE(s1, REG_RESULT);
+#ifdef ENABLE_VERIFIER
if (iptr->val.a) {
codegen_addpatchref(cd, mcodeptr,
PATCHER_athrow_areturn,
if (opt_showdisassemble)
M_NOP;
}
+#endif /* ENABLE_VERIFIER */
goto nowperformreturn;
case ICMD_FRETURN: /* ..., retvalue ==> ... */
/* call trace function */
- if (runverbose) {
+ if (opt_verbosecall) {
M_LDA(REG_SP, REG_SP, -3 * 8);
M_AST(REG_RA, REG_SP, 0 * 8);
M_LST(REG_RESULT, REG_SP, 1 * 8);
if (iptr->op1 == true) {
M_BEQZ(REG_RESULT, 0);
- codegen_addxexceptionrefs(cd, mcodeptr);
+ codegen_add_fillinstacktrace_ref(cd, mcodeptr);
}
break;
case ICMD_INVOKESPECIAL:
M_BEQZ(rd->argintregs[0], 0);
- codegen_addxnullrefs(cd, mcodeptr);
+ codegen_add_nullpointerexception_ref(cd, mcodeptr);
/* fall through */
case ICMD_INVOKESTATIC:
OFFSET(vftbl_t, interfacetablelength));
M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
M_BLEZ(REG_ITMP3, 0);
- codegen_addxcastrefs(cd, mcodeptr);
+ codegen_add_classcastexception_ref(cd, mcodeptr);
M_ALD(REG_ITMP3, REG_ITMP2,
(s4) (OFFSET(vftbl_t, interfacetable[0]) -
superindex * sizeof(methodptr*)));
M_BEQZ(REG_ITMP3, 0);
- codegen_addxcastrefs(cd, mcodeptr);
+ codegen_add_classcastexception_ref(cd, mcodeptr);
if (!super)
M_BR(s3);
/* } */
M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
M_BEQZ(REG_ITMP3, 0);
- codegen_addxcastrefs(cd, mcodeptr);
+ codegen_add_classcastexception_ref(cd, mcodeptr);
}
d = reg_of_var(rd, iptr->dst, s1);
M_LDA(REG_PV, REG_RA, -disp);
M_BEQZ(REG_RESULT, 0);
- codegen_addxcastrefs(cd, mcodeptr);
+ codegen_add_classcastexception_ref(cd, mcodeptr);
var_to_reg_int(s1, src, REG_ITMP1);
d = reg_of_var(rd, iptr->dst, s1);
break;
case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
- /* op1 = dimension, val.a = array descriptor */
+ /* op1 = dimension, val.a = class */
/* check for negative sizes and copy sizes to stack if necessary */
/* is patcher function set? */
- if (iptr->target) {
+ if (iptr->val.a == NULL) {
disp = dseg_addaddress(cd, 0);
codegen_addpatchref(cd, mcodeptr,
- (functionptr) iptr->target, iptr->val.a,
+ PATCHER_builtin_multianewarray,
+ (constant_classref *) iptr->target,
disp);
if (opt_showdisassemble)
M_INTMOVE(REG_SP, rd->argintregs[2]);
- disp = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
+ disp = dseg_addaddress(cd, BUILTIN_multianewarray);
M_ALD(REG_PV, REG_PV, disp);
M_JSR(REG_RA, REG_PV);
disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
/* check for exception before result assignment */
M_BEQZ(REG_RESULT, 0);
- codegen_addxexceptionrefs(cd, mcodeptr);
+ codegen_add_fillinstacktrace_ref(cd, mcodeptr);
d = reg_of_var(rd, iptr->dst, REG_RESULT);
M_INTMOVE(REG_RESULT, d);
src = bptr->outstack;
len = bptr->outdepth;
MCODECHECK(64+len);
-#ifdef LSRA
+#if defined(ENABLE_LSRA)
if (!opt_lsra)
#endif
while (src) {
} /* if (bptr -> flags >= BBREACHED) */
} /* for basic block */
- codegen_createlinenumbertable(cd);
-
- {
-
- s4 *xcodeptr = NULL;
- branchref *bref;
-
- /* generate ArithmeticException stubs */
-
- for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
- gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
- bref->branchpos,
- (u1 *) mcodeptr - cd->mcodebase);
-
- MCODECHECK(100);
-
- M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
-
- if (xcodeptr != NULL) {
- disp = xcodeptr - mcodeptr - 1;
- M_BR(disp);
-
- } else {
- xcodeptr = mcodeptr;
-
- M_MOV(REG_PV, rd->argintregs[0]);
- M_MOV(REG_SP, rd->argintregs[1]);
- M_ALD(rd->argintregs[2],
- REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
- M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
-
- M_LDA(REG_SP, REG_SP, -1 * 8);
- M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
-
- disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
- M_ALD(REG_PV, REG_PV, disp);
- M_JSR(REG_RA, REG_PV);
- disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
- M_LDA(REG_PV, REG_RA, -disp);
-
- M_MOV(REG_RESULT, REG_ITMP1_XPTR);
-
- M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
- M_LDA(REG_SP, REG_SP, 1 * 8);
-
- disp = dseg_addaddress(cd, asm_handle_exception);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JMP(REG_ZERO, REG_ITMP3);
- }
- }
-
- /* generate ArrayIndexOutOfBoundsException stubs */
-
- xcodeptr = NULL;
-
- for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
- gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
- bref->branchpos,
- (u1*) mcodeptr - cd->mcodebase);
-
- MCODECHECK(100);
-
- /* move index register into REG_ITMP1 */
-
- M_MOV(bref->reg, REG_ITMP1);
- M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
-
- if (xcodeptr != NULL) {
- disp = xcodeptr - mcodeptr - 1;
- M_BR(disp);
-
- } else {
- xcodeptr = mcodeptr;
-
- M_MOV(REG_PV, rd->argintregs[0]);
- M_MOV(REG_SP, rd->argintregs[1]);
-
- if (m->isleafmethod)
- M_MOV(REG_RA, rd->argintregs[2]);
- else
- M_ALD(rd->argintregs[2],
- REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
-
- M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
- M_MOV(REG_ITMP1, rd->argintregs[4]);
-
- M_LDA(REG_SP, REG_SP, -2 * 8);
- M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
-
- if (m->isleafmethod)
- M_AST(REG_RA, REG_SP, 1 * 8);
-
- disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
- M_ALD(REG_PV, REG_PV, disp);
- M_JSR(REG_RA, REG_PV);
- disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
- M_LDA(REG_PV, REG_RA, -disp);
-
- M_MOV(REG_RESULT, REG_ITMP1_XPTR);
-
- if (m->isleafmethod)
- M_ALD(REG_RA, REG_SP, 1 * 8);
-
- M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
- M_LDA(REG_SP, REG_SP, 2 * 8);
-
- disp = dseg_addaddress(cd, asm_handle_exception);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JMP(REG_ZERO, REG_ITMP3);
- }
- }
-
- /* generate ArrayStoreException stubs */
-
- xcodeptr = NULL;
-
- for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
- gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
- bref->branchpos,
- (u1 *) mcodeptr - cd->mcodebase);
-
- MCODECHECK(100);
-
- M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
-
- if (xcodeptr != NULL) {
- disp = xcodeptr - mcodeptr - 1;
- M_BR(disp);
-
- } else {
- xcodeptr = mcodeptr;
-
- M_MOV(REG_PV, rd->argintregs[0]);
- M_MOV(REG_SP, rd->argintregs[1]);
- M_ALD(rd->argintregs[2],
- REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
- M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
-
- M_LDA(REG_SP, REG_SP, -1 * 8);
- M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
-
- disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
- M_ALD(REG_PV, REG_PV, disp);
- M_JSR(REG_RA, REG_PV);
- disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
- M_LDA(REG_PV, REG_RA, -disp);
-
- M_MOV(REG_RESULT, REG_ITMP1_XPTR);
-
- M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
- M_LDA(REG_SP, REG_SP, 1 * 8);
-
- disp = dseg_addaddress(cd, asm_handle_exception);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JMP(REG_ZERO, REG_ITMP3);
- }
- }
-
- /* generate ClassCastException stubs */
-
- xcodeptr = NULL;
-
- for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
- gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
- bref->branchpos,
- (u1 *) mcodeptr - cd->mcodebase);
-
- MCODECHECK(100);
-
- M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
-
- if (xcodeptr != NULL) {
- disp = xcodeptr - mcodeptr - 1;
- M_BR(disp);
-
- } else {
- xcodeptr = mcodeptr;
-
- M_MOV(REG_PV, rd->argintregs[0]);
- M_MOV(REG_SP, rd->argintregs[1]);
-
- if (m->isleafmethod)
- M_MOV(REG_RA, rd->argintregs[2]);
- else
- M_ALD(rd->argintregs[2],
- REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
-
- M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
+ dseg_createlinenumbertable(cd);
- M_LDA(REG_SP, REG_SP, -2 * 8);
- M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
- if (m->isleafmethod)
- M_AST(REG_RA, REG_SP, 1 * 8);
+ /* generate exception and patcher stubs */
- disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
- M_ALD(REG_PV, REG_PV, disp);
- M_JSR(REG_RA, REG_PV);
- disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
- M_LDA(REG_PV, REG_RA, -disp);
-
- M_MOV(REG_RESULT, REG_ITMP1_XPTR);
-
- if (m->isleafmethod)
- M_ALD(REG_RA, REG_SP, 1 * 8);
-
- M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
- M_LDA(REG_SP, REG_SP, 2 * 8);
-
- disp = dseg_addaddress(cd, asm_handle_exception);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JMP(REG_ZERO, REG_ITMP3);
- }
- }
-
- /* generate NullPointerException stubs */
-
- xcodeptr = NULL;
-
- for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
- gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
- bref->branchpos,
- (u1 *) mcodeptr - cd->mcodebase);
-
- MCODECHECK(100);
-
- M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
-
- if (xcodeptr != NULL) {
- disp = xcodeptr - mcodeptr - 1;
- M_BR(disp);
+ {
+ exceptionref *eref;
+ patchref *pref;
+ u4 mcode;
+ s4 *savedmcodeptr;
+ s4 *tmpmcodeptr;
- } else {
- xcodeptr = mcodeptr;
+ savedmcodeptr = NULL;
- M_MOV(REG_PV, rd->argintregs[0]);
- M_MOV(REG_SP, rd->argintregs[1]);
+ /* generate exception stubs */
- if (m->isleafmethod)
- M_MOV(REG_RA, rd->argintregs[2]);
- else
- M_ALD(rd->argintregs[2],
- REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
+ for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
+ gen_resolvebranch((u1 *) cd->mcodebase + eref->branchpos,
+ eref->branchpos,
+ (u1 *) mcodeptr - cd->mcodebase);
- M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
+ MCODECHECK(100);
- M_LDA(REG_SP, REG_SP, -2 * 8);
- M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
+ /* move index register into REG_ITMP1 */
- if (m->isleafmethod)
- M_AST(REG_RA, REG_SP, 1 * 8);
+ /* Check if the exception is an
+ ArrayIndexOutOfBoundsException. If so, move index register
+ into REG_ITMP1. */
- disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
- M_ALD(REG_PV, REG_PV, disp);
- M_JSR(REG_RA, REG_PV);
- disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
- M_LDA(REG_PV, REG_RA, -disp);
+ if (eref->reg != -1)
+ M_MOV(eref->reg, REG_ITMP1);
- M_MOV(REG_RESULT, REG_ITMP1_XPTR);
+ /* calcuate exception address */
- if (m->isleafmethod)
- M_ALD(REG_RA, REG_SP, 1 * 8);
+ M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
- M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
- M_LDA(REG_SP, REG_SP, 2 * 8);
+ /* move function to call into REG_ITMP3 */
- disp = dseg_addaddress(cd, asm_handle_exception);
+ disp = dseg_addaddress(cd, eref->function);
M_ALD(REG_ITMP3, REG_PV, disp);
- M_JMP(REG_ZERO, REG_ITMP3);
- }
- }
-
- /* generate exception check stubs */
- xcodeptr = NULL;
+ if (savedmcodeptr != NULL) {
+ disp = savedmcodeptr - mcodeptr - 1;
+ M_BR(disp);
- for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
- gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
- bref->branchpos,
- (u1 *) mcodeptr - cd->mcodebase);
+ } else {
+ savedmcodeptr = mcodeptr;
- MCODECHECK(100);
+ M_MOV(REG_PV, rd->argintregs[0]);
+ M_MOV(REG_SP, rd->argintregs[1]);
- M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
+ if (m->isleafmethod)
+ M_MOV(REG_RA, rd->argintregs[2]);
+ else
+ M_ALD(rd->argintregs[2],
+ REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
- if (xcodeptr != NULL) {
- disp = xcodeptr - mcodeptr - 1;
- M_BR(disp);
+ M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
+ M_MOV(REG_ITMP1, rd->argintregs[4]);
- } else {
- xcodeptr = mcodeptr;
+ M_LDA(REG_SP, REG_SP, -2 * 8);
+ M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
- M_MOV(REG_PV, rd->argintregs[0]);
- M_MOV(REG_SP, rd->argintregs[1]);
- M_ALD(rd->argintregs[2],
- REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
- M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
+ if (m->isleafmethod)
+ M_AST(REG_RA, REG_SP, 1 * 8);
- M_LDA(REG_SP, REG_SP, -1 * 8);
- M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
+ M_MOV(REG_ITMP3, REG_PV);
+ M_JSR(REG_RA, REG_PV);
+ disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
+ M_LDA(REG_PV, REG_RA, -disp);
- disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
- M_ALD(REG_PV, REG_PV, disp);
- M_JSR(REG_RA, REG_PV);
- disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
- M_LDA(REG_PV, REG_RA, -disp);
+ M_MOV(REG_RESULT, REG_ITMP1_XPTR);
- M_MOV(REG_RESULT, REG_ITMP1_XPTR);
+ if (m->isleafmethod)
+ M_ALD(REG_RA, REG_SP, 1 * 8);
- M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
- M_LDA(REG_SP, REG_SP, 1 * 8);
+ M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
+ M_LDA(REG_SP, REG_SP, 2 * 8);
- disp = dseg_addaddress(cd, asm_handle_exception);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JMP(REG_ZERO, REG_ITMP3);
+ disp = dseg_addaddress(cd, asm_handle_exception);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_JMP(REG_ZERO, REG_ITMP3);
+ }
}
- }
- /* generate patcher stub call code */
- {
- patchref *pref;
- u4 mcode;
- s4 *tmpmcodeptr;
+ /* generate code patching stub call code */
for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
/* check code segment size */
MCODECHECK(100);
- /* Get machine code which is patched back in later. The call is */
- /* 1 instruction word long. */
+ /* Get machine code which is patched back in later. The
+ call is 1 instruction word long. */
- xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
- mcode = *xcodeptr;
+ savedmcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
+ mcode = *savedmcodeptr;
- /* patch in the call to call the following code (done at compile */
- /* time) */
+ /* Patch in the call to call the following code (done at
+ compile time). */
tmpmcodeptr = mcodeptr; /* save current mcodeptr */
- mcodeptr = xcodeptr; /* set mcodeptr to patch position */
+ mcodeptr = savedmcodeptr; /* set mcodeptr to patch position */
- M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
+ M_BSR(REG_ITMP3, tmpmcodeptr - (savedmcodeptr + 1));
mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
M_ALD(REG_ITMP3, REG_PV, disp);
M_JMP(REG_ZERO, REG_ITMP3);
}
- }
+
+ /* generate replacement-out stubs */
+
+ {
+ int i;
+
+ replacementpoint = cd->code->rplpoints;
+ for (i=0; i<cd->code->rplpointcount; ++i, ++replacementpoint) {
+ /* check code segment size */
+
+ MCODECHECK(100);
+
+ /* note start of stub code */
+
+ replacementpoint->outcode = (u1*) (ptrint)((u1*)mcodeptr - cd->mcodebase);
+
+ /* make machine code for patching */
+
+ tmpmcodeptr = mcodeptr;
+ mcodeptr = (s4*) &(replacementpoint->mcode);
+
+ disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
+ M_BR(disp);
+
+ mcodeptr = tmpmcodeptr;
+
+ /* create stack frame */
+
+ M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
+
+ /* push address of `rplpoint` struct */
+
+ disp = dseg_addaddress(cd, replacementpoint);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_AST(REG_ITMP3, REG_SP, 0 * 8);
+
+ /* jump to replacement function */
+
+ disp = dseg_addaddress(cd, asm_replacement_out);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_JMP(REG_ZERO, REG_ITMP3);
+ }
+ }
}
codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
*******************************************************************************/
-#define COMPSTUBSIZE 3
+#define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
+#define COMPILERSTUB_CODESIZE 3 * 4
-functionptr createcompilerstub(methodinfo *m)
+#define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
+
+
+u1 *createcompilerstub(methodinfo *m)
{
- u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
- s4 *mcodeptr = (s4 *) s; /* code generation pointer */
+ u1 *s; /* memory to hold the stub */
+ ptrint *d;
+ s4 *mcodeptr; /* code generation pointer */
+
+ s = CNEW(u1, COMPILERSTUB_SIZE);
+
+ /* set data pointer and code pointer */
+
+ d = (ptrint *) s;
+ s = s + COMPILERSTUB_DATASIZE;
+
+ mcodeptr = (s4 *) s;
- /* code for the stub */
- M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
- M_JMP(0, REG_PV); /* jump to the compiler, return address
- in reg 0 is used as method pointer */
- s[1] = (ptrint) m; /* literals to be adressed */
- s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
-
-#if defined(STATISTICS)
+ /* Store the methodinfo* in the same place as in the methodheader
+ for compiled methods. */
+
+ d[0] = (ptrint) asm_call_jit_compiler;
+ d[1] = (ptrint) m;
+
+ /* code for the stub */
+
+ M_ALD(REG_ITMP1, REG_PV, -1 * 8); /* load methodinfo pointer */
+ M_ALD(REG_PV, REG_PV, -2 * 8); /* load pointer to the compiler */
+ M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
+
+#if defined(ENABLE_STATISTICS)
if (opt_stat)
- count_cstub_len += COMPSTUBSIZE * 8;
+ count_cstub_len += COMPILERSTUB_SIZE;
#endif
- return (functionptr) s;
+ return s;
}
*******************************************************************************/
-functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
- registerdata *rd, methoddesc *nmd)
+u1 *createnativestub(functionptr f, methodinfo *m, codegendata *cd,
+ registerdata *rd, methoddesc *nmd)
{
s4 *mcodeptr; /* code generation pointer */
s4 stackframesize; /* size of stackframe if needed */
/* initialize mcode variables */
- mcodeptr = (s4 *) cd->mcodebase;
- cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
+ mcodeptr = (s4 *) cd->mcodeptr;
/* generate stub code */
/* call trace function */
- if (runverbose) {
+ if (opt_verbosecall) {
/* save integer argument registers */
for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
funcdisp = dseg_addaddress(cd, f);
-#if !defined(ENABLE_STATICVM)
+#if !defined(WITH_STATIC_CLASSPATH)
if (f == NULL) {
codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
/* put env into first argument register */
- disp = dseg_addaddress(cd, &env);
+ disp = dseg_addaddress(cd, _Jv_env);
M_ALD(rd->argintregs[0], REG_PV, disp);
/* do the native function call */
/* call finished trace */
- if (runverbose) {
+ if (opt_verbosecall) {
/* just restore the value we need, don't care about the other */
if (IS_INT_LNG_TYPE(md->returntype.type))
{
patchref *pref;
- s4 *xcodeptr;
u4 mcode;
+ s4 *savedmcodeptr;
s4 *tmpmcodeptr;
- /* there can only be one <clinit> ref entry */
+ /* there can only be one <clinit> ref entry */
+
pref = cd->patchrefs;
for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
- /* Get machine code which is patched back in later. The call is */
- /* 1 instruction word long. */
+ /* Get machine code which is patched back in later. The
+ call is 1 instruction word long. */
- xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
- mcode = (u4) *xcodeptr;
+ savedmcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
+ mcode = (u4) *savedmcodeptr;
/* patch in the call to call the following code (done at compile */
/* time) */
tmpmcodeptr = mcodeptr; /* save current mcodeptr */
- mcodeptr = xcodeptr; /* set mcodeptr to patch position */
+ mcodeptr = savedmcodeptr; /* set mcodeptr to patch position */
- M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
+ M_BSR(REG_ITMP3, tmpmcodeptr - (savedmcodeptr + 1));
mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
- /* create stack frame */
+ /* create stack frame */
M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
- return m->entrypoint;
+ return cd->code->entrypoint;
}
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/