GNU header update.
[cacao.git] / src / vm / jit / i386 / codegen.c
index b7e7167b628f85cc99aa62c0d94351c0b42a846b..017dced78f0f02a871400dc9383d9f88dede14de 100644 (file)
@@ -1,10 +1,9 @@
-/* jit/i386/codegen.c - machine code generator for i386
+/* vm/jit/i386/codegen.c - machine code generator for i386
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Institut f. Computersprachen, TU Wien
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
-   S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
-   J. Wenninger
+   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
 
    This file is part of CACAO.
 
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.c 1461 2004-11-05 16:23:47Z twisti $
+   Changes: Joseph Wenninger
+
+   $Id: codegen.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
+
 #define _GNU_SOURCE
 
-#include "config.h"
-#include "global.h"
 #include <stdio.h>
-#include <signal.h>
-#include <sys/ucontext.h>
-#include "types.h"
-#include "main.h"
-#include "builtin.h"
-#include "asmpart.h"
-#include "exceptions.h"
-#include "jni.h"
-#include "loader.h"
-#include "tables.h"
-#include "native.h"
-#include "jit/jit.h"
-#include "jit/parse.h"
-#include "jit/reg.h"
-#include "jit/i386/codegen.h"
-#include "jit/i386/emitfuncs.h"
+#include <ucontext.h>
+#ifdef __FreeBSD__
+#include <machine/signal.h>
+#endif
+
+#include "config.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/tables.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/parse.h"
+#include "vm/jit/reg.h"
+#include "vm/jit/i386/codegen.h"
+#include "vm/jit/i386/emitfuncs.h"
+#include "vm/jit/i386/types.h"
+#include "vm/jit/i386/asmoffsets.h"
 
 
 /* register descripton - array ************************************************/
 
 /* #define REG_END   -1        last entry in tables */
 
