* src/vm/jit/code.h (codeinfo) [ENABLE_PROFILING]: Made frequency,
[cacao.git] / src / vm / jit / codegen-common.c
index 7be1d3e9e66997cb4206931db6546770a890aafc..2eb113e7156135198ca6c25ec7fc0d91eee3dacf 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/codegen-common.c - architecture independent code generator stuff
 
-   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: Reinhard Grafl
-            Andreas  Krall
-
-   Changes: Christian Thalinger
-            Joseph Wenninger
-                       Edwin Steiner
-
    All functions assume the following code area / data area layout:
 
    +-----------+
@@ -48,7 +39,7 @@
    memory. All functions writing values into the data area return the offset
    relative the begin of the code area (start of procedure).   
 
-   $Id: codegen-common.c 4775 2006-04-14 11:57:04Z twisti $
+   $Id: codegen-common.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -61,7 +52,7 @@
 #include "vm/types.h"
 
 #if defined(ENABLE_JIT)
-/* this is required for gen_resolvebranch and PATCHER_CALL_SIZE */
+/* this is required PATCHER_CALL_SIZE */
 # include "codegen.h"
 #endif
 
 #endif
 
 #include "mm/memory.h"
+
 #include "toolbox/avl.h"
+#include "toolbox/list.h"
 #include "toolbox/logging.h"
+
 #include "native/jni.h"
 #include "native/native.h"
 
-#if defined(USE_THREADS)
-# if defined(NATIVE_THREADS)
-#  include "threads/native/threads.h"
-# else
-#  include "threads/green/threads.h"
-# endif
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
 #endif
 
 #include "vm/exceptions.h"
-#include "vm/method.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 
 
 #include "vm/jit/dseg.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/md.h"
 #include "vm/jit/stacktrace.h"
 #include "vm/jit/replace.h"
 
+#if defined(ENABLE_INTRP)
+#include "vm/jit/intrp/intrp.h"
+#endif
+
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
 
 /* in this tree we store all method addresses *********************************/
 
-#if defined(__I386__) || defined(__X86_64__) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
 static avl_tree *methodtree = NULL;
 static s4 methodtree_comparator(const void *pc, const void *element);
-#endif
 
 
 /* codegen_init ****************************************************************
@@ -118,7 +116,6 @@ static s4 methodtree_comparator(const void *pc, const void *element);
 
 void codegen_init(void)
 {
-#if defined(__I386__) || defined(__X86_64__) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
        /* this tree is global, not method specific */
 
        if (!methodtree) {
@@ -139,7 +136,6 @@ void codegen_init(void)
                avl_insert(methodtree, mte);
 #endif /* defined(ENABLE_JIT) */
        }
-#endif /* defined(__I386__) || defined(__X86_64__) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
 }
 
 
@@ -165,12 +161,7 @@ void codegen_setup(jitdata *jd)
 
        /* initialize mcode variables */
 
-#if defined(__I386__) || defined(__X86_64__)   
-       cd->mcodeptr = cd->mcodebase;
-#else
-       cd->mcodeptr = (u4 *) cd->mcodebase;
-#endif
-
+       cd->mcodeptr     = cd->mcodebase;
        cd->lastmcodeptr = cd->mcodebase;
 
 #if defined(ENABLE_INTRP)
@@ -188,11 +179,9 @@ void codegen_setup(jitdata *jd)
                cd->superstarts = NULL;
        }
 #endif
-       
-       cd->dsegtop = DMNEW(u1, DSEGINITSIZE);
-       cd->dsegsize = DSEGINITSIZE;
-       cd->dsegtop += cd->dsegsize;
-       cd->dseglen = 0;
+
+       cd->dseg           = NULL;
+       cd->dseglen        = 0;
 
        cd->jumpreferences = NULL;
 
@@ -201,6 +190,7 @@ void codegen_setup(jitdata *jd)
 #endif
 
        cd->exceptionrefs  = NULL;
