/* src/vm/jit/intrp/codegen.c - code generator for Interpreter
- 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
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
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 5835 2006-10-26 11:29:42Z edwin $
-
*/
#include "vm/jit/intrp/codegen.h"
#include "vm/jit/intrp/intrp.h"
-#include "native/native.h"
-#include "vm/builtin.h"
-#include "vm/class.h"
-#include "vm/exceptions.h"
+#include "mm/memory.h"
+
+#include "native/native.hpp"
+
+#include "vm/jit/builtin.hpp"
+#include "vm/class.hpp"
+#include "vm/exceptions.hpp"
#include "vm/global.h"
#include "vm/options.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
+
#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
+#include "vm/jit/codegen-common.hpp"
#include "vm/jit/dseg.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/parse.h"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/parse.hpp"
#include "vm/jit/patcher.h"
#include "vm/jit/stack.h"
+#include "vm/jit/stacktrace.hpp"
#define gen_branch(_inst) { \
s4 i, len, s1, s2, d;
basicblock *bptr;
instruction *iptr;
- exception_entry *ex;
u2 currentline;
methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
unresolved_method *um;
cd->stackframesize = m->maxlocals;
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ if (checksync && code_is_synchronized(code))
cd->stackframesize += 1;
#endif
/* create method header */
- (void) dseg_addaddress(cd, jd->code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, cd->stackframesize * 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 */
- else
-#endif
- (void) dseg_adds4(cd, 0); /* IsSync */
-
- (void) dseg_adds4(cd, 0); /* IsLeaf */
- (void) dseg_adds4(cd, 0); /* IntSave */
- (void) dseg_adds4(cd, 0); /* FltSave */
+ code->synchronizedoffset = rd->memuse * 8;
- dseg_addlinenumbertablesize(cd);
+ /* REMOVEME: We still need it for exception handling in assembler. */
- (void) dseg_adds4(cd, jd->exceptiontablelength); /* ExTableSize */
+ if (code_is_leafmethod(code))
+ (void) dseg_add_unique_s4(cd, 1);
+ else
+ (void) dseg_add_unique_s4(cd, 0);
- /* create exception table */
+ (void) dseg_add_unique_s4(cd, 0);
+ (void) dseg_add_unique_s4(cd, 0);
- for (ex = jd->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);
- }
+ dseg_addlinenumbertablesize(cd);
#if 0
/* initialize mcode variables */
gen_BBSTART;
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ if (checksync && code_is_synchronized(code)) {
if (m->flags & ACC_STATIC) {
- gen_ACONST(cd, (java_objectheader *) m->class);
+ gen_ACONST(cd, (java_objectheader *) m->clazz);
}
else {
gen_ALOAD(cd, 0);
case TYPE_INT:
if (fi == NULL)
gen_PATCHER_GETSTATIC_INT(cd, 0, uf);
- else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
gen_PATCHER_GETSTATIC_CLINIT_INT(cd, 0, fi);
else
gen_GETSTATIC_INT(cd, (u1 *) &(fi->value.i), fi);
case TYPE_FLT:
if (fi == NULL)
gen_PATCHER_GETSTATIC_FLOAT(cd, 0, uf);
- else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
gen_PATCHER_GETSTATIC_CLINIT_FLOAT(cd, 0, fi);
else
gen_GETSTATIC_FLOAT(cd, (u1 *) &(fi->value.i), fi);
case TYPE_DBL:
if (fi == NULL)
gen_PATCHER_GETSTATIC_LONG(cd, 0, uf);
- else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
gen_PATCHER_GETSTATIC_CLINIT_LONG(cd, 0, fi);
else
gen_GETSTATIC_LONG(cd, (u1 *) &(fi->value.l), fi);
case TYPE_ADR:
if (fi == NULL)
gen_PATCHER_GETSTATIC_CELL(cd, 0, uf);
- else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
gen_PATCHER_GETSTATIC_CLINIT_CELL(cd, 0, fi);
else
gen_GETSTATIC_CELL(cd, (u1 *) &(fi->value.a), fi);
case TYPE_INT:
if (fi == NULL)
gen_PATCHER_PUTSTATIC_INT(cd, 0, uf);
- else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
gen_PATCHER_PUTSTATIC_CLINIT_INT(cd, 0, fi);
else
gen_PUTSTATIC_INT(cd, (u1 *) &(fi->value.i), fi);
case TYPE_FLT:
if (fi == NULL)
gen_PATCHER_PUTSTATIC_FLOAT(cd, 0, uf);
- else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
gen_PATCHER_PUTSTATIC_CLINIT_FLOAT(cd, 0, fi);
else
gen_PUTSTATIC_FLOAT(cd, (u1 *) &(fi->value.i), fi);
case TYPE_DBL:
if (fi == NULL)
gen_PATCHER_PUTSTATIC_LONG(cd, 0, uf);
- else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
gen_PATCHER_PUTSTATIC_CLINIT_LONG(cd, 0, fi);
else
gen_PUTSTATIC_LONG(cd, (u1 *) &(fi->value.l), fi);
case TYPE_ADR:
if (fi == NULL)
gen_PATCHER_PUTSTATIC_CELL(cd, 0, uf);
- else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
gen_PATCHER_PUTSTATIC_CLINIT_CELL(cd, 0, fi);
else
gen_PUTSTATIC_CELL(cd, (u1 *) &(fi->value.a), fi);
case ICMD_FRETURN: /* ..., retvalue ==> ... */
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ if (checksync && code_is_synchronized(code)) {
if (m->flags & ACC_STATIC) {
- gen_ACONST(cd, (java_objectheader *) m->class);
+ gen_ACONST(cd, (java_objectheader *) m->clazz);
} else {
gen_ALOAD(cd, index2offset(m->maxlocals));
}
case ICMD_DRETURN: /* ..., retvalue ==> ... */
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ if (checksync && code_is_synchronized(code)) {
if (m->flags & ACC_STATIC) {
- gen_ACONST(cd, (java_objectheader *) m->class);
+ gen_ACONST(cd, (java_objectheader *) m->clazz);
} else {
gen_ALOAD(cd, index2offset(m->maxlocals));
}
case ICMD_RETURN: /* ... ==> ... */
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ if (checksync && code_is_synchronized(code)) {
if (m->flags & ACC_STATIC) {
- gen_ACONST(cd, (java_objectheader *) m->class);
+ gen_ACONST(cd, (java_objectheader *) m->clazz);
} else {
gen_ALOAD(cd, index2offset(m->maxlocals));
}
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;
md = lm->parseddesc;
s1 = OFFSET(vftbl_t, interfacetable[0]) -
- sizeof(methodptr*) * lm->class->index;
+ sizeof(methodptr*) * lm->clazz->index;
- s2 = sizeof(methodptr) * (lm - lm->class->methods);
+ s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, lm);
}
break;
default:
- *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+ exceptions_throw_internalerror("Unknown ICMD %d during code generation",
+ iptr->opc);
return false;
} /* switch */
*******************************************************************************/
-#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;
+ int32_t dumpmarker;
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 */
- dumpsize = dump_size();
+ DMARKER;
cd = DNEW(codegendata);
cd->mcodeptr = (u1 *) s;
stackframesize = m->maxlocals;
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ if (checksync && code_is_synchronized(code))
stackframesize += 1;
#endif
}
/* release dump area */
- dump_release(dumpsize);
+ DRELEASE;
return (u1 *) s;
}
/* 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;
/* determine stackframe size (in units of ptrint) */
/* create method header */
- /* Store the codeinfo pointer in the same place as in the
- methodheader for compiled methods. */
-
- code = code_codeinfo_new(m);
-
- (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, stackframesize * 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 */
assert(false);
}
- av_ptr(alist, _Jv_JNIEnv *, _Jv_env);
+ av_ptr(alist, _Jv_JNIEnv *, VM_get_jnienv());
if (m->flags & ACC_STATIC)
- av_ptr(alist, classinfo *, m->class);
+ av_ptr(alist, classinfo *, m->clazz);
for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
switch (md->paramtypes[i].type) {
/* pass env pointer */
- penv = (_Jv_JNIEnv *) _Jv_env;
+ penv = (_Jv_JNIEnv *) VM_get_jnienv();
*pvalues++ = &penv;
/* for static methods, pass class pointer */
if (m->flags & ACC_STATIC)
- *pvalues++ = &m->class;
+ *pvalues++ = &m->clazz;
/* pass parameter to native function */
jitdata *jd;
codegendata *cd;
registerdata *rd;
- s4 dumpsize;
methoddesc *md;
+ int32_t dumpmarker;
/* mark dump memory */
- dumpsize = dump_size();
+ DMARKER;
/* allocate memory */
/* 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 */
/* release memory */
- dump_release(dumpsize);
+ DRELEASE;
return entrypoint;
}