-int nregdescint[] = {
+static int nregdescint[] = {
     REG_RET, REG_RES, REG_RES, REG_TMP, REG_RES, REG_SAV, REG_SAV, REG_SAV,
     REG_END
 };
 
 
-int nregdescfloat[] = {
+static int nregdescfloat[] = {
   /* rounding problems with callee saved registers */
 /*      REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_RES, REG_RES, */
 /*      REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, */
@@ -88,9 +93,11 @@ int nregdescfloat[] = {
 
 *******************************************************************************/
 
-#include "jit/codegen.inc"
-#include "jit/reg.inc"
-
+#include "vm/jit/codegen.inc"
+#include "vm/jit/reg.inc"
+#ifdef LSRA
+#include "vm/jit/lsra.inc"
+#endif
 
 void codegen_stubcalled() {
        log_text("Stub has been called");
@@ -105,33 +112,18 @@ void codegen_general_stubcalled() {
 void thread_restartcriticalsection(ucontext_t *uc)
 {
        void *critical;
+#ifdef __FreeBSD__
+       if ((critical = thread_checkcritical((void*) uc->uc_mcontext.mc_eip)) != NULL)
+               uc->uc_mcontext.mc_eip = (u4) critical;
+#else
        if ((critical = thread_checkcritical((void*) uc->uc_mcontext.gregs[REG_EIP])) != NULL)
                uc->uc_mcontext.gregs[REG_EIP] = (u4) critical;
+
+#endif
 }
 #endif
 
 
-#define PREPARE_NATIVE_STACKINFO \
-    i386_push_reg(cd, REG_ITMP1);      /*save itmp1, needed by some stubs */ \
-    i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
-    i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
-    i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/ \
-    i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
-    i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/ \
-    i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/ \
-    i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4);     /* store value on stack */ \
-    i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
-    i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
-    i386_mov_imm_membase(cd, 0,REG_SP, 2*4);    /* builtin */ 
-
-
-#define REMOVE_NATIVE_STACKINFO \
-    i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
-    i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
-    i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
-
 
 /* NullPointerException signal handler for hardware null pointer check */
 
@@ -140,8 +132,13 @@ void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
        sigset_t nsig;
 /*     long     faultaddr; */
 
-    struct ucontext *_uc = (struct ucontext *) _p;
-    struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
+#ifdef __FreeBSD__
+       ucontext_t *_uc = (ucontext_t *) _p;
+       mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
+#else
+       struct ucontext *_uc = (struct ucontext *) _p;
+       struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
+#endif
        struct sigaction act;
 
        /* Reset signal handler - necessary for SysV, does no harm for BSD */
@@ -153,19 +150,24 @@ void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
 
 /*     if (faultaddr == 0) { */
 /*             signal(sig, (void *) catch_NullPointerException); */
-       act.sa_sigaction = (void *) catch_NullPointerException;
+       act.sa_sigaction = (functionptr) catch_NullPointerException;
        act.sa_flags = SA_SIGINFO;
        sigaction(sig, &act, NULL);                          /* reinstall handler */
 
-               sigemptyset(&nsig);
-               sigaddset(&nsig, sig);
-               sigprocmask(SIG_UNBLOCK, &nsig, NULL);           /* unblock signal    */
+       sigemptyset(&nsig);
+       sigaddset(&nsig, sig);
+       sigprocmask(SIG_UNBLOCK, &nsig, NULL);           /* unblock signal    */
 
-               sigctx->ecx = sigctx->eip;                       /* REG_ITMP2_XPC     */
-               sigctx->eax = (u4) string_java_lang_NullPointerException;
-               sigctx->eip = (u4) asm_throw_and_handle_exception;
-               
-               return;
+#ifdef __FreeBSD__
+       sigctx->mc_ecx = sigctx->mc_eip;     /* REG_ITMP2_XPC*/
+       sigctx->mc_eax = (u4) string_java_lang_NullPointerException;
+       sigctx->mc_eip = (u4) asm_throw_and_handle_exception;
+#else
+       sigctx->ecx = sigctx->eip;             /* REG_ITMP2_XPC     */
+       sigctx->eax = (u4) string_java_lang_NullPointerException;
+       sigctx->eip = (u4) asm_throw_and_handle_exception;
+#endif
+       return;
 
 /*     } else { */
 /*             faultaddr += (long) ((instr << 16) >> 16); */
@@ -183,14 +185,21 @@ void catch_ArithmeticException(int sig, siginfo_t *siginfo, void *_p)
 
 /*     void **_p = (void **) &sig; */
 /*     struct sigcontext *sigctx = (struct sigcontext *) ++_p; */
-    struct ucontext *_uc = (struct ucontext *) _p;
-    struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
+
+#ifdef __FreeBSD__
+       ucontext_t *_uc = (ucontext_t *) _p;
+       mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
+#else
+       struct ucontext *_uc = (struct ucontext *) _p;
+       struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
+#endif
+
        struct sigaction act;
 
        /* Reset signal handler - necessary for SysV, does no harm for BSD        */
 
 /*     signal(sig, (void *) catch_ArithmeticException); */
-       act.sa_sigaction = (void *) catch_ArithmeticException;
+       act.sa_sigaction = (functionptr) catch_ArithmeticException;
        act.sa_flags = SA_SIGINFO;
        sigaction(sig, &act, NULL);                          /* reinstall handler */
 
@@ -198,9 +207,13 @@ void catch_ArithmeticException(int sig, siginfo_t *siginfo, void *_p)
        sigaddset(&nsig, sig);
        sigprocmask(SIG_UNBLOCK, &nsig, NULL);               /* unblock signal    */
 
-       sigctx->ecx = sigctx->eip;                           /* REG_ITMP2_XPC     */
+#ifdef __FreeBSD__
+       sigctx->mc_ecx = sigctx->mc_eip;                 /* REG_ITMP2_XPC     */
+       sigctx->mc_eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
+#else
+       sigctx->ecx = sigctx->eip;                     /* REG_ITMP2_XPC     */
        sigctx->eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
-
+#endif
        return;
 }
 
@@ -215,21 +228,21 @@ void init_exceptions(void)
        if (!checknull) {
 #if defined(SIGSEGV)
 /*             signal(SIGSEGV, (void *) catch_NullPointerException); */
-               act.sa_sigaction = (void *) catch_NullPointerException;
+               act.sa_sigaction = (functionptr) catch_NullPointerException;
                act.sa_flags = SA_SIGINFO;
                sigaction(SIGSEGV, &act, NULL);
 #endif
 
 #if defined(SIGBUS)
 /*             signal(SIGBUS, (void *) catch_NullPointerException); */
-               act.sa_sigaction = (void *) catch_NullPointerException;
+               act.sa_sigaction = (functionptr) catch_NullPointerException;
                act.sa_flags = SA_SIGINFO;
                sigaction(SIGBUS, &act, NULL);
 #endif
        }
 
 /*     signal(SIGFPE, (void *) catch_ArithmeticException); */
-       act.sa_sigaction = (void *) catch_ArithmeticException;
+       act.sa_sigaction = (functionptr) catch_ArithmeticException;
        act.sa_flags = SA_SIGINFO;
        sigaction(SIGFPE, &act, NULL);
 }
@@ -266,6 +279,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
        parentargs_base = rd->maxmemuse + savedregs_num;
 
+          
 #if defined(USE_THREADS)           /* space to save argument of monitor_enter */
 
        if (checksync && (m->flags & ACC_SYNCHRONIZED))
@@ -342,10 +356,10 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
        /* save monitorenter argument */
 
 #if defined(USE_THREADS)
-       s4 func_enter = (m->flags & ACC_STATIC) ?
-               (s4) builtin_staticmonitorenter : (s4) builtin_monitorenter;
-
        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+               s4 func_enter = (m->flags & ACC_STATIC) ?
+                       (s4) builtin_staticmonitorenter : (s4) builtin_monitorenter;
+
                if (m->flags & ACC_STATIC) {
                        i386_mov_imm_reg(cd, (s4) m->class, REG_ITMP1);
                        i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, rd->maxmemuse * 8);
@@ -527,15 +541,47 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                src = bptr->instack;
                len = bptr->indepth;
                MCODECHECK(64+len);
+
+#ifdef LSRA
+               if (opt_lsra) {
                while (src != NULL) {
                        len--;
                        if ((len == 0) && (bptr->type != BBTYPE_STD)) {
                                if (!IS_2_WORD_TYPE(src->type)) {
                                        if (bptr->type == BBTYPE_SBR) {
-                                               d = reg_of_var(rd, src, REG_ITMP1);
+                                                       /*                                                      d = reg_of_var(m, src, REG_ITMP1); */
+                                                       if (!(src->flags & INMEMORY))
+                                                               d= src->regoff;
+                                                       else
+                                                               d=REG_ITMP1;
                                                i386_pop_reg(cd, d);
                                                store_reg_to_var_int(src, d);
+                                               } else if (bptr->type == BBTYPE_EXH) {
+                                                       /*                                                      d = reg_of_var(m, src, REG_ITMP1); */
+                                                       if (!(src->flags & INMEMORY))
+                                                               d= src->regoff;
+                                                       else
+                                                               d=REG_ITMP1;
+                                                       M_INTMOVE(REG_ITMP1, d);
+                                                       store_reg_to_var_int(src, d);
+                                               }
 
+                                       } else {
+                                               panic("copy interface registers(EXH, SBR): longs have to me in memory (begin 1)");
+                                       }
+                               }
+                               src = src->prev;
+                       }
+               } else {
+#endif
+                       while (src != NULL) {
+                               len--;
+                               if ((len == 0) && (bptr->type != BBTYPE_STD)) {
+                                       if (!IS_2_WORD_TYPE(src->type)) {
+                                               if (bptr->type == BBTYPE_SBR) {
+                                                       d = reg_of_var(rd, src, REG_ITMP1);
+                                                       i386_pop_reg(cd, d);
+                                                       store_reg_to_var_int(src, d);
                                        } else if (bptr->type == BBTYPE_EXH) {
                                                d = reg_of_var(rd, src, REG_ITMP1);
                                                M_INTMOVE(REG_ITMP1, d);
@@ -589,6 +635,9 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        }
                        src = src->prev;
                }
+#ifdef LSRA
+               }
+#endif
 
                /* walk through all instructions */
                
@@ -1161,7 +1210,6 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                      /* val.i = constant                             */
 
                        d = reg_of_var(rd, iptr->dst, REG_NULL);
-                       /* should we use a inc optimization for smaller code size? */
                        i386_emit_ialuconst(cd, I386_ADD, src, iptr);
                        break;
 
@@ -2023,6 +2071,9 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                i386_alu_imm_membase(cd, I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
 
                        } else {
+                               /* `inc reg' is slower on p4's (regarding to ia32             */
+                               /* optimization reference manual and benchmarks) and as fast  */
+                               /* on athlon's.                                               */
                                i386_alu_imm_reg(cd, I386_ADD, iptr->val.i, var->regoff);
                        }
                        break;
@@ -2832,195 +2883,219 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
                                      /* op1 = type, val.a = field address            */
 
-                       /* if class isn't yet initialized, do it */
+                       /* If the static fields' class is not yet initialized, we do it   */
+                       /* now. The call code is generated later.                         */
                        if (!((fieldinfo *) iptr->val.a)->class->initialized) {
-                               /* call helper function which patches this code */
-                               i386_mov_imm_reg(cd, (s4) ((fieldinfo *) iptr->val.a)->class, REG_ITMP1);
-                               i386_mov_imm_reg(cd, (s4) asm_check_clinit, REG_ITMP2);
-                               i386_call_reg(cd, REG_ITMP2);
+                               codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr->val.a)->class);
+
+                               /* This is just for debugging purposes. Is very difficult to  */
+                               /* read patched code. Here we patch the following 5 nop's     */
+                               /* so that the real code keeps untouched.                     */
+                               if (showdisassemble) {
+                                       i386_nop(cd);
+                                       i386_nop(cd);
+                                       i386_nop(cd);
+                                       i386_nop(cd);
+                                       i386_nop(cd);
+                               }
                        }
 
-                       a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
-                       /* here it's slightly slower */
-                       i386_mov_imm_reg(cd, 0, REG_ITMP2);
-                       dseg_adddata(cd, cd->mcodeptr);
-                       i386_mov_membase_reg(cd, REG_ITMP2, a, REG_ITMP2);
+                       a = (u4) &(((fieldinfo *) iptr->val.a)->value);
                        switch (iptr->op1) {
                        case TYPE_INT:
                        case TYPE_ADR:
                                var_to_reg_int(s2, src, REG_ITMP1);
-                               i386_mov_reg_membase(cd, s2, REG_ITMP2, 0);
+                               i386_mov_reg_mem(cd, s2, a);
                                break;
                        case TYPE_LNG:
                                if (src->flags & INMEMORY) {
-                                       i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
-                                       i386_mov_reg_membase(cd, REG_ITMP1, REG_ITMP2, 0);
-                                       i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
-                                       i386_mov_reg_membase(cd, REG_ITMP1, REG_ITMP2, 0 + 4);
+                                       /* Using both REG_ITMP1 and REG_ITMP2 is faster than only */
+                                       /* using REG_ITMP1 alternating.                           */
+                                       s2 = src->regoff;
+                                       i386_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
+                                       i386_mov_membase_reg(cd, REG_SP, s2 * 8 + 4, REG_ITMP2);
+                                       i386_mov_reg_mem(cd, REG_ITMP1, a);
+                                       i386_mov_reg_mem(cd, REG_ITMP2, a + 4);
                                } else {
                                        panic("PUTSTATIC: longs have to be in memory");
                                }
                                break;
                        case TYPE_FLT:
                                var_to_reg_flt(s2, src, REG_FTMP1);
-                               i386_fstps_membase(cd, REG_ITMP2, 0);
+                               i386_fstps_mem(cd, a);
                                fpu_st_offset--;
                                break;
                        case TYPE_DBL:
                                var_to_reg_flt(s2, src, REG_FTMP1);
-                               i386_fstpl_membase(cd, REG_ITMP2, 0);
+                               i386_fstpl_mem(cd, a);
                                fpu_st_offset--;
                                break;
-                       default: panic ("internal error");
+                       default:
+                               throw_cacao_exception_exit(string_java_lang_InternalError,
+                                                                                  "Unknown PUTSTATIC operand type %d",
+                                                                                  iptr->op1);
                        }
                        break;
 
                case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
                                      /* op1 = type, val.a = field address            */
 
-                       /* if class isn't yet initialized, do it */
+                       /* If the static fields' class is not yet initialized, we do it   */
+                       /* now. The call code is generated later.                         */
                        if (!((fieldinfo *) iptr->val.a)->class->initialized) {
-                               /* call helper function which patches this code */
-                               i386_mov_imm_reg(cd, (s4) ((fieldinfo *) iptr->val.a)->class, REG_ITMP1);
-                               i386_mov_imm_reg(cd, (s4) asm_check_clinit, REG_ITMP2);
-                               i386_call_reg(cd, REG_ITMP2);
-                       }
+                               codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr->val.a)->class);
+
+                               /* This is just for debugging purposes. Is very difficult to  */
+                               /* read patched code. Here we patch the following 5 nop's     */
+                               /* so that the real code keeps untouched.                     */
+                               if (showdisassemble) {
+                                       i386_nop(cd);
+                                       i386_nop(cd);
+                                       i386_nop(cd);
+                                       i386_nop(cd);
+                                       i386_nop(cd);
+                               }
+                       }
 
