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 $
*/
#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;
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] = {
#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"},
*******************************************************************************/
+#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++;
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 */
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 */
}
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 */
jcode = m->jcode;
exceptiontablelength = m->exceptiontablelength;
raw_extable = m->exceptiontable;
+ regs_ok = false;
#ifdef STATISTICS
count_tryblocks += exceptiontablelength;
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();
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
preregpass();
#endif
+ LOG_STEP("Regalloc");
regalloc();
regs_ok = true;
+
+ LOG_STEP("Codegen");
codegen();
/* intermediate and assembly code listings ********************************/
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;
}
#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;
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;
}
-#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;
stackreq[JAVA_DUP_X2] = 4;
stackreq[JAVA_DUP2_X1] = 3;
stackreq[JAVA_DUP2_X2] = 4;
-
+
+ reg_init();
init_exceptions();
}