+/*     cd->patchrefs      = list_create_dump(OFFSET(patchref, linkage)); */
        cd->patchrefs      = NULL;
 
        cd->linenumberreferences = NULL;
@@ -209,18 +199,10 @@ void codegen_setup(jitdata *jd)
        cd->linenumbertab = 0;
        
        cd->method = m;
-       cd->exceptiontable = 0;
-       cd->exceptiontablelength = 0;
-
-       if (m->exceptiontablelength > 0) {
-               cd->exceptiontablelength = m->exceptiontablelength;
-               cd->exceptiontable = DMNEW(exceptiontable, m->exceptiontablelength + 1);
-       }
 
        cd->maxstack = m->maxstack;
-       cd->maxlocals = m->maxlocals;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        cd->threadcritcurrent.next = NULL;
        cd->threadcritcount = 0;
 #endif
@@ -245,7 +227,7 @@ void codegen_close(void)
 
 *******************************************************************************/
 
-s4 *codegen_increase(codegendata *cd, u1 *mcodeptr)
+void codegen_increase(codegendata *cd)
 {
        u1 *oldmcodebase;
 
@@ -262,16 +244,16 @@ s4 *codegen_increase(codegendata *cd, u1 *mcodeptr)
        cd->mcodesize *= 2;
        cd->mcodeend   = cd->mcodebase + cd->mcodesize;
 
+       /* set new mcodeptr */
+
+       cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
+
 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(ENABLE_INTRP)
        /* adjust the pointer to the last patcher position */
 
        if (cd->lastmcodeptr != NULL)
                cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
 #endif
-
-       /* return the new mcodeptr */
-
-       return (s4 *) (cd->mcodebase + (mcodeptr - oldmcodebase));
 }
 
 
@@ -305,35 +287,41 @@ u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
 #endif
 
 