-                       a = dseg_addaddress(cd, &(((fieldinfo *) iptr->val.a)->value));
-                       i386_mov_imm_reg(cd, 0, REG_ITMP2);
-                       dseg_adddata(cd, cd->mcodeptr);
-                       i386_mov_membase_reg(cd, REG_ITMP2, a, REG_ITMP2);
+                       a = (u4) &(((fieldinfo *) iptr->val.a)->value);
                        switch (iptr->op1) {
                        case TYPE_INT:
                        case TYPE_ADR:
                                d = reg_of_var(rd, iptr->dst, REG_ITMP1);
-                               i386_mov_membase_reg(cd, REG_ITMP2, 0, d);
+                               i386_mov_mem_reg(cd, a, d);
                                store_reg_to_var_int(iptr->dst, d);
                                break;
                        case TYPE_LNG:
                                d = reg_of_var(rd, iptr->dst, REG_NULL);
                                if (iptr->dst->flags & INMEMORY) {
-                                       i386_mov_membase_reg(cd, REG_ITMP2, 0, REG_ITMP1);
+                                       /* Using both REG_ITMP1 and REG_ITMP2 is faster than only */
+                                       /* using REG_ITMP1 alternating.                           */
+                                       i386_mov_mem_reg(cd, a, REG_ITMP1);
+                                       i386_mov_mem_reg(cd, a + 4, REG_ITMP2);
                                        i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
-                                       i386_mov_membase_reg(cd, REG_ITMP2, 0 + 4, REG_ITMP1);
-                                       i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
+                                       i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
                                } else {
                                        panic("GETSTATIC: longs have to be in memory");
                                }
                                break;
                        case TYPE_FLT:
                                d = reg_of_var(rd, iptr->dst, REG_FTMP1);
-                               i386_flds_membase(cd, REG_ITMP2, 0);
+                               i386_flds_mem(cd, a);
                                fpu_st_offset++;
                                store_reg_to_var_flt(iptr->dst, d);
                                break;
                        case TYPE_DBL:                          
                                d = reg_of_var(rd, iptr->dst, REG_FTMP1);
-                               i386_fldl_membase(cd, REG_ITMP2, 0);
+                               i386_fldl_mem(cd, a);
                                fpu_st_offset++;
                                store_reg_to_var_flt(iptr->dst, d);
                                break;
-                       default: panic ("internal error");
+                       default:
+                               throw_cacao_exception_exit(string_java_lang_InternalError,
+                                                                                  "Unknown GETSTATIC operand type %d",
+                                                                                  iptr->op1);
                        }
                        break;
 
                case ICMD_PUTFIELD:   /* ..., value  ==> ...                          */
                                      /* op1 = type, val.i = field offset             */
 
