fix bug when jit_compile is entered recursively
[cacao.git] / src / vm / jit / jit.c
index e7506562a0edeefa1614b9353b900cfba875eed9..12dd4bc1290f4290298ae39e791b52c8ee9c1ed3 100644 (file)
@@ -29,7 +29,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: jit.c 732 2003-12-12 17:23:15Z stefan $
+   $Id: jit.c 923 2004-02-24 13:28:08Z edwin $
 
 */
 
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "global.h"    /* we define _GNU_SOURCE there */
+#include "main.h"
 #include "tables.h"
 #include "loader.h"
 #include "jit.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;
@@ -204,7 +180,14 @@ bool regs_ok;                   /* true if registers have been allocated      */
 chain *uninitializedclasses;
 
 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] = {
 
@@ -1375,16 +1358,23 @@ builtin_descriptor builtin_desc[] = {
 #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"},
@@ -1430,11 +1420,26 @@ static void* do_nothing_function()
 
 *******************************************************************************/
 
+#if 0
+#define LOG_STEP(step)                                                                                 \
+       if (compileverbose) {                                                                           \
+               char logtext[MAXLOGTEXT];                                                               \
+               sprintf(logtext, "%s: ",step);                                                  \
+               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);             \
+               log_text(logtext);                                                                              \
+       }
+#else
+#define LOG_STEP(step)
+#endif
+
 methodptr jit_compile(methodinfo *m)
 {
-       int dumpsize;
-       long starttime = 0;
-       long stoptime  = 0;
+       s4 dumpsize;
+       s8 starttime = 0;
+       s8 stoptime  = 0;
 
        count_jit_calls++;
 
@@ -1445,9 +1450,13 @@ methodptr jit_compile(methodinfo *m)
 
        count_methods++;
 
-       intsDisable();      /* disable interrupts */
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       pthread_mutex_lock(&compiler_mutex);
+#endif
 
-       regs_ok = false;
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
+       intsDisable();      /* disable interrupts */
+#endif
 
        /* mark start of dump memory area */
 
@@ -1468,7 +1477,9 @@ methodptr jit_compile(methodinfo *m)
                utf_sprint(logtext+strlen(logtext), m->name);
                utf_sprint(logtext+strlen(logtext), m->descriptor);
                log_text(logtext);
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
                intsRestore();                             /* enable interrupts again */
+#endif
                return (methodptr) do_nothing_function;    /* return empty method     */
        }
 
@@ -1484,6 +1495,16 @@ methodptr jit_compile(methodinfo *m)
                log_text(logtext);
        }
 
+       /* initialize the static function's class */
+       if (m->flags & ACC_STATIC && !m->class->initialized) {
+               if (initverbose) {
+                       char logtext[MAXLOGTEXT];
+                       sprintf(logtext, "Initialize class ");
+                       utf_sprint(logtext + strlen(logtext), m->class->name);
+                       log_text(logtext);
+               }
+               class_init(m->class);
+       }
 
        /* initialisation of variables and subsystems */
 
@@ -1498,6 +1519,7 @@ methodptr jit_compile(methodinfo *m)
        jcode = m->jcode;
        exceptiontablelength = m->exceptiontablelength;
        raw_extable = m->exceptiontable;
+       regs_ok = false;
 
 #ifdef STATISTICS
        count_tryblocks += exceptiontablelength;
@@ -1512,19 +1534,18 @@ methodptr jit_compile(methodinfo *m)
        mparamcount = m->paramcount;
        mparamtypes = m->paramtypes;
 
-       /* initialize class list with class the compiled method belongs to */
-
-       uninitializedclasses = chain_new(); 
-       compiler_addinitclass(m->class);
-
+#if defined(__I386__)
+       method_uses_ecx = true;
+       method_uses_edx = false;
+#endif
 
        /* call the compiler passes ***********************************************/
 
-       /* must be call before reg_init, because it can change maxlocals */
+       /* must be called before reg_init, because it can change maxlocals */
        if (useinlining)
                inlining_init(m);
 
-       reg_init(m);
+       reg_setup();
 
        codegen_init();
 
@@ -1532,22 +1553,10 @@ methodptr jit_compile(methodinfo *m)
        analyse_stack();
    
 #ifdef CACAO_TYPECHECK
-       /* print log message for compiled method */
-
-       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);
-               log_text(logtext);
-       }
-
-       typecheck();
-       
-       if (compileverbose) {
-               dolog("Typechecking done.");
+       if (opt_verify) {
+               LOG_STEP("Typechecking");
+               typecheck();
+               LOG_STEP("Done typechecking");
        }
 #endif
        
@@ -1561,8 +1570,11 @@ methodptr jit_compile(methodinfo *m)
        preregpass();
 #endif
 
+       LOG_STEP("Regalloc");
        regalloc();
        regs_ok = true;
+
+       LOG_STEP("Codegen");
        codegen();
 
        /* intermediate and assembly code listings ********************************/
@@ -1583,27 +1595,20 @@ methodptr jit_compile(methodinfo *m)
 
        if (getcompilingtime) {
                stoptime = getcputime();
-               compilingtime += (stoptime-starttime); 
-       }
-
-       /* 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);
+               compilingtime += (stoptime - starttime);
        }
 
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
        intsRestore();    /* enable interrupts again */
+#endif
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       pthread_mutex_unlock(&compiler_mutex);
+#endif
 
        /* return pointer to the methods entry point */
        
+       LOG_STEP("Done compiling");
        return m->entrypoint;
 } 
 
@@ -1613,19 +1618,6 @@ methodptr jit_compile(methodinfo *m)
 
 #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;
@@ -1637,29 +1629,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;
@@ -1673,12 +1642,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;
@@ -1795,7 +1758,8 @@ void jit_init()
        stackreq[JAVA_DUP_X2] = 4;
        stackreq[JAVA_DUP2_X1] = 3;
        stackreq[JAVA_DUP2_X2] = 4;
-       
+
+       reg_init();
        init_exceptions();
 }