GNU header update.
[cacao.git] / src / vm / jit / jit.c
index a72d201a7c097c1f84f55f12e44de70dc113a3d8..f27f52ee99614c42d5920daf31440a0f0295205f 100644 (file)
@@ -1,9 +1,9 @@
-/* jit/jit.c - calls the code generation functions
+/* vm/jit/jit.c - calls the code generation functions
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   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
             Reinhard Grafl
 
-   $Id: jit.c 727 2003-12-11 10:52:40Z edwin $
+   Changes: Edwin Steiner
+
+   $Id: jit.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
 
-#include <stdlib.h>
-#include <string.h>
-#include "global.h"    /* we define _GNU_SOURCE there */
-#include "tables.h"
-#include "loader.h"
-#include "jit.h"
-#include "parse.h"
-#include "stack.h"
-#include "reg.h"
-#include "inline.h"
-#include "builtin.h"
-#include "native.h"
-#include "asmpart.h"
 #include "codegen.h"
-#include "types.h"
-#include "threads/thread.h"
 #include "disass.h"
-#include "loop/loop.h"
-#include "loop/graph.h"
-#include "loop/analyze.h"
-#include "toolbox/loging.h"
-#include "toolbox/memory.h"
-
-
-/* global switches ************************************************************/
-bool compileverbose =  false;
-bool showstack = false;
-bool showdisassemble = false; 
-bool showddatasegment = false; 
-bool showintermediate = false;
-int  optimizelevel = 0;
-
-bool useinlining = false;
-bool inlinevirtuals = false;
-bool inlineexceptions = false;
-bool inlineparamopt = false;
-bool inlineoutsiders = false;
-
-bool checkbounds = true;
-bool checknull = true;
-bool opt_noieee = false;
-bool checksync = true;
-bool opt_loops = false;
-
-bool getcompilingtime = false;
-long compilingtime = 0;
-
-int  has_ext_instr_set = 0;
-
-bool statistics = false;         
-
-int count_jit_calls = 0;
-int count_methods = 0;
-int count_spills = 0;
-int count_pcmd_activ = 0;
-int count_pcmd_drop = 0;
-int count_pcmd_zero = 0;
-int count_pcmd_const_store = 0;
-int count_pcmd_const_alu = 0;
-int count_pcmd_const_bra = 0;
-int count_pcmd_load = 0;
-int count_pcmd_move = 0;
-int count_load_instruction = 0;
-int count_pcmd_store = 0;
-int count_pcmd_store_comb = 0;
-int count_dup_instruction = 0;
-int count_pcmd_op = 0;
-int count_pcmd_mem = 0;
-int count_pcmd_met = 0;
-int count_pcmd_bra = 0;
-int count_pcmd_table = 0;
-int count_pcmd_return = 0;
-int count_pcmd_returnx = 0;
-int count_check_null = 0;
-int count_check_bound = 0;
-int count_max_basic_blocks = 0;
-int count_basic_blocks = 0;
-int count_javainstr = 0;
-int count_max_javainstr = 0;
-int count_javacodesize = 0;
-int count_javaexcsize = 0;
-int count_calls = 0;
-int count_tryblocks = 0;
-int count_code_len = 0;
-int count_data_len = 0;
-int count_cstub_len = 0;
-int count_nstub_len = 0;
-int count_max_new_stack = 0;
-int count_upper_bound_new_stack = 0;
-static int count_block_stack_init[11] = {
-       0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 
-       0
-};
-int *count_block_stack = count_block_stack_init;
-static int count_analyse_iterations_init[5] = {
-       0, 0, 0, 0, 0
-};
-int *count_analyse_iterations = count_analyse_iterations_init;
-static int count_method_bb_distribution_init[9] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0
-};
-int *count_method_bb_distribution = count_method_bb_distribution_init;
-static int count_block_size_distribution_init[18] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0
-};
-int *count_block_size_distribution = count_block_size_distribution_init;
-static int count_store_length_init[21] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0
-};
-int *count_store_length = count_store_length_init;
-static int count_store_depth_init[11] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0
-};
-int *count_store_depth = count_store_depth_init;
-
-
-
-/* global compiler variables **************************************************/
-
-                                /* data about the currently compiled method   */
-
-classinfo  *class;              /* class the compiled method belongs to       */
-methodinfo *method;             /* pointer to method info of compiled method  */
-static utf *descriptor;         /* type descriptor of compiled method         */
-int         mparamcount;        /* number of parameters (incl. this)          */
-u1         *mparamtypes;        /* types of all parameters (TYPE_INT, ...)    */
-static int mreturntype;         /* return type of method                      */
-       
-int maxstack;                   /* maximal JavaVM stack size                  */
-int maxlocals;                  /* maximal number of local JavaVM variables   */
-int jcodelength;                /* length of JavaVM-codes                     */
-u1 *jcode;                      /* pointer to start of JavaVM-code            */
-int exceptiontablelength;       /* length of exception table                  */
-xtable *extable;                /* pointer to start of exception table        */
-exceptiontable *raw_extable;
-
-int block_count;                /* number of basic blocks                     */
-basicblock *block;              /* points to basic block array                */
-int *block_index;               /* a table which contains for every byte of   */
-                                /* JavaVM code a basic block index if at this */
-                                /* byte there is the start of a basic block   */
-
-int instr_count;                /* number of JavaVM instructions              */
-instruction *instr;             /* points to intermediate code instructions   */
-
-int stack_count;                /* number of stack elements                   */
-stackelement *stack;            /* points to intermediate code instructions   */
-
-bool isleafmethod;              /* true if a method doesn't call subroutines  */
+#include "types.h"
+#include "mm/memory.h"
+#include "toolbox/logging.h"
+#include "vm/builtin.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
+#include "vm/tables.h"
+#include "vm/jit/codegen.inc.h"
+#include "vm/jit/jit.h"
+#ifdef LSRA
+#include "vm/jit/lsra.h"
+#endif
+#include "vm/jit/parse.h"
+#include "vm/jit/reg.h"
+#include "vm/jit/stack.h"
+#include "vm/jit/inline/inline.h"
+#include "vm/jit/inline/parseRT.h"
+#include "vm/jit/loop/analyze.h"
+#include "vm/jit/loop/graph.h"
+#include "vm/jit/loop/loop.h"
+#include "vm/jit/verify/typecheck.h"
+
+#if defined(USE_THREADS)
+# if defined(NATIVE_THREADS)
+#  include "threads/native/threads.h"
+# else
+#  include "threads/green/threads.h"
+# endif
+#endif
 