-void codegen_addreference(codegendata *cd, basicblock *target, void *branchptr)
+/* codegen_add_branch_ref ******************************************************
+
+   Prepends an branch to the list.
+
+*******************************************************************************/
+
+void codegen_add_branch_ref(codegendata *cd, basicblock *target)
 {
-       s4 branchpos;
+       s4 branchmpc;
 
-       branchpos = (u1 *) branchptr - cd->mcodebase;
+       /* calculate the mpc of the branch instruction */
+
+       branchmpc = cd->mcodeptr - cd->mcodebase;
 
 #if defined(ENABLE_JIT)
        /* Check if the target basicblock has already a start pc, so the
           jump is backward and we can resolve it immediately. */
 
-       /* The interpreter uses absolute branches, so we do branch
-          resolving after the code and data segment move. */
-
-       if (target->mpc >= 0
+       if ((target->mpc >= 0)
 # if defined(ENABLE_INTRP)
+               /* The interpreter uses absolute branches, so we do branch
+                  resolving after the code and data segment move. */
+
                && !opt_intrp
 # endif
                )
        {
-               gen_resolvebranch((u1 *) cd->mcodebase + branchpos,
-                                                 branchpos,
-                                                 target->mpc);
-
-       } else
+               md_codegen_patch_branch(cd, branchmpc, target->mpc);
+       }
+       else
 #endif
        {
                branchref *br = DNEW(branchref);
 
-               br->branchpos = branchpos;
+               br->branchpos = branchmpc;
                br->next      = target->branchrefs;
 
                target->branchrefs = br;
@@ -341,28 +329,53 @@ void codegen_addreference(codegendata *cd, basicblock *target, void *branchptr)
 }
 
 
+/* codegen_resolve_branchrefs **************************************************
+
+   Resolves and patches the branch references of a given basic block.
+
+*******************************************************************************/
+
+void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
+{
+       branchref *br;
+       s4         branchmpc;
+       s4         targetmpc;
+
+       /* set target */
+
+       targetmpc = bptr->mpc;
+
+       for (br = bptr->branchrefs; br != NULL; br = br->next) {
+               branchmpc = br->branchpos;
+
+               md_codegen_patch_branch(cd, branchmpc, targetmpc);
+       }
+}
+
+
 /* codegen_add_exception_ref ***************************************************
 
-   Adds an exception branch to the list.
+   Prepends an exception branch to the list.
 
 *******************************************************************************/
 
-static void codegen_add_exception_ref(codegendata *cd, void *branchptr, s4 reg,
+static void codegen_add_exception_ref(codegendata *cd, s4 reg,
                                                                          functionptr function)
 {
-       s4            branchpos;
-       exceptionref *eref;
+       s4            branchmpc;
+       exceptionref *er;
 
-       branchpos = (u1 *) branchptr - cd->mcodebase;
+       branchmpc = cd->mcodeptr - cd->mcodebase;
 
-       eref = DNEW(exceptionref);
+       er = DNEW(exceptionref);
 
-       eref->branchpos = branchpos;
-       eref->reg       = reg;
-       eref->function  = function;
-       eref->next      = cd->exceptionrefs;
+       er->branchpos = branchmpc;
+       er->reg       = reg;
+       er->function  = function;
 
-       cd->exceptionrefs = eref;
+       er->next      = cd->exceptionrefs;
+
+       cd->exceptionrefs = er;
 }
 
 
@@ -372,10 +385,9 @@ static void codegen_add_exception_ref(codegendata *cd, void *branchptr, s4 reg,
 
 *******************************************************************************/
 
-void codegen_add_arithmeticexception_ref(codegendata *cd, void *branchptr)
+void codegen_add_arithmeticexception_ref(codegendata *cd)
 {
-       codegen_add_exception_ref(cd, branchptr, -1,
-                                                         STACKTRACE_inline_arithmeticexception);
+       codegen_add_exception_ref(cd, -1, STACKTRACE_inline_arithmeticexception);
 }
 
 
@@ -385,10 +397,9 @@ void codegen_add_arithmeticexception_ref(codegendata *cd, void *branchptr)
 
 *******************************************************************************/
 
-void codegen_add_arrayindexoutofboundsexception_ref(codegendata *cd,
-                                                                                                       void *branchptr, s4 reg)
+void codegen_add_arrayindexoutofboundsexception_ref(codegendata *cd, s4 reg)
 {
-       codegen_add_exception_ref(cd, branchptr, reg,
+       codegen_add_exception_ref(cd, reg,
                                                          STACKTRACE_inline_arrayindexoutofboundsexception);
 }
 
@@ -399,10 +410,9 @@ void codegen_add_arrayindexoutofboundsexception_ref(codegendata *cd,
 
 *******************************************************************************/
 
-void codegen_add_arraystoreexception_ref(codegendata *cd, void *branchptr)
+void codegen_add_arraystoreexception_ref(codegendata *cd)
 {
-       codegen_add_exception_ref(cd, branchptr, -1,
-                                                         STACKTRACE_inline_arraystoreexception);
+       codegen_add_exception_ref(cd, -1, STACKTRACE_inline_arraystoreexception);
 }
 
 
@@ -412,10 +422,9 @@ void codegen_add_arraystoreexception_ref(codegendata *cd, void *branchptr)
 
 *******************************************************************************/
 
-void codegen_add_classcastexception_ref(codegendata *cd, void *branchptr)
+void codegen_add_classcastexception_ref(codegendata *cd, s4 reg)
 {
-       codegen_add_exception_ref(cd, branchptr, -1,
-                                                         STACKTRACE_inline_classcastexception);
+       codegen_add_exception_ref(cd, reg, STACKTRACE_inline_classcastexception);
 }
 
 
@@ -425,10 +434,9 @@ void codegen_add_classcastexception_ref(codegendata *cd, void *branchptr)
 
 *******************************************************************************/
 
-void codegen_add_nullpointerexception_ref(codegendata *cd, void *branchptr)
+void codegen_add_nullpointerexception_ref(codegendata *cd)
 {
-       codegen_add_exception_ref(cd, branchptr, -1,
-                                                         STACKTRACE_inline_nullpointerexception);
+       codegen_add_exception_ref(cd, -1, STACKTRACE_inline_nullpointerexception);
 }
 
 
@@ -438,37 +446,44 @@ void codegen_add_nullpointerexception_ref(codegendata *cd, void *branchptr)
 
 *******************************************************************************/
 
-void codegen_add_fillinstacktrace_ref(codegendata *cd, void *branchptr)
+void codegen_add_fillinstacktrace_ref(codegendata *cd)
 {
-       codegen_add_exception_ref(cd, branchptr, -1,
-                                                         STACKTRACE_inline_fillInStackTrace);
+       codegen_add_exception_ref(cd, -1, STACKTRACE_inline_fillInStackTrace);
 }
 
 
-/* codegen_addpatchref *********************************************************
+/* codegen_add_patch_ref *******************************************************
 
-   Adds a new patcher reference to the list of patching positions.
+   Appends a new patcher reference to the list of patching positions.
 
 *******************************************************************************/
 
-void codegen_addpatchref(codegendata *cd, voidptr branchptr,
-                                                functionptr patcher, voidptr ref, s4 disp)
+void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref,
+                                                  s4 disp)
 {
        patchref *pr;
-       s4        branchpos;
+       s4        branchmpc;
 
-       branchpos = (u1 *) branchptr - cd->mcodebase;
+       branchmpc = cd->mcodeptr - cd->mcodebase;
 
        pr = DNEW(patchref);
 
-       pr->branchpos = branchpos;
+       pr->branchpos = branchmpc;
+       pr->disp      = disp;
        pr->patcher   = patcher;
        pr->ref       = ref;
-       pr->disp      = disp;
 
+/*     list_add_first(cd->patchrefs, pr); */
        pr->next      = cd->patchrefs;
        cd->patchrefs = pr;
 
+#if defined(ENABLE_JIT) && (defined(__ALPHA__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__))
+       /* Generate NOPs for opt_shownops. */
+
+       if (opt_shownops)
+               PATCHER_NOPS;
+#endif
+
 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__MIPS__) || defined(__X86_64__))
        /* On some architectures the patcher stub call instruction might
           be longer than the actual instruction generated.  On this
@@ -476,15 +491,14 @@ void codegen_addpatchref(codegendata *cd, voidptr branchptr,
           the basic block code generation is completed, we check the
           range and maybe generate some nop's. */
 
-       cd->lastmcodeptr = ((u1 *) branchptr) + PATCHER_CALL_SIZE;
+       cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
 #endif
 }
 
 
-#if defined(__I386__) || defined(__X86_64__) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
 /* methodtree_comparator *******************************************************
 
-   XXX
+   Comparator function used for the AVL tree of methods.
 
 *******************************************************************************/
 
@@ -517,7 +531,7 @@ static s4 methodtree_comparator(const void *pc, const void *element)
 
 /* codegen_insertmethod ********************************************************
 
-   XXX
+   Insert the machine code range of a method into the AVL tree of methods.
 
 *******************************************************************************/
 
@@ -539,13 +553,14 @@ void codegen_insertmethod(u1 *startpc, u1 *endpc)
 }
 
 
-/* codegen_findmethod **********************************************************
+/* codegen_get_pv_from_pc ******************************************************
 
-   XXX
+   Find the PV for the given PC by searching in the AVL tree of
+   methods.
 
 *******************************************************************************/
 
-u1 *codegen_findmethod(u1 *pc)
+u1 *codegen_get_pv_from_pc(u1 *pc)
 {
        methodtree_element  mtepc;
        methodtree_element *mte;
@@ -557,17 +572,106 @@ u1 *codegen_findmethod(u1 *pc)
 
        mte = avl_find(methodtree, &mtepc);
 
-       if (!mte) {
-               printf("Cannot find Java function at %p\n", (void *) (ptrint) pc);
-               assert(0);
+       if (mte == NULL) {
+               /* No method was found.  Let's dump a stacktrace. */
+
+               log_println("We received a SIGSEGV and tried to handle it, but we were");
+               log_println("unable to find a Java method at:");
+               log_println("");
+#if SIZEOF_VOID_P == 8
+               log_println("PC=0x%016lx", pc);
+#else
+               log_println("PC=0x%08x", pc);
+#endif
+               log_println("");
+               log_println("Dumping the current stacktrace:");
+
+               stacktrace_dump_trace(THREADOBJECT);
 
-               throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                                  "Cannot find Java function at %p", pc);
+               vm_abort("Exiting...");
        }
 
        return mte->startpc;
 }
-#endif /* defined(__I386__) || defined(__X86_64__) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
+
+
+/* codegen_get_pv_from_pc_nocheck **********************************************
+
+   Find the PV for the given PC by searching in the AVL tree of
+   methods.  This method does not check the return value and is used
+   by the profiler.
+
+*******************************************************************************/
+
+u1 *codegen_get_pv_from_pc_nocheck(u1 *pc)
+{
+       methodtree_element  mtepc;
+       methodtree_element *mte;
+
+       /* allocation of the search structure on the stack is much faster */
+
+       mtepc.startpc = pc;
+       mtepc.endpc   = pc;
+
+       mte = avl_find(methodtree, &mtepc);
+
+       if (mte == NULL)
+               return NULL;
+       else
+               return mte->startpc;
+}
+
+
+/* codegen_set_replacement_point_notrap ****************************************
+
+   Record the position of a non-trappable replacement point.
+
+*******************************************************************************/
+
+#if defined(ENABLE_REPLACEMENT)
+#if !defined(NDEBUG)
+void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
+#else
+void codegen_set_replacement_point_notrap(codegendata *cd)
+#endif
+{
+       assert(cd->replacementpoint);
+       assert(cd->replacementpoint->type == type);
+       assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
+
+       cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
+
+       cd->replacementpoint++;
+}
+#endif /* defined(ENABLE_REPLACEMENT) */
+
+
+/* codegen_set_replacement_point ***********************************************
+
+   Record the position of a trappable replacement point.
+
+*******************************************************************************/
+
+#if defined(ENABLE_REPLACEMENT)
+#if !defined(NDEBUG)
+void codegen_set_replacement_point(codegendata *cd, s4 type)
+#else
+void codegen_set_replacement_point(codegendata *cd)
+#endif
+{
+       assert(cd->replacementpoint);
+       assert(cd->replacementpoint->type == type);
+       assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
+
+       cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
+
+       cd->replacementpoint++;
+
+       /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
+
+       cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
+}
+#endif /* defined(ENABLE_REPLACEMENT) */
 
 
 /* codegen_finish **************************************************************
@@ -578,13 +682,11 @@ u1 *codegen_findmethod(u1 *pc)
 
 *******************************************************************************/
 
-void codegen_finish(jitdata *jd, s4 mcodelen)
+void codegen_finish(jitdata *jd)
 {
        codeinfo    *code;
        codegendata *cd;
-#if 0
        s4           mcodelen;
-#endif
 #if defined(ENABLE_INTRP)
        s4           ncodelen;
 #endif
@@ -605,8 +707,12 @@ void codegen_finish(jitdata *jd, s4 mcodelen)
        ncodelen = 0;
 #endif
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       extralen = sizeof(threadcritnode) * cd->threadcritcount;
+       /* calculate the code length */
+
+       mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
+
+#if defined(ENABLE_THREADS)
+       extralen = sizeof(critical_section_node_t) * cd->threadcritcount;
 #else
        extralen = 0;
 #endif
@@ -618,10 +724,7 @@ void codegen_finish(jitdata *jd, s4 mcodelen)
        }
 #endif
 
-#if 0
-       mcodelen = cd->mcodeptr - cd->mcodebase;
-#endif
-       alignedmcodelen = ALIGN(mcodelen, MAX_ALIGN);
+       alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
 
 #if defined(ENABLE_INTRP)
        if (opt_intrp)
@@ -631,7 +734,7 @@ void codegen_finish(jitdata *jd, s4 mcodelen)
        }
 #endif
 
