* src/vm/jit/parse.cpp,
[cacao.git] / src / vm / jit / intrp / codegen.c
index eb8bbd1d0b74726196cfa1cd498912be96a5d09e..4fbca4a70d15856dfe575b7af0675374fcef8cea 100644 (file)
@@ -1,9 +1,7 @@
 /* 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
-            Edwin Steiner
-
-   $Id: codegen.c 5980 2006-11-15 12:25:13Z twisti $
-
 */
 
 
 #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) { \
@@ -292,7 +286,6 @@ bool intrp_codegen(jitdata *jd)
        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;
@@ -320,38 +313,28 @@ bool intrp_codegen(jitdata *jd)
        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 */
@@ -363,9 +346,9 @@ bool intrp_codegen(jitdata *jd)
        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);
@@ -414,10 +397,9 @@ switch_again:
                case ICMD_NOP:        /* ...  ==> ...                                 */
                        break;
 
-               case ICMD_CHECKNULL_POP: /* ..., objectref  ==> ...                   */
+               case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
 
                        gen_CHECKNULL(cd);
-                       gen_POP(cd);
                        break;
 
                /* constant operations ************************************************/
@@ -1120,7 +1102,7 @@ dont_opt_IF_LCMPxx:
                        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);
@@ -1128,7 +1110,7 @@ dont_opt_IF_LCMPxx:
                        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);
@@ -1137,7 +1119,7 @@ dont_opt_IF_LCMPxx:
                        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);
@@ -1145,7 +1127,7 @@ dont_opt_IF_LCMPxx:
                        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);
@@ -1171,7 +1153,7 @@ dont_opt_IF_LCMPxx:
                        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);
@@ -1179,7 +1161,7 @@ dont_opt_IF_LCMPxx:
                        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);
@@ -1188,7 +1170,7 @@ dont_opt_IF_LCMPxx:
                        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);
@@ -1196,7 +1178,7 @@ dont_opt_IF_LCMPxx:
                        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);
@@ -1529,9 +1511,9 @@ dont_opt_IF_LCMPxx:
                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));
                                }
@@ -1548,9 +1530,9 @@ dont_opt_IF_LCMPxx:
                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));
                                }
@@ -1566,9 +1548,9 @@ dont_opt_IF_LCMPxx:
                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));
                                }
@@ -1612,12 +1594,12 @@ dont_opt_IF_LCMPxx:
                        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;
 
@@ -1644,15 +1626,15 @@ dont_opt_IF_LCMPxx:
                        /* 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;
 
@@ -1733,9 +1715,9 @@ dont_opt_IF_LCMPxx:
                                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);
                        }
@@ -1780,7 +1762,8 @@ dont_opt_IF_LCMPxx:
                        break;
 
                default:
-                       *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+                       exceptions_throw_internalerror("Unknown ICMD %d during code generation",
+                                                                                  iptr->opc);
                        return false;
        } /* switch */
                
@@ -1840,7 +1823,7 @@ dont_opt_IF_LCMPxx:
 
 *******************************************************************************/
 
-#define COMPILERSTUB_DATASIZE    1
+#define COMPILERSTUB_DATASIZE    2
 #define COMPILERSTUB_CODESIZE    4
 
 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
@@ -1851,9 +1834,8 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        Inst        *s;
        Inst        *d;
        codegendata *cd;
-       codeinfo    *code;
-       s4           dumpsize;
        s4           stackframesize;
+       int32_t      dumpmarker;
 
        s = CNEW(Inst, COMPILERSTUB_SIZE);
 
@@ -1862,15 +1844,15 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        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;
@@ -1886,7 +1868,7 @@ u1 *intrp_createcompilerstub(methodinfo *m)
                stackframesize = m->maxlocals;
 
 #if defined(ENABLE_THREADS)
-               if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               if (checksync && code_is_synchronized(code))
                        stackframesize += 1;
 #endif
        }
@@ -1908,7 +1890,7 @@ u1 *intrp_createcompilerstub(methodinfo *m)
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
        
        return (u1 *) s;
 }
@@ -2001,9 +1983,10 @@ u1 *intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* 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) */
 
@@ -2011,19 +1994,14 @@ u1 *intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* 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 */
@@ -2105,10 +2083,10 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
                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) {
@@ -2170,13 +2148,13 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
 
        /* 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 */
 
@@ -2221,12 +2199,12 @@ u1 *createcalljavafunction(methodinfo *m)
        jitdata            *jd;
        codegendata        *cd;
        registerdata       *rd;
-       s4                  dumpsize;
        methoddesc         *md;
+       int32_t             dumpmarker;
 
        /* mark dump memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* allocate memory */
 
@@ -2255,14 +2233,14 @@ u1 *createcalljavafunction(methodinfo *m)
 
        /* 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 */
@@ -2282,7 +2260,7 @@ u1 *createcalljavafunction(methodinfo *m)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return entrypoint;
 }