-basicblock *last_block;         /* points to the end of the BB list           */
 
-bool regs_ok;                   /* true if registers have been allocated      */
 
-/* list of all classes used by the compiled method which have to be           */
-/* initialised (if not already done) before execution of this method          */
-chain *uninitializedclasses;
+/* global switches ************************************************************/
 
 int stackreq[256];
+
                                 
+#if defined(__I386__)
+/* these define if a method has ICMDs which use %edx or %ecx */
+bool method_uses_ecx;
+bool method_uses_edx;
+#endif
+
 
 int jcommandsize[256] = {
 
@@ -219,7 +97,6 @@ int jcommandsize[256] = {
 #define ICMD_ICONST            3        /* val.i = constant                   */
        1,
 #define JAVA_ICONST_1          4
-#define ICMD_IREM0X10001       4
        1,
 #define JAVA_ICONST_2          5
 #define ICMD_IDIVPOW2          5        /* val.i = constant                   */
@@ -230,7 +107,6 @@ int jcommandsize[256] = {
 #define JAVA_ICONST_4          7
        1,
 #define JAVA_ICONST_5          8
-#define ICMD_LREM0X10001       8
        1,
 #define JAVA_LCONST_0          9
 #define ICMD_LCONST            9        /* val.l = constant                   */
@@ -804,9 +680,27 @@ int jcommandsize[256] = {
        5,
 #define JAVA_BREAKPOINT       202
        1,
+#define ICMD_CHECKEXCEPTION   203
+       1,
+#define ICMD_IASTORECONST     204
+       1,
+#define ICMD_LASTORECONST     205
+       1,
+#define ICMD_FASTORECONST     206
+       1,
+#define ICMD_DASTORECONST     207
+       1,
+#define ICMD_AASTORECONST     208
+       1,
+#define ICMD_BASTORECONST     209
+       1,
+#define ICMD_CASTORECONST     210
+       1,
+#define ICMD_SASTORECONST     211
+       1,
 
-           1,1,1,1,1,1,1,1,            /* unused */
-       1,1,1,1,1,1,1,1,1,1,
+       /* unused */
+       1,1,1,1,1,1,1,1,
        1,1,1,1,1,1,1,1,1,1,
        1,1,1,1,1,1,1,1,1,1,
        1,1,1,1,1,1,1,1,1,1,
@@ -819,15 +713,15 @@ char *icmd_names[256] = {
        "ACONST       ", /*               1 */
        "NULLCHECKPOP ", /* ICONST_M1     2 */
        "ICONST       ", /*               3 */
-       "IREM0X10001  ", /* ICONST_1      4 */
+       "UNDEF4       ", /* ICONST_1      4 */
        "IDIVPOW2     ", /* ICONST_2      5 */
        "LDIVPOW2     ", /* ICONST_3      6 */
-       "UNDEF__7     ", /* ICONST_4      7 */
-       "LREM0X10001  ", /* ICONST_5      8 */
+       "UNDEF7       ", /* ICONST_4      7 */
+       "UNDEF8       ", /* ICONST_5      8 */
        "LCONST       ", /*               9 */
        "LCMPCONST    ", /* LCONST_1     10 */
        "FCONST       ", /*              11 */
-       "UNDEF_12     ", /* FCONST_1     12 */
+       "UNDEF12      ", /* FCONST_1     12 */
        "ELSE_ICONST  ", /* FCONST_2     13 */
        "DCONST       ", /*              14 */
        "IFEQ_ICONST  ", /* DCONST_1     15 */
@@ -886,14 +780,14 @@ char *icmd_names[256] = {
        "IF_LCMPGE    ", /* FSTORE_1     68 */
        "IF_LCMPGT    ", /* FSTORE_2     69 */
        "IF_LCMPLE    ", /* FSTORE_3     70 */
-       "UNDEF_71     ", /* DSTORE_0     71 */
-       "UNDEF_72     ", /* DSTORE_1     72 */
-       "UNDEF_73     ", /* DSTORE_2     73 */
-       "UNDEF_74     ", /* DSTORE_3     74 */
-       "UNDEF_75     ", /* ASTORE_0     75 */
-       "UNDEF_76     ", /* ASTORE_1     76 */
-       "UNDEF_77     ", /* ASTORE_2     77 */
-       "UNDEF_78     ", /* ASTORE_3     78 */
+       "UNDEF71      ", /* DSTORE_0     71 */
+       "UNDEF72      ", /* DSTORE_1     72 */
+       "UNDEF73      ", /* DSTORE_2     73 */
+       "UNDEF74      ", /* DSTORE_3     74 */
+       "UNDEF75      ", /* ASTORE_0     75 */
+       "UNDEF76      ", /* ASTORE_1     76 */
+       "UNDEF77      ", /* ASTORE_2     77 */
+       "UNDEF78      ", /* ASTORE_3     78 */
        "IASTORE      ", /*              79 */
        "LASTORE      ", /*              80 */
        "FASTORE      ", /*              81 */
@@ -1018,10 +912,16 @@ char *icmd_names[256] = {
        "UNDEF200     ", /* GOTO_W      200 */
        "UNDEF201     ", /* JSR_W       201 */
        "UNDEF202     ", /* BREAKPOINT  202 */
-
-                             "UNDEF203","UNDEF204","UNDEF205",
-       "UNDEF206","UNDEF207","UNDEF208","UNDEF209","UNDEF210",
-       "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+       "CHECKEXCEPTION", /* UNDEF203    203 */
+       "IASTORECONST ", /*             204 */
+       "LASTORECONST ", /*             205 */
+       "FASTORECONST ", /*             206 */
+       "DASTORECONST ", /*             207 */
+       "AASTORECONST ", /*             208 */
+       "BASTORECONST ", /*             209 */
+       "CASTORECONST ", /*             210 */
+       "SASTORECONST ", /*             211 */
+       "UNDEF","UNDEF","UNDEF","UNDEF",
        "UNDEF216","UNDEF217","UNDEF218","UNDEF219","UNDEF220",
        "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
        "UNDEF226","UNDEF227","UNDEF228","UNDEF229","UNDEF230",
@@ -1029,7 +929,9 @@ char *icmd_names[256] = {
        "UNDEF236","UNDEF237","UNDEF238","UNDEF239","UNDEF240",
        "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
        "UNDEF246","UNDEF247","UNDEF248","UNDEF249","UNDEF250",
-       "UNDEF251","UNDEF252",
+
+       "INLINE_START", /*          251 */
+        "INLINE_END", /*            252"*/
 
        "BUILTIN3     ", /*             253 */
        "BUILTIN2     ", /*             254 */
@@ -1241,10 +1143,16 @@ char *opcode_names[256] = {
        "GOTO_W       ", /* GOTO_W      200 */
        "JSR_W        ", /* JSR_W       201 */
        "BREAKPOINT   ", /* BREAKPOINT  202 */
-
-                             "UNDEF203","UNDEF204","UNDEF205",
-       "UNDEF206","UNDEF207","UNDEF208","UNDEF209","UNDEF210",
-       "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+       "CHECKEXCEPTION", /* UNDEF203    203 */
+       "IASTORECONST ", /*             204 */
+       "LASTORECONST ", /*             205 */
+       "FASTORECONST ", /*             206 */
+       "DASTORECONST ", /*             207 */
+       "AASTORECONST ", /*             208 */
+       "BASTORECONST ", /*             209 */
+       "CASTORECONST ", /*             210 */
+       "SASTORECONST ", /*             211 */
+       "UNDEF","UNDEF","UNDEF","UNDEF",
        "UNDEF216","UNDEF217","UNDEF218","UNDEF219","UNDEF220",
        "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
        "UNDEF226","UNDEF227","UNDEF228","UNDEF229","UNDEF230",
@@ -1252,8 +1160,9 @@ char *opcode_names[256] = {
        "UNDEF236","UNDEF237","UNDEF238","UNDEF239","UNDEF240",
        "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
        "UNDEF246","UNDEF247","UNDEF248","UNDEF249","UNDEF250",
-       "UNDEF251","UNDEF252",
 
+       "INLINE_START", /*              251 */
+        "INLINE_END",  /*               252 */
        "BUILTIN3     ", /*             253 */
        "BUILTIN2     ", /*             254 */
        "BUILTIN1     "  /*             255 */
@@ -1306,11 +1215,25 @@ stdopdescriptor builtintable[] = {
 };
 
 #endif
-int builtintablelen; /* XXX make static again? */
+
+static int builtintablelen;
 
 #endif /* USEBUILTINTABLE */
 
 
+
+#define EXTABLEN
+/*     \
+        { \
+                printf("PARSE method name ="); \
+                utf_display(m->class->name); \
+                printf("."); \
+                method_display(m); \
+               printf("        exceptiontablelength %d\n",m->exceptiontablelength);    \
+                fflush(stdout); \
+        }
+*/
+
 /*****************************************************************************
                                                 TABLE OF BUILTIN FUNCTIONS
 
@@ -1320,12 +1243,13 @@ int builtintablelen; /* XXX make static again? */
     The first part of the table (up to the 255-marker) lists the
     opcodes which are automatically replaced in stack.c.
 
-    The second part lists the builtin functions which are used for
-    BUILTIN* opcodes in parse.c and stack.c.
+    The second part lists the builtin functions which are "manually"
+    used for BUILTIN* opcodes in parse.c and stack.c.
 
 *****************************************************************************/
 
 builtin_descriptor builtin_desc[] = {
+#if defined(USEBUILTINTABLE)
        {ICMD_LCMP , BUILTIN_lcmp ,ICMD_BUILTIN2,TYPE_LONG  ,TYPE_LONG  ,TYPE_VOID ,TYPE_INT   ,
                     SUPPORT_LONG && SUPPORT_LONG_CMP,false,"lcmp"},
        
@@ -1368,18 +1292,26 @@ builtin_descriptor builtin_desc[] = {
                     SUPPORT_FLOAT && SUPPORT_FICVT,true ,"f2i"},
        {ICMD_D2I  , BUILTIN_d2i  ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID  ,TYPE_VOID ,TYPE_INT   ,
                     SUPPORT_DOUBLE && SUPPORT_FICVT,true ,"d2i"},
+#endif
 
        /* this record marks the end of the automatically replaced opcodes */
-       {255       , NULL        ,0            ,0          ,0          ,0         ,0          ,
-                    true                            ,false,"<INVALID>"},
+       {255,NULL,0,0,0,0,0,0,0,"<INVALID>"},
 
        /* the following functions are not replaced automatically */
+       
+#if defined(__ALPHA__)
+       {255, BUILTIN_f2l  ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID  ,TYPE_VOID ,TYPE_LONG  ,0,0,"f2l"},
+       {255, BUILTIN_d2l  ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID  ,TYPE_VOID ,TYPE_LONG  ,0,0,"d2l"},
+       {255, BUILTIN_f2i  ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID  ,TYPE_VOID ,TYPE_INT   ,0,0,"f2i"},
+       {255, BUILTIN_d2i  ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID  ,TYPE_VOID ,TYPE_INT   ,0,0,"d2i"},
+#endif
+
        {255,BUILTIN_instanceof      ,ICMD_BUILTIN2,TYPE_ADR   ,TYPE_ADR   ,TYPE_VOID  ,TYPE_INT   ,0,0,"instanceof"},
        {255,BUILTIN_arrayinstanceof ,ICMD_BUILTIN2,TYPE_ADR   ,TYPE_ADR   ,TYPE_VOID  ,TYPE_INT   ,0,0,"arrayinstanceof"},
        {255,BUILTIN_checkarraycast  ,ICMD_BUILTIN2,TYPE_ADR   ,TYPE_ADR   ,TYPE_VOID  ,TYPE_VOID  ,0,0,"checkarraycast"},
        {255,BUILTIN_aastore         ,ICMD_BUILTIN3,TYPE_ADR   ,TYPE_INT   ,TYPE_ADR   ,TYPE_VOID  ,0,0,"aastore"},
        {255,BUILTIN_new             ,ICMD_BUILTIN1,TYPE_ADR   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"new"},
-       {255,BUILTIN_newarray        ,ICMD_BUILTIN1,TYPE_ADR   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray"},
+       {255,BUILTIN_newarray        ,ICMD_BUILTIN2,TYPE_INT   ,TYPE_ADR   ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray"},
        {255,BUILTIN_newarray_boolean,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_boolean"},
        {255,BUILTIN_newarray_char   ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_char"},
        {255,BUILTIN_newarray_float  ,ICMD_BUILTIN1,TYPE_INT   ,TYPE_VOID  ,TYPE_VOID  ,TYPE_ADR   ,0,0,"newarray_float"},
@@ -1407,10 +1339,6 @@ builtin_descriptor builtin_desc[] = {
 
 /* include compiler subsystems ************************************************/
 
-/* from codegen.inc */
-extern int dseglen;
-
-
 /* dummy function, used when there is no JavaVM code available                */
 
 static void* do_nothing_function()
@@ -1421,206 +1349,318 @@ static void* do_nothing_function()
 
 /* jit_compile *****************************************************************
 
-       jit_compile, new version of compiler, translates one method to machine code
+   jit_compile, new version of compiler, translates one method to machine code
 
 *******************************************************************************/
 
-methodptr jit_compile(methodinfo *m)
+static functionptr jit_compile_intern(methodinfo *m, codegendata *cd,
+                                                                         registerdata *rd, loopdata *ld,
+                                                                         t_inlining_globals *id);
+
+functionptr jit_compile(methodinfo *m)
 {
-       int dumpsize;
-       long starttime = 0;
-       long stoptime  = 0;
+       static bool jitrunning;
+       functionptr r;
+       s4 dumpsize;
+       codegendata *cd;
+       registerdata *rd;
+       loopdata *ld;
+       t_inlining_globals *id;
+
+       if (opt_stat)
+               count_jit_calls++;
+
+       /* enter a monitor on the method */
 
-       count_jit_calls++;
+       builtin_monitorenter((java_objectheader *) m);
 
        /* if method has been already compiled return immediately */
 
-       if (m->entrypoint)
+       if (m->entrypoint) {
+               builtin_monitorexit((java_objectheader *) m);
+
                return m->entrypoint;
+       }
+
+       if (opt_stat)
+               count_methods++;
+
+       /* if there is no javacode, print error message and return empty method   */
+
+       if (!m->jcode) {
+               if (compileverbose)
+                       log_message_method("No code given for: ", m);
+
+               /*m->entrypoint = (methodptr) do_nothing_function;*/
+               m->entrypoint = (functionptr) do_nothing_function;
+
+               return m->entrypoint;    /* return empty method     */
+       }
+
+#if 0
+       if (jitrunning) {
+               printf("JITRUNNING!!! new method=");
+               utf_display_classname(m->class->name);printf(".");utf_display(m->name);
+               printf("\n");
+       }
+
+       /* now the jit is running */
 
-       count_methods++;
+       jitrunning = true;
+#endif
 
-       intsDisable();      /* disable interrupts */
+       /* measure time */
 
-       regs_ok = false;
+       if (getcompilingtime)
+               compilingtime_start();
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
+       /* allocate memory */
+
+       cd = DNEW(codegendata);
+       rd = DNEW(registerdata);
+       ld = DNEW(loopdata);
+       id = DNEW(t_inlining_globals);
+
+       /* RTA static analysis must be called before inlining */
+       if (opt_rt)
+               RT_jit_parse(m); /* will be called just once */
+                            /* return value ignored for now */
+
+       /* must be called before reg_setup, because it can change maxlocals */
+       /* init reqd to initialize for parse even in no inlining */
+       inlining_setup(m, id);
+
+       /* initialize the register allocator */
+       reg_setup(m, rd, id);
+
+       /* setup the codegendata memory */
+       codegen_setup(m, cd, id);
+
+       /* now call internal compile function */
+
+       r = jit_compile_intern(m, cd, rd, ld, id);
+
+       /* free some memory */
+
+       reg_free(m, rd);
+       codegen_free(m, cd);
+
+       /* clear pointers to dump memory area */
+
+       m->basicblocks = NULL;
+       m->basicblockindex = NULL;
+       m->instructions = NULL;
+       m->stack = NULL;
+       /* NO !!! m->exceptiontable = NULL; */
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
        /* measure time */
 
        if (getcompilingtime)
-               starttime = getcputime();
+               compilingtime_stop();
 
-       /* if there is no javacode print error message and return empty method    */
+       jitrunning = false;
 
-       if (!m->jcode) {
-               char logtext[MAXLOGTEXT];
-               sprintf(logtext, "No code given for: ");
-               utf_sprint(logtext+strlen(logtext), m->class->name);
-               strcpy(logtext+strlen(logtext), ".");
-               utf_sprint(logtext+strlen(logtext), m->name);
-               utf_sprint(logtext+strlen(logtext), m->descriptor);
-               dolog(logtext);
-               intsRestore();                             /* enable interrupts again */
-               return (methodptr) do_nothing_function;    /* return empty method     */
+        /* define in options.h; Used in main.c, jit.c & inline.c */
+       #ifdef INAFTERMAIN
+       if ((utf_new_char("main") == m->name) && (useinliningm))
+               useinlining = false;
+       #endif
+
+       /* leave the monitor */
+
+       builtin_monitorexit((java_objectheader *) m );
+
+       if (r) {
+               if (compileverbose)
+                       log_message_method("Running: ", m);
        }
 
+       /* return pointer to the methods entry point */
+
+       return r;
+}
+
+
+/* jit_compile_intern **********************************************************
+
+   Static internal function which does the actual compilation.
+
+*******************************************************************************/
+
+static functionptr jit_compile_intern(methodinfo *m, codegendata *cd,
+                                                                         registerdata *rd, loopdata *ld,
+                                                                         t_inlining_globals *id)
+{
        /* print log message for compiled method */
 
-       if (compileverbose) {
-               char logtext[MAXLOGTEXT];
-               sprintf(logtext, "Compiling: ");
-               utf_sprint(logtext+strlen(logtext), m->class->name);
-               strcpy(logtext+strlen(logtext), ".");
-               utf_sprint(logtext+strlen(logtext), m->name);
-               utf_sprint(logtext+strlen(logtext), m->descriptor);
-               dolog(logtext);
-       }
+       if (compileverbose)
+               log_message_method("Compiling: ", m);
+
+       /* initialize the static function's class */
 
+       if (m->flags & ACC_STATIC && !m->class->initialized) {
+               if (initverbose)
+                       log_message_class("Initialize class ", m->class);
+
+               if (!class_init(m->class))
+                       return NULL;
+       }
 
        /* initialisation of variables and subsystems */
 
-       isleafmethod = true;
-
-       method = m;
-       class = m->class;
-       descriptor = m->descriptor;
-       maxstack = m->maxstack;
-       maxlocals = m->maxlocals;
-       jcodelength = m->jcodelength;
-       jcode = m->jcode;
-       exceptiontablelength = m->exceptiontablelength;
-       raw_extable = m->exceptiontable;
-
-#ifdef STATISTICS
-       count_tryblocks += exceptiontablelength;
-       count_javacodesize += jcodelength + 18;
-       count_javaexcsize += exceptiontablelength * POINTERSIZE;
+       m->isleafmethod = true;
+
+#if defined(STATISTICS)
+       if (opt_stat) {
+               count_tryblocks += m->exceptiontablelength;
+               count_javacodesize += m->jcodelength + 18;
+               count_javaexcsize += m->exceptiontablelength * POINTERSIZE;
+       }
 #endif
 
        /* initialise parameter type descriptor */
 
        descriptor2types(m);
-       mreturntype = m->returntype;
-       mparamcount = m->paramcount;
-       mparamtypes = m->paramtypes;
 
-       /* initialize class list with class the compiled method belongs to */
+#if defined(__I386__)
+       /* we try to use these registers as scratch registers */
+    if (m->exceptiontablelength > 0) {
+               method_uses_ecx = true;
+               method_uses_edx = true;
+
+       } else {
+               /* XXX when we use this, we have to save used registers in asm_
+                  functions (see asm_check_clinit */
+/*             method_uses_ecx = false; */
+/*             method_uses_edx = false; */
+               method_uses_ecx = true;
+               method_uses_edx = true;
+       }
+#endif
 
-       uninitializedclasses = chain_new(); 
-       compiler_addinitclass(m->class);
+       /* call the compiler passes ***********************************************/
 
+       if (compileverbose)
+               log_message_method("Parsing: ", m);
 
-       /* call the compiler passes ***********************************************/
+       /* call parse pass */
+       if (!parse(m, cd, id)) {
+               if (compileverbose)
+                       log_message_method("Exception while parsing: ", m);
 
-       /* must be call before reg_init, because it can change maxlocals */
-       if (useinlining)
-               inlining_init(m);
+               return NULL;
+       }
 
-       reg_init(m);
+       if (compileverbose) {
+               log_message_method("Parsing done: ", m);
+               log_message_method("Analysing: ", m);
+       }
 
-       codegen_init();
+       /* call stack analysis pass */
+       if (!analyse_stack(m, cd, rd)) {
+               if (compileverbose)
+                       log_message_method("Exception while analysing: ", m);
+
+               return NULL;
+       }
+
+       if (compileverbose)
+               log_message_method("Analysing done: ", m);
 
-       parse();
-       analyse_stack();
-   
 #ifdef CACAO_TYPECHECK
-       /* print log message for compiled method */
+       if (opt_verify) {
+               if (compileverbose)
+                       log_message_method("Typechecking: ", m);
 
-       if (compileverbose) {
-               char logtext[MAXLOGTEXT];
-               sprintf(logtext, "Typechecking: ");
-               utf_sprint(logtext+strlen(logtext), m->class->name);
-               strcpy(logtext+strlen(logtext), ".");
-               utf_sprint(logtext+strlen(logtext), m->name);
-               utf_sprint(logtext+strlen(logtext), m->descriptor);
-               dolog(logtext);
-       }
+               /* call typecheck pass */
+               if (!typecheck(m, cd, rd)) {
+                       if (compileverbose)
+                               log_message_method("Exception while typechecking: ", m);
 
-       typecheck();
-       
-       if (compileverbose) {
-               dolog("Typechecking done.");
+                       return NULL;
+               }
+
+               if (compileverbose)
+                       log_message_method("Typechecking done: ", m);
        }
 #endif
-       
+
        if (opt_loops) {
-               depthFirst();
-               analyseGraph();
-               optimize_loops();
+               depthFirst(m, ld);
+               analyseGraph(m, ld);
+               optimize_loops(m, cd, ld);
        }
    
 #ifdef SPECIALMEMUSE
-       preregpass();
+       preregpass(m, rd);
 #endif
 
-       regalloc();
-       regs_ok = true;
-       codegen();
+       if (compileverbose)
+               log_message_method("Allocating registers: ", m);
 
-       /* intermediate and assembly code listings ********************************/
-               
-       if (showintermediate)
-               show_icmd_method();
-       else if (showdisassemble)
-               disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
+       /* allocate registers */
+#ifdef LSRA
+       if (opt_lsra)
+               lsra(m, cd, rd, ld, id);
+       else
+#endif
+               regalloc(m, cd, rd);
 
-       if (showddatasegment)
-               dseg_display((void*) (m->mcode));
+       if (compileverbose) {
+               log_message_method("Allocating registers done: ", m);
+               log_message_method("Generating code: ", m);
+       }
 
-       /* release dump area */
+       /* now generate the machine code */
+       codegen(m, cd, rd);
 
-       dump_release(dumpsize);
+       if (compileverbose)
+               log_message_method("Generating code done: ", m);
 
-       /* measure time */
+       /* intermediate and assembly code listings */
+               
+       if (showintermediate) {
+               show_icmd_method(m, cd, rd);
 
-       if (getcompilingtime) {
-               stoptime = getcputime();
-               compilingtime += (stoptime-starttime); 
+       } else if (showdisassemble) {
+               disassemble((void *) ((long) m->mcode + cd->dseglen), 
+                                       m->mcodelength - cd->dseglen);
        }
 
-       /* initialize all used classes */
-       /* because of reentrant code global variables are not allowed here        */
-
-       {
-               chain *ul = uninitializedclasses;   /* list of uninitialized classes      */ 
-               classinfo *c;                       /* single class                       */
-
-               while ((c = chain_first(ul)) != NULL) {
-                       chain_remove(ul);
-                       class_init(c);                  /* may again call the compiler        */
-               }
-               chain_free(ul);
-       }
+       if (showddatasegment)
+               dseg_display(m, cd);
 
-       intsRestore();    /* enable interrupts again */
+       if (compileverbose)
+               log_message_method("Compiling done: ", m);
 
        /* return pointer to the methods entry point */
-       
+
        return m->entrypoint;
 } 
 
 
+void compile_all_class_methods(classinfo *c)
+{
+       s4 i;
+
+       for (i = 0; i < c->methodscount; i++) {
+               (void) jit_compile(&(c->methods[i]));
+       }
+}
+
 
 /* functions for compiler initialisation and finalisation *********************/
 
 #ifdef USEBUILTINTABLE
 
-/* XXX delete */
-#if 0
-static int stdopcompare(const void *a, const void *b)
-{
-       stdopdescriptor *o1 = (stdopdescriptor *) a;
-       stdopdescriptor *o2 = (stdopdescriptor *) b;
-       if (!o1->supported && o2->supported)
-               return -1;
-       if (o1->supported && !o2->supported)
-               return 1;
-       return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
-}
-#endif
 static int stdopcompare(const void *a, const void *b)
 {
        builtin_descriptor *o1 = (builtin_descriptor *) a;
@@ -1632,29 +1672,6 @@ static int stdopcompare(const void *a, const void *b)
        return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
 }
 
-/* XXX delete */
-#if 0
-static inline void sort_builtintable()
-{
-       int len;
-
-       len = sizeof(builtintable) / sizeof(stdopdescriptor);
-       qsort(builtintable, len, sizeof(builtin_descriptor), stdopcompare);
-
-       for (--len; len>=0 && builtintable[len].supported; len--);
-       builtintablelen = ++len;
-
-#if 0
-       {
-               int i;
-               for (i=0; i<len; i++)
-                       if (!builtintable[i].supported)
-                               printf("%s\n", icmd_names[builtintable[i].opcode]);
-       }
-#endif
-}
-#endif
-
 static inline void sort_builtintable()
 {
        int len;
@@ -1668,12 +1685,6 @@ static inline void sort_builtintable()
 }
 
 
-#if 0
-stdopdescriptor *find_builtin(int icmd)
-{
-       builtin_descriptor *first = builtintable;
-       builtin_descriptor *last = builtintable + builtintablelen;
-#endif
 builtin_descriptor *find_builtin(int icmd)
 {
        builtin_descriptor *first = builtin_desc;
@@ -1700,7 +1711,7 @@ builtin_descriptor *find_builtin(int icmd)
 
 void jit_init()
 {
-       int i;
+       s4 i;
 
 #ifdef USEBUILTINTABLE
        sort_builtintable();
@@ -1790,16 +1801,14 @@ void jit_init()
        stackreq[JAVA_DUP_X2] = 4;
        stackreq[JAVA_DUP2_X1] = 3;
        stackreq[JAVA_DUP2_X2] = 4;
-       
-       init_exceptions();
-}
 
+       /* initialize the codegen stuff */
+       codegen_init();
+}
 
 
 void jit_close()
 {
-       codegen_close();
-       reg_close();
 }