-       cd->dseglen = ALIGN(cd->dseglen, MAX_ALIGN);
+       cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
        alignedlen = alignedmcodelen + cd->dseglen;
 
 #if defined(ENABLE_INTRP)
@@ -643,18 +746,21 @@ void codegen_finish(jitdata *jd, s4 mcodelen)
        /* allocate new memory */
 
        code->mcodelength = mcodelen + cd->dseglen;
-       code->mcode = CNEW(u1, alignedlen + extralen);
-
-       /* copy data and code to their new location */
-
-       MCOPY((void *) code->mcode, cd->dsegtop - cd->dseglen, u1, cd->dseglen);
-       MCOPY((void *) (code->mcode + cd->dseglen), cd->mcodebase, u1, mcodelen);
+       code->mcode       = CNEW(u1, alignedlen + extralen);
 
        /* set the entrypoint of the method */
        
        assert(code->entrypoint == NULL);
        code->entrypoint = epoint = (code->mcode + cd->dseglen);
 
+       /* fill the data segment (code->entrypoint must already be set!) */
+
+       dseg_finish(jd);
+
+       /* copy code to the new location */
+
+       MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
+
 #if defined(ENABLE_INTRP)
        /* relocate native dynamic superinstruction code (if any) */
 
@@ -712,24 +818,24 @@ void codegen_finish(jitdata *jd, s4 mcodelen)
                *((ptrint *) ((ptrint) epoint + cd->linenumbertablesizepos)) = lrtlen;
        }
 