-                       a = ((fieldinfo *)(iptr->val.a))->offset;
+                       a = ((fieldinfo *) (iptr->val.a))->offset;
                        switch (iptr->op1) {
-                               case TYPE_INT:
-                               case TYPE_ADR:
-                                       var_to_reg_int(s1, src->prev, REG_ITMP1);
-                                       var_to_reg_int(s2, src, REG_ITMP2);
-                                       gen_nullptr_check(s1);
-                                       i386_mov_reg_membase(cd, s2, s1, a);
-                                       break;
-                               case TYPE_LNG:
-                                       var_to_reg_int(s1, src->prev, REG_ITMP1);
-                                       gen_nullptr_check(s1);
-                                       if (src->flags & INMEMORY) {
-                                               i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2);
-                                               i386_mov_reg_membase(cd, REG_ITMP2, s1, a);
-                                               i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
-                                               i386_mov_reg_membase(cd, REG_ITMP2, s1, a + 4);
-                                       } else {
-                                               panic("PUTFIELD: longs have to be in memory");
-                                       }
-                                       break;
-                               case TYPE_FLT:
-                                       var_to_reg_int(s1, src->prev, REG_ITMP1);
-                                       var_to_reg_flt(s2, src, REG_FTMP1);
-                                       gen_nullptr_check(s1);
-                                       i386_fstps_membase(cd, s1, a);
-                                       fpu_st_offset--;
-                                       break;
-                               case TYPE_DBL:
-                                       var_to_reg_int(s1, src->prev, REG_ITMP1);
-                                       var_to_reg_flt(s2, src, REG_FTMP1);
-                                       gen_nullptr_check(s1);
-                                       i386_fstpl_membase(cd, s1, a);
-                                       fpu_st_offset--;
-                                       break;
-                               default: panic ("internal error");
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               var_to_reg_int(s1, src->prev, REG_ITMP1);
+                               var_to_reg_int(s2, src, REG_ITMP2);
+                               gen_nullptr_check(s1);
+                               i386_mov_reg_membase(cd, s2, s1, a);
+                               break;
+                       case TYPE_LNG:
+                               var_to_reg_int(s1, src->prev, REG_ITMP1);
+                               gen_nullptr_check(s1);
+                               if (src->flags & INMEMORY) {
+                                       i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2);
+                                       i386_mov_reg_membase(cd, REG_ITMP2, s1, a);
+                                       i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
+                                       i386_mov_reg_membase(cd, REG_ITMP2, s1, a + 4);
+                               } else {
+                                       panic("PUTFIELD: longs have to be in memory");
                                }
