/* src/vm/jit/intrp/codegen.c - code generator for Interpreter
- 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
- Anton Ertl
-
- Changes: Edwin Steiner
-
- $Id: codegen.c 5689 2006-10-05 10:50:39Z edwin $
-
*/
#include "vm/jit/intrp/codegen.h"
#include "vm/jit/intrp/intrp.h"
+#include "mm/memory.h"
+
#include "native/native.h"
+
#include "vm/builtin.h"
-#include "vm/class.h"
#include "vm/exceptions.h"
#include "vm/global.h"
-#include "vm/options.h"
#include "vm/stringlocal.h"
#include "vm/vm.h"
+
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/parse.h"
#include "vm/jit/patcher.h"
#include "vm/jit/stack.h"
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/class.h"
+#include "vmcore/options.h"
#define gen_branch(_inst) { \
/* include the interpreter generation functions *******************************/
-#include "vm/jit/intrp/java-gen.i"
+/* Do not use "java-gen.i", it does not work with builddir. */
+#include <java-gen.i>
typedef void (*genfunctionptr) (codegendata *);
s4 i, len, s1, s2, d;
basicblock *bptr;
instruction *iptr;
- exceptiontable *ex;
+ exception_entry *ex;
u2 currentline;
methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
unresolved_method *um;
lm = NULL;
bte = NULL;
+ /* determine stackframe size (in units of ptrint slots) */
+
+ cd->stackframesize = m->maxlocals;
+
+#if defined(ENABLE_THREADS)
+ if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ cd->stackframesize += 1;
+#endif
+
/* create method header */
- (void) dseg_addaddress(cd, jd->code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P); /* FrameSize */
+ (void) dseg_add_unique_address(cd, jd->code);
+ (void) dseg_add_unique_s4(cd, cd->stackframesize * SIZEOF_VOID_P);
#if defined(ENABLE_THREADS)
if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_adds4(cd, 1); /* IsSync */
+ (void) dseg_add_unique_s4(cd, 1);
else
#endif
- (void) dseg_adds4(cd, 0); /* IsSync */
+ (void) dseg_add_unique_s4(cd, 0);
- (void) dseg_adds4(cd, 0); /* IsLeaf */
- (void) dseg_adds4(cd, 0); /* IntSave */
- (void) dseg_adds4(cd, 0); /* FltSave */
+ (void) dseg_add_unique_s4(cd, 0);
+ (void) dseg_add_unique_s4(cd, 0);
+ (void) dseg_add_unique_s4(cd, 0);
dseg_addlinenumbertablesize(cd);
- (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
+ (void) dseg_add_unique_s4(cd, jd->exceptiontablelength);
/* create exception table */
- for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
- dseg_addtarget(cd, ex->start);
- dseg_addtarget(cd, ex->end);
- dseg_addtarget(cd, ex->handler);
- (void) dseg_addaddress(cd, ex->catchtype.any);
+ for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
+ dseg_add_target(cd, ex->start);
+ dseg_add_target(cd, ex->end);
+ dseg_add_target(cd, ex->handler);
+ (void) dseg_add_unique_address(cd, ex->catchtype.any);
}
#if 0
#if defined(ENABLE_THREADS)
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
- if (m->flags & ACC_STATIC)
+ if (m->flags & ACC_STATIC) {
gen_ACONST(cd, (java_objectheader *) m->class);
- else
+ }
+ else {
gen_ALOAD(cd, 0);
+ gen_DUP(cd);
+ gen_ASTORE(cd, index2offset(m->maxlocals));
+ }
gen_MONITORENTER(cd);
}
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
+ uf = NULL;
fieldtype = fi->type;
}
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
+ uf = NULL;
fieldtype = fi->type;
}
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
+ uf = NULL;
fieldtype = fi->type;
}
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
+ uf = NULL;
fieldtype = fi->type;
}
if (m->flags & ACC_STATIC) {
gen_ACONST(cd, (java_objectheader *) m->class);
} else {
- gen_ALOAD(cd, 0);
+ gen_ALOAD(cd, index2offset(m->maxlocals));
}
gen_MONITOREXIT(cd);
}
if (opt_verbosecall)
gen_TRACERETURN(cd, m);
- gen_IRETURN(cd, index2offset(cd->maxlocals));
+ gen_IRETURN(cd, index2offset(cd->stackframesize));
break;
case ICMD_LRETURN: /* ..., retvalue ==> ... */
if (m->flags & ACC_STATIC) {
gen_ACONST(cd, (java_objectheader *) m->class);
} else {
- gen_ALOAD(cd, 0);
+ gen_ALOAD(cd, index2offset(m->maxlocals));
}
gen_MONITOREXIT(cd);
}
if (opt_verbosecall)
gen_TRACELRETURN(cd, m);
- gen_LRETURN(cd, index2offset(cd->maxlocals));
+ gen_LRETURN(cd, index2offset(cd->stackframesize));
break;
case ICMD_RETURN: /* ... ==> ... */
if (m->flags & ACC_STATIC) {
gen_ACONST(cd, (java_objectheader *) m->class);
} else {
- gen_ALOAD(cd, 0);
+ gen_ALOAD(cd, index2offset(m->maxlocals));
}
gen_MONITOREXIT(cd);
}
if (opt_verbosecall)
gen_TRACERETURN(cd, m);
- gen_RETURN(cd, index2offset(cd->maxlocals));
+ gen_RETURN(cd, index2offset(cd->stackframesize));
break;
table += i;
while (--i >= 0) {
- dseg_addtarget(cd, BLOCK_OF(table->insindex));
+ dseg_add_target(cd, BLOCK_OF(table->insindex));
--table;
}
}
- /* length of dataseg after last dseg_addtarget is used by load */
+ /* length of dataseg after last dseg_add_target is used by load */
((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
break;
/* build jump table top down and use address of lowest entry */
while (--i >= 0) {
- dseg_addtarget(cd, BLOCK_OF(lookup->target.insindex));
- dseg_addaddress(cd, lookup->value);
+ dseg_add_target(cd, BLOCK_OF(lookup->target.insindex));
+ dseg_add_unique_address(cd, lookup->value);
lookup++;
}
codegen_addreference(cd, BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex));
}
- /* length of dataseg after last dseg_addtarget is used by load */
+ /* length of dataseg after last dseg_add_target is used by load */
((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
break;
break;
default:
- *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+ exceptions_throw_internalerror("Unknown ICMD %d during code generation",
+ iptr->opc);
return false;
} /* switch */
+-------------+ <-- stub
| codeptr |
+-------------+
- | maxlocals |
+ | framesize | (in ptrint units, does not include return address)
+-------------+
| TRANSLATE |
+-------------+
*******************************************************************************/
-#define COMPILERSTUB_DATASIZE 1
+#define COMPILERSTUB_DATASIZE 2
#define COMPILERSTUB_CODESIZE 4
#define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
Inst *s;
Inst *d;
codegendata *cd;
- codeinfo *code;
s4 dumpsize;
+ s4 stackframesize;
s = CNEW(Inst, COMPILERSTUB_SIZE);
d = s;
s = s + COMPILERSTUB_DATASIZE;
- /* Store the codeinfo pointer in the same place as in the
- methodheader for compiled methods. */
+ /* The codeinfo pointer is actually a pointer to the
+ methodinfo. This fakes a codeinfo structure. */
- code = code_codeinfo_new(m);
- d[0] = (Inst *) code;
+ d[0] = (Inst *) m;
+ d[1] = (Inst *) &d[0]; /* fake code->m */
/* mark start of dump memory area */
genarg_ainst(cd, s + 2);
if (m->flags & ACC_NATIVE) {
- genarg_i(cd, m->parseddesc->paramslots);
- } else {
- genarg_i(cd, m->maxlocals);
+ stackframesize = m->parseddesc->paramslots;
+ }
+ else {
+ stackframesize = m->maxlocals;
+
+#if defined(ENABLE_THREADS)
+ if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ stackframesize += 1;
+#endif
}
+ genarg_i(cd, stackframesize);
+
gen_BBSTART;
gen_TRANSLATE(cd, m);
gen_BBEND;
#else
u1 *cif;
#endif
+ s4 stackframesize;
/* get required compiler data */
- m = jd->m;
- cd = jd->cd;
- rd = jd->rd;
+ m = jd->m;
+ code = jd->code;
+ cd = jd->cd;
+ rd = jd->rd;
- /* create method header */
+ /* determine stackframe size (in units of ptrint) */
- /* Store the codeinfo pointer in the same place as in the
- methodheader for compiled methods. */
+ stackframesize = nmd->paramslots;
- code = code_codeinfo_new(m);
+ /* create method header */
- (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize */
- (void) dseg_adds4(cd, 0); /* IsSync */
- (void) dseg_adds4(cd, 0); /* IsLeaf */
- (void) dseg_adds4(cd, 0); /* IntSave */
- (void) dseg_adds4(cd, 0); /* FltSave */
+ (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
+ (void) dseg_add_unique_s4(cd, stackframesize * SIZEOF_VOID_P); /*FrameSize*/
+ (void) dseg_add_unique_s4(cd, 0); /* IsSync */
+ (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
+ (void) dseg_add_unique_s4(cd, 0); /* IntSave */
+ (void) dseg_add_unique_s4(cd, 0); /* FltSave */
dseg_addlinenumbertablesize(cd);
- (void) dseg_adds4(cd, 0); /* ExTableSize */
+ (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
#if defined(WITH_FFI)
/* prepare ffi cif structure */
/* create method header */
- (void) dseg_addaddress(cd, NULL); /* CodeinfoPointer */
- (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
- (void) dseg_adds4(cd, 0); /* IsSync */
- (void) dseg_adds4(cd, 0); /* IsLeaf */
- (void) dseg_adds4(cd, 0); /* IntSave */
- (void) dseg_adds4(cd, 0); /* FltSave */
+ (void) dseg_add_unique_address(cd, NULL); /* CodeinfoPointer */
+ (void) dseg_add_unique_s4(cd, md->paramslots * SIZEOF_VOID_P);/* FrameSize*/
+ (void) dseg_add_unique_s4(cd, 0); /* IsSync */
+ (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
+ (void) dseg_add_unique_s4(cd, 0); /* IntSave */
+ (void) dseg_add_unique_s4(cd, 0); /* FltSave */
dseg_addlinenumbertablesize(cd);
- (void) dseg_adds4(cd, 0); /* ExTableSize */
+ (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
/* generate code */