+#if defined(ENABLE_REPLACEMENT)
        /* replacement point resolving */
        {
                int i;
                rplpoint *rp;
 
+               code->replacementstubs += (ptrint) epoint;
+
                rp = code->rplpoints;
                for (i=0; i<code->rplpointcount; ++i, ++rp) {
                        rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
-                       rp->outcode = (u1*) ((ptrint) epoint + (ptrint) rp->outcode);
                }
        }
+#endif /* defined(ENABLE_REPLACEMENT) */
 
-#if defined(__I386__) || defined(__X86_64__) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
        /* add method into methodtree to find the entrypoint */
 
        codegen_insertmethod(code->entrypoint, code->entrypoint + mcodelen);
-#endif
-
 
 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
        /* resolve data segment references */
@@ -737,18 +843,17 @@ void codegen_finish(jitdata *jd, s4 mcodelen)
        dseg_resolve_datareferences(jd);
 #endif
 
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        {
-               threadcritnode *n = (threadcritnode *) ((ptrint) code->mcode + alignedlen);
+               critical_section_node_t *n = (critical_section_node_t *) ((ptrint) code->mcode + alignedlen);
                s4 i;
-               threadcritnodetemp *nt = cd->threadcrit;
+               codegen_critical_section_t *nt = cd->threadcrit;
 
                for (i = 0; i < cd->threadcritcount; i++) {
                        n->mcodebegin = (u1 *) (ptrint) code->mcode + nt->mcodebegin;
                        n->mcodeend = (u1 *) (ptrint) code->mcode + nt->mcodeend;
                        n->mcoderestart = (u1 *) (ptrint) code->mcode + nt->mcoderestart;
-                       thread_registercritical(n);
+                       critical_register_critical_section(n);
                        n++;
                        nt = nt->next;
                }
@@ -788,6 +893,7 @@ codeinfo *codegen_createnativestub(functionptr f, methodinfo *m)
        jd->m     = m;
        jd->cd    = DNEW(codegendata);
        jd->rd    = DNEW(registerdata);
+       jd->flags = 0;
 
        /* Allocate codeinfo memory from the heap as we need to keep them. */
 
@@ -797,6 +903,16 @@ codeinfo *codegen_createnativestub(functionptr f, methodinfo *m)
 
        code = jd->code;
 
+       /* set the flags for the current JIT run */
+
+#if defined(ENABLE_PROFILING)
+       if (opt_prof)
+               jd->flags |= JITDATA_FLAG_INSTRUMENT;
+#endif
+
+       if (opt_verbosecall)
+               jd->flags |= JITDATA_FLAG_VERBOSECALL;
+
        /* setup code generation stuff */
 
 #if defined(ENABLE_JIT)
@@ -891,10 +1007,10 @@ codeinfo *codegen_createnativestub(functionptr f, methodinfo *m)
 void codegen_disassemble_nativestub(methodinfo *m, u1 *start, u1 *end)
 {
        printf("Native stub: ");
-       utf_fprint_classname(stdout, m->class->name);
+       utf_fprint_printable_ascii_classname(stdout, m->class->name);
        printf(".");
-       utf_fprint(stdout, m->name);
-       utf_fprint(stdout, m->descriptor);
+       utf_fprint_printable_ascii(stdout, m->name);
+       utf_fprint_printable_ascii(stdout, m->descriptor);
        printf("\n\nLength: %d\n\n", (s4) (end - start));
 
        DISASSEMBLE(start, end);
@@ -944,6 +1060,7 @@ void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra)
 
        stacktrace_create_native_stackframeinfo(sfi, pv, sp, ra);
 
+#if defined(ENABLE_JAVASE)
        /* add current JNI local references table to this thread */
 
        lrt->capacity    = LOCALREFTABLE_CAPACITY;
@@ -956,22 +1073,26 @@ void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra)
        MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
 
        LOCALREFTABLE = lrt;