+                               break;
+                       case TYPE_FLT:
+                               var_to_reg_int(s1, src->prev, REG_ITMP1);
+                               var_to_reg_flt(s2, src, REG_FTMP1);
+                               gen_nullptr_check(s1);
+                               i386_fstps_membase(cd, s1, a);
+                               fpu_st_offset--;
+                               break;
+                       case TYPE_DBL:
+                               var_to_reg_int(s1, src->prev, REG_ITMP1);
+                               var_to_reg_flt(s2, src, REG_FTMP1);
+                               gen_nullptr_check(s1);
+                               i386_fstpl_membase(cd, s1, a);
+                               fpu_st_offset--;
+                               break;
+                       default:
+                               throw_cacao_exception_exit(string_java_lang_InternalError,
+                                                                                  "Unknown PUTFIELD operand type %d",
+                                                                                  iptr->op1);
+                       }
                        break;
 
                case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
                                      /* op1 = type, val.i = field offset             */
 
-                       a = ((fieldinfo *)(iptr->val.a))->offset;
+                       a = ((fieldinfo *) (iptr->val.a))->offset;
                        switch (iptr->op1) {
-                               case TYPE_INT:
-                               case TYPE_ADR:
-                                       var_to_reg_int(s1, src, REG_ITMP1);
-                                       d = reg_of_var(rd, iptr->dst, REG_ITMP2);
-                                       gen_nullptr_check(s1);
-                                       i386_mov_membase_reg(cd, s1, a, d);
-                                       store_reg_to_var_int(iptr->dst, d);
-                                       break;
-                               case TYPE_LNG:
-                                       var_to_reg_int(s1, src, REG_ITMP1);
-                                       d = reg_of_var(rd, iptr->dst, REG_NULL);
-                                       gen_nullptr_check(s1);
-                                       i386_mov_membase_reg(cd, s1, a, REG_ITMP2);
-                                       i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
-                                       i386_mov_membase_reg(cd, s1, a + 4, REG_ITMP2);
-                                       i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
-                                       break;
-                               case TYPE_FLT:
-                                       var_to_reg_int(s1, src, REG_ITMP1);
-                                       d = reg_of_var(rd, iptr->dst, REG_FTMP1);
-                                       gen_nullptr_check(s1);
-                                       i386_flds_membase(cd, s1, a);
-                                       fpu_st_offset++;
-                                       store_reg_to_var_flt(iptr->dst, d);
-                                       break;
-                               case TYPE_DBL:                          
-                                       var_to_reg_int(s1, src, REG_ITMP1);
-                                       d = reg_of_var(rd, iptr->dst, REG_FTMP1);
-                                       gen_nullptr_check(s1);
-                                       i386_fldl_membase(cd, s1, a);
-                                       fpu_st_offset++;
-                                       store_reg_to_var_flt(iptr->dst, d);
-                                       break;
-                               default: panic ("internal error");
-                               }
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               var_to_reg_int(s1, src, REG_ITMP1);
+                               d = reg_of_var(rd, iptr->dst, REG_ITMP2);
+                               gen_nullptr_check(s1);
+                               i386_mov_membase_reg(cd, s1, a, d);
+                               store_reg_to_var_int(iptr->dst, d);
+                               break;
+                       case TYPE_LNG:
+                               var_to_reg_int(s1, src, REG_ITMP1);
+                               d = reg_of_var(rd, iptr->dst, REG_NULL);
+                               gen_nullptr_check(s1);
+                               i386_mov_membase_reg(cd, s1, a, REG_ITMP2);
+                               i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
+                               i386_mov_membase_reg(cd, s1, a + 4, REG_ITMP2);
+                               i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
+                               break;
+                       case TYPE_FLT:
+                               var_to_reg_int(s1, src, REG_ITMP1);
+                               d = reg_of_var(rd, iptr->dst, REG_FTMP1);
+                               gen_nullptr_check(s1);
+                               i386_flds_membase(cd, s1, a);
+                               fpu_st_offset++;
+                               store_reg_to_var_flt(iptr->dst, d);
+                               break;
+                       case TYPE_DBL:                          
+                               var_to_reg_int(s1, src, REG_ITMP1);
+                               d = reg_of_var(rd, iptr->dst, REG_FTMP1);
+                               gen_nullptr_check(s1);
+                               i386_fldl_membase(cd, s1, a);
+                               fpu_st_offset++;
+                               store_reg_to_var_flt(iptr->dst, d);
+                               break;
+                       default:
+                               throw_cacao_exception_exit(string_java_lang_InternalError,
+                                                                                  "Unknown GETFIELD operand type %d",
+                                                                                  iptr->op1);
+                       }
                        break;
 
 
                /* branch operations **************************************************/
 