+#endif
 }
 
 
 /* codegen_finish_native_call **************************************************
 
    Removes the stuff required for a native (JNI) function call.
+   Additionally it checks for an exceptions and in case, get the
+   exception object and clear the pointer.
 
 *******************************************************************************/
 
-void codegen_finish_native_call(u1 *datasp)
+java_objectheader *codegen_finish_native_call(u1 *datasp)
 {
-       stackframeinfo  *sfi;
-       stackframeinfo **psfi;
-       localref_table  *lrt;
-       localref_table  *plrt;
-       s4               localframes;
+       stackframeinfo     *sfi;
+       stackframeinfo    **psfi;
+       localref_table     *lrt;
+       localref_table     *plrt;
+       s4                  localframes;
+       java_objectheader  *e;
 
        /* get data structures from stack */
 
@@ -985,6 +1106,7 @@ void codegen_finish_native_call(u1 *datasp)
 
        *psfi = sfi->prev;
 
+#if defined(ENABLE_JAVASE)
        /* release JNI local references tables for this thread */
 
        lrt = LOCALREFTABLE;
@@ -1012,6 +1134,13 @@ void codegen_finish_native_call(u1 *datasp)
        /* now store the previous local frames in the thread structure */
 
        LOCALREFTABLE = lrt;
+#endif
+
+       /* get the exception and return it */
+
+       e = exceptions_get_and_clear_exception();
+
+       return e;
 }
 
 