-                       /* TWISTI */
-/*  #define ALIGNCODENOP {if((int)((long)cd->mcodeptr&7)){M_NOP;}} */
-#define ALIGNCODENOP do {} while (0)
-
                case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
 
                        var_to_reg_int(s1, src, REG_ITMP1);
                        M_INTMOVE(s1, REG_ITMP1_XPTR);
 
-                       i386_call_imm(cd, 0);                    /* passing exception pointer */
+                       i386_call_imm(cd, 0);                /* passing exception pointer */
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
                        i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
@@ -4315,6 +4390,9 @@ gen_method: {
                        store_reg_to_var_int(iptr->dst, s1);
                        break;
 
+               case ICMD_INLINE_START:
+               case ICMD_INLINE_END:
+                       break;
                default:
                        error ("Unknown pseudo command: %d", iptr->opc);
        } /* switch */
@@ -4326,6 +4404,9 @@ gen_method: {
        src = bptr->outstack;
        len = bptr->outdepth;
        MCODECHECK(64+len);
+#ifdef LSRA
+       if (!opt_lsra)
+#endif
        while (src) {
                len--;
                if ((src->varkind != STACKVAR)) {
@@ -4397,7 +4478,11 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
 
                        i386_alu_imm_reg(cd, I386_SUB, 1 * 4, REG_SP);
                        i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0 * 4);
@@ -4405,7 +4490,9 @@ gen_method: {
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
                        i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4445,12 +4532,23 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
+
 
                        i386_mov_imm_reg(cd, (u4) new_negativearraysizeexception, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
+                       /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
+
+
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
 
-                       REMOVE_NATIVE_STACKINFO;
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4490,12 +4588,22 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_mov_imm_reg(cd, (u4) new_classcastexception, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
+                       /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
+
+
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
 
-                       REMOVE_NATIVE_STACKINFO;
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4535,12 +4643,21 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
+
 
                        i386_mov_imm_reg(cd, (u4) new_arithmeticexception, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4580,7 +4697,12 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_mov_imm_reg(cd, (s4) codegen_general_stubcalled, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);                
@@ -4628,7 +4750,10 @@ java stack at this point*/
                        i386_pop_reg(cd, REG_ITMP1_XPTR);
                        i386_pop_reg(cd, REG_ITMP3); /* just remove the no longer needed 0 from the stack*/
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4668,7 +4793,13 @@ java stack at this point*/
                        
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
+
 
 #if 0
                        /* create native call block*/
@@ -4690,7 +4821,10 @@ java stack at this point*/
                        i386_mov_imm_reg(cd, (u4) new_nullpointerexception, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
 #if 0
                        /* restore native call stack */
@@ -4706,6 +4840,46 @@ java stack at this point*/
                        i386_jmp_reg(cd, REG_ITMP3);
                }
        }
+
+       /* generate put/getstatic stub call code */
+
+       {
+               clinitref   *cref;
+               codegendata *tmpcd;
+               u1           xmcode;
+               u4           mcode;
+
+               tmpcd = DNEW(codegendata);
+
+               for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
+                       /* Get machine code which is patched back in later. A             */
+                       /* `call rel32' is 5 bytes long.                                  */
+                       xcodeptr = cd->mcodebase + cref->branchpos;
+                       xmcode = *xcodeptr;
+                       mcode = *((u4 *) (xcodeptr + 1));
+
+                       MCODECHECK(50);
+
+                       /* patch in `call rel32' to call the following code               */
+                       tmpcd->mcodeptr = xcodeptr;     /* set dummy mcode pointer        */
+                       i386_call_imm(tmpcd, cd->mcodeptr - (xcodeptr + 5));
+
+                       /* Save current stack pointer into a temporary register.          */
+                       i386_mov_reg_reg(cd, REG_SP, REG_ITMP1);
+
+                       /* Push machine code bytes to patch onto the stack.               */
+                       i386_push_imm(cd, (u4) xmcode);
+                       i386_push_imm(cd, (u4) mcode);
+
+                       i386_push_imm(cd, (u4) cref->class);
+
+                       /* Push previously saved stack pointer onto stack.                */
+                       i386_push_reg(cd, REG_ITMP1);
+
+                       i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP1);
+                       i386_jmp_reg(cd, REG_ITMP1);
+               }
+       }
        }
        
        codegen_finish(m, cd, (u4) (cd->mcodeptr - cd->mcodebase));
@@ -4723,8 +4897,14 @@ java stack at this point*/
 u1 *createcompilerstub(methodinfo *m)
 {
     u1 *s = CNEW(u1, COMPSTUBSIZE);     /* memory to hold the stub            */
-       codegendata *cd = NEW(codegendata);
+       codegendata *cd;
+       s4 dumpsize;
 
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+       
+       cd = DNEW(codegendata);
     cd->mcodeptr = s;
 
     /* code for the stub */
@@ -4734,16 +4914,15 @@ u1 *createcompilerstub(methodinfo *m)
     i386_mov_imm_reg(cd, (u4) asm_call_jit_compiler, REG_ITMP3);
     i386_jmp_reg(cd, REG_ITMP3);        /* jump to compiler                   */
 
-       /* free codegendata memory */
-       codegen_close(m);
-
 #if defined(STATISTICS)
        if (opt_stat)
                count_cstub_len += COMPSTUBSIZE;
 #endif
 
-       FREE(cd, codegendata);
+       /* release dump area */
 
+       dump_release(dumpsize);
+       
     return s;
 }
 
@@ -4766,7 +4945,8 @@ void removecompilerstub(u1 *stub)
 
 *******************************************************************************/
 
-#define NATIVESTUBSIZE 350
+#define NATIVESTUBSIZE    370 + 36
+
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
 static java_objectheader **(*callgetexceptionptrptr)() = builtin_get_exceptionptrptr;
@@ -4797,14 +4977,20 @@ void traverseStackInfo() {
 
 }
 
+
 u1 *createnativestub(functionptr f, methodinfo *m)
 {
     u1 *s = CNEW(u1, NATIVESTUBSIZE);   /* memory to hold the stub            */
+       codegendata *cd;
+       registerdata *rd;
+       t_inlining_globals *id;
+       s4 dumpsize;
+
     int addmethod=0;
     u1 *tptr;
     int i;
-    int stackframesize = 4+12;           /* initial 4 bytes is space for jni env,
-                                               + 4 byte thread pointer + 4 byte previous pointer + method info*/
+    int stackframesize = 4+16;           /* initial 4 bytes is space for jni env,
+                                               + 4 byte thread pointer + 4 byte previous pointer + method info + 4 offset native*/
     int stackframeoffset = 4;
 
     int p, t;
@@ -4813,22 +4999,31 @@ u1 *createnativestub(functionptr f, methodinfo *m)
     u1* jmpInstrPos=0;
     void** jmpInstrPatchPos=0;
 
-       codegendata *cd = NEW(codegendata);
-       registerdata *rd = NEW(registerdata);
-       t_inlining_globals *id = NEW(t_inlining_globals);
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* allocate required dump memory */
+
+       cd = DNEW(codegendata);
+       rd = DNEW(registerdata);
+       id = DNEW(t_inlining_globals);
 
        /* setup registers before using it */
+
        inlining_setup(m, id);
        reg_setup(m, rd, id);
 
+       /* set some required varibles which are normally set by codegen_setup */
+       cd->mcodebase = s;
        cd->mcodeptr = s;
+       cd->clinitrefs = NULL;
 
        if (m->flags & ACC_STATIC) {
                stackframesize += 4;
                stackframeoffset += 4;
        }
 
-    reg_init(m);
     descriptor2types(m);                     /* set paramcount and paramtypes */
   
 /*DEBUG*/
@@ -4841,11 +5036,11 @@ u1 *createnativestub(functionptr f, methodinfo *m)
        /* if function is static, check for initialized */
 
        if (m->flags & ACC_STATIC) {
-       /* if class isn't yet initialized, do it */
+               /* if class isn't yet initialized, do it */
                if (!m->class->initialized) {
                        s4 *header = (s4 *) s;
                        *header = 0;/*extablesize*/
-                       header;
+                       header++;
                        *header = 0;/*line number table start*/
                        header++;
                        *header = 0;/*line number table size*/
@@ -4861,14 +5056,15 @@ u1 *createnativestub(functionptr f, methodinfo *m)
                        *header = 0;/*framesize*/
                        header++;
                        *header = (u4) m;/*methodpointer*/
-                       *header++;
-                       cd->mcodeptr = s = (u1 *) header;
+                       header++;
+
+                       s = (u1 *) header;
+
+                       cd->mcodebase = s;
+                       cd->mcodeptr = s;
                        addmethod = 1;
 
-                       /* call helper function which patches this code */
-                       i386_mov_imm_reg(cd, (u4) m->class, REG_ITMP1);
-                       i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP2);
-                       i386_call_reg(cd, REG_ITMP2);
+                       codegen_addclinitref(cd, cd->mcodeptr, m->class);
                }
        }
 
@@ -4961,14 +5157,15 @@ u1 *createnativestub(functionptr f, methodinfo *m)
        i386_alu_imm_reg(cd, I386_SUB, stackframesize, REG_SP);
 
 /* CREATE DYNAMIC STACK INFO -- BEGIN*/
-   i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-4);
+   i386_mov_imm_membase(cd,0,REG_SP,stackframesize-4);
+   i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-8);
    i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo, REG_ITMP1);
    i386_call_reg(cd, REG_ITMP1);
-   i386_mov_reg_membase(cd, REG_RESULT,REG_SP,stackframesize-8); /*save thread specific pointer*/
+   i386_mov_reg_membase(cd, REG_RESULT,REG_SP,stackframesize-12); /*save thread specific pointer*/
    i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); 
-   i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,stackframesize-12); /*save previous value of memory adress pointed to by thread specific pointer*/
+   i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,stackframesize-16); /*save previous value of memory adress pointed to by thread specific pointer*/
    i386_mov_reg_reg(cd, REG_SP,REG_ITMP2);
-   i386_alu_imm_reg(cd, I386_ADD,stackframesize-12,REG_ITMP2);
+   i386_alu_imm_reg(cd, I386_ADD,stackframesize-16,REG_ITMP2);
    i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT,0);
 
 /*TESTING ONLY */
@@ -4981,7 +5178,7 @@ u1 *createnativestub(functionptr f, methodinfo *m)
 /* RESOLVE NATIVE METHOD -- BEGIN*/
 #ifndef STATIC_CLASSPATH
    if (f==0) {
-     log_text("Dynamic classpath: preparing for delayed native function resolving");
+     /*log_text("Dynamic classpath: preparing for delayed native function resolving");*/
      i386_jmp_imm(cd,0);
      jmpInstrPos=cd->mcodeptr-4;
      /*patchposition*/
@@ -5008,7 +5205,7 @@ u1 *createnativestub(functionptr f, methodinfo *m)
      i386_pop_reg(cd,REG_ITMP1);
      /*fix jmp offset replacement*/
      (*jmpInstrPatchPos)=cd->mcodeptr-jmpInstrPos-4;
-   } else log_text("Dynamic classpath: immediate native function resolution possible");
+   } /*else log_text("Dynamic classpath: immediate native function resolution possible");*/
 #endif
 /* RESOLVE NATIVE METHOD -- END*/
 