@@ -1059,59 +1188,30 @@ void removenativestub(u1 *stub)
 
 *******************************************************************************/
 
-s4 codegen_reg_of_var(registerdata *rd, u2 opcode, stackptr v, s4 tempregnum)
+s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
 {
-       varinfo *var;
 
+#if 0
        /* Do we have to generate a conditional move?  Yes, then always
           return the temporary register.  The real register is identified
           during the store. */
 
        if (opcode & ICMD_CONDITION_MASK)
                return tempregnum;
-
-       switch (v->varkind) {
-       case TEMPVAR:
-               if (!(v->flags & INMEMORY))
-                       return(v->regoff);
-               break;
-
-       case STACKVAR:
-               var = &(rd->interfaces[v->varnum][v->type]);
-               v->regoff = var->regoff;
-               if (!(var->flags & INMEMORY))
-                       return(var->regoff);
-               break;
-
-       case LOCALVAR:
-               var = &(rd->locals[v->varnum][v->type]);
-               v->regoff = var->regoff;
-               if (!(var->flags & INMEMORY)) {
-#if defined(__ARM__) && defined(__ARMEL__)
-                       if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(var->regoff) == REG_SPLIT))
-                               return(PACK_REGS(GET_LOW_REG(var->regoff), GET_HIGH_REG(tempregnum)));
-#endif
-#if defined(__ARM__) && defined(__ARMEB__)
-                       if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(var->regoff) == REG_SPLIT))
-                               return(PACK_REGS(GET_LOW_REG(tempregnum), GET_HIGH_REG(var->regoff)));
 #endif