@@ -5056,8 +5253,8 @@ u1 *createnativestub(functionptr f, methodinfo *m)
 
 /*REMOVE DYNAMIC STACK INFO -BEGIN */
     i386_push_reg(cd, REG_RESULT2);
-    i386_mov_membase_reg(cd, REG_SP,stackframesize-8,REG_ITMP2); /*old value*/
-    i386_mov_membase_reg(cd, REG_SP,stackframesize-4,REG_RESULT2); /*pointer*/
+    i386_mov_membase_reg(cd, REG_SP,stackframesize-12,REG_ITMP2); /*old value*/
+    i386_mov_membase_reg(cd, REG_SP,stackframesize-8,REG_RESULT2); /*pointer*/
     i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT2,0);
     i386_pop_reg(cd, REG_RESULT2);
 /*REMOVE DYNAMIC STACK INFO -END */
@@ -5085,7 +5282,6 @@ u1 *createnativestub(functionptr f, methodinfo *m)
         i386_alu_imm_reg(cd, I386_ADD, 4 + 8 + 8 + 4, REG_SP);
     }
 
-
        /* we can't use REG_ITMP3 == REG_RESULT2 */
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
        i386_push_reg(cd, REG_RESULT);
@@ -5124,23 +5320,60 @@ u1 *createnativestub(functionptr f, methodinfo *m)
                codegen_insertmethod(s, cd->mcodeptr);
        }
 
+       {
+               u1          *xcodeptr;
+               clinitref   *cref;
+               codegendata *tmpcd;
+               u1           xmcode;
+               u4           mcode;
+
+               tmpcd = DNEW(codegendata);
+
+               /* there can only be one clinit ref entry                             */
+               cref = cd->clinitrefs;
+
+               if (cref) {
+                       /* Get machine code which is patched back in later. A             */
+                       /* `call rel32' is 5 bytes long.                                  */
+                       xcodeptr = cd->mcodebase + cref->branchpos;
+                       xmcode = *xcodeptr;
+                       mcode =  *((u4 *) (xcodeptr + 1));
+
+                       /* patch in `call rel32' to call the following code               */
+                       tmpcd->mcodeptr = xcodeptr;     /* set dummy mcode pointer        */
+                       i386_call_imm(tmpcd, cd->mcodeptr - (xcodeptr + 5));
+
+                       /* Save current stack pointer into a temporary register.          */
+                       i386_mov_reg_reg(cd, REG_SP, REG_ITMP1);
+
+                       /* Push machine code bytes to patch onto the stack.               */
+                       i386_push_imm(cd, (u4) xmcode);
+                       i386_push_imm(cd, (u4) mcode);
+
+                       i386_push_imm(cd, (u4) cref->class);
+
+                       /* Push previously saved stack pointer onto stack.                */
+                       i386_push_reg(cd, REG_ITMP1);
+
+                       i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP1);
+                       i386_jmp_reg(cd, REG_ITMP1);
+               }
+       }
+
 #if 0
-       dolog_plain("native stubentry: %p, stubsize: %x (for %d params) --", (s4)s,(s4) (cd->mcodeptr - s), m->paramcount);
+       dolog_plain("native stubentry: %p, stubsize: %d (for %d params) --", (s4)s,(s4) (cd->mcodeptr - s), m->paramcount);
        utf_display(m->name);
        dolog_plain("\n");
 #endif
 
-       /* free codegendata memory */
-       codegen_close(m);
-
 #if defined(STATISTICS)
        if (opt_stat)
                count_nstub_len += NATIVESTUBSIZE;
 #endif
 
-       FREE(cd, codegendata);
-       FREE(rd, registerdata);
-       FREE(id, t_inlining_globals);
+       /* release dump area */
+
+       dump_release(dumpsize);
 
        return s;
 }