-                       return(var->regoff);
-               }
-               break;
 
-       case ARGVAR:
-               if (!(v->flags & INMEMORY)) {
+       if (!(v->flags & INMEMORY)) {
 #if defined(__ARM__) && defined(__ARMEL__)
-                       if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(v->regoff) == REG_SPLIT))
-                               return(PACK_REGS(GET_LOW_REG(v->regoff), GET_HIGH_REG(tempregnum)));
+               if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(v->vv.regoff) == REG_SPLIT))
+                       return PACK_REGS(GET_LOW_REG(v->vv.regoff),
+                                                        GET_HIGH_REG(tempregnum));
 #endif
 #if defined(__ARM__) && defined(__ARMEB__)
-                       if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(v->regoff) == REG_SPLIT))
-                               return(PACK_REGS(GET_LOW_REG(tempregnum), GET_HIGH_REG(v->regoff)));
+               if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(v->vv.regoff) == REG_SPLIT))
+                       return PACK_REGS(GET_LOW_REG(tempregnum),
+                                                        GET_HIGH_REG(v->vv.regoff));
 #endif
-                       return(v->regoff);
-               }
-               break;
+               return v->vv.regoff;
        }
 
 #if defined(ENABLE_STATISTICS)
@@ -1119,13 +1219,32 @@ s4 codegen_reg_of_var(registerdata *rd, u2 opcode, stackptr v, s4 tempregnum)
                count_spills_read++;
 #endif
 
-       v->flags |= INMEMORY;
-
        return tempregnum;
 }
 
+/* codegen_reg_of_dst **********************************************************
+
+   This function determines a register, to which the result of an
+   operation should go, when it is ultimatively intended to store the
+   result in iptr->dst.var.  If dst.var is assigned to an actual
+   register, this register will be returned.  Otherwise (when it is
+   spilled) this function returns tempregnum.  If not already done,
+   regoff and flags are set in the stack location.
+       
+   On ARM we have to check if a long/double variable is splitted
+   across reg/stack (HIGH_REG == REG_SPLIT). We return the actual
+   register of dst.var for LOW_REG and the tempregnum for HIGH_REG in such
+   cases.  (michi 2005/07/24)
+
+*******************************************************************************/
+
+s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
+{
+       return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
+}
+
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
 void codegen_threadcritrestart(codegendata *cd, int offset)
 {
        cd->threadcritcurrent.mcoderestart = offset;
@@ -1142,7 +1261,7 @@ void codegen_threadcritstop(codegendata *cd, int offset)
 {
        cd->threadcritcurrent.next = cd->threadcrit;
        cd->threadcritcurrent.mcodeend = offset;
-       cd->threadcrit = DNEW(threadcritnodetemp);
+       cd->threadcrit = DNEW(codegen_critical_section_t);
        *(cd->threadcrit) = cd->threadcritcurrent;
        cd->threadcritcount++;
 }