Changes: Edwin Steiner
Christian Thalinger
+ Christian Ullrich
- $Id: jit.c 2406 2005-04-28 12:19:06Z jowenn $
+ $Id: jit.c 3744 2005-11-22 23:42:43Z twisti $
*/
#include "config.h"
-#include "codegen.h"
-#include "disass.h"
-#include "types.h"
+
+#include "vm/types.h"
+
#include "mm/memory.h"
+#include "native/native.h"
#include "toolbox/logging.h"
#include "vm/builtin.h"
#include "vm/class.h"
#include "vm/options.h"
#include "vm/statistics.h"
#include "vm/tables.h"
+#include "vm/jit/asmpart.h"
#include "vm/jit/codegen.inc.h"
+#include "vm/jit/disass.h"
#include "vm/jit/jit.h"
+
#ifdef LSRA
-#include "vm/jit/lsra.h"
+# 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/inline/parseXTA.h"
+
+#if defined(USE_INLINING)
+# include "vm/jit/inline/inline.h"
+# include "vm/jit/inline/parseRT.h"
+# include "vm/jit/inline/parseXTA.h"
+#endif
+
#include "vm/jit/loop/analyze.h"
#include "vm/jit/loop/graph.h"
#include "vm/jit/loop/loop.h"
#define JAVA_INVOKEINTERFACE 185
#define ICMD_INVOKEINTERFACE 185 /* val.a = method info pointer */
5,
-#define ICMD_CHECKASIZE 186 /* */
- 1, /* unused */
+/* UNDEF186 */
+ 1,
#define JAVA_NEW 187
#define ICMD_NEW 187 /* op1 = 1, val.a = class pointer */
3,
5,
#define JAVA_BREAKPOINT 202
1,
-#define ICMD_CHECKEXCEPTION 203
+/* UNDEF 203 */
1,
#define ICMD_IASTORECONST 204
1,
"INVOKESPECIAL ", /* 183 */
"INVOKESTATIC ", /* 184 */
"INVOKEINTERFACE", /* 185 */
- "CHECKASIZE ", /* UNDEF186 186 */
+ "UNDEF186 ", /* UNDEF186 186 */
"NEW ", /* 187 */
"NEWARRAY ", /* 188 */
"ANEWARRAY ", /* 189 */
"UNDEF200 ", /* GOTO_W 200 */
"UNDEF201 ", /* JSR_W 201 */
"UNDEF202 ", /* BREAKPOINT 202 */
- "CHECKEXCEPTION ", /* UNDEF203 203 */
+ "UNDEF203 ", /* UNDEF203 203 */
"IASTORECONST ", /* 204 */
"LASTORECONST ", /* 205 */
"FASTORECONST ", /* 206 */
"INLINE_START ", /* 251 */
"INLINE_END ", /* 252 */
- "BUILTIN3 ", /* 253 */
- "BUILTIN2 ", /* 254 */
- "BUILTIN1 " /* 255 */
+ "UNDEF253", "UNDEF254",
+
+ "BUILTIN " /* 255 */
};
};
-/* include compiler subsystems ************************************************/
+/* jit_init ********************************************************************
+
+ Initializes the JIT subsystem.
+
+*******************************************************************************/
+
+void jit_init(void)
+{
+ s4 i;
+
+#if defined(__ALPHA__)
+ has_ext_instr_set = ! has_no_x_instr_set();
+#endif
+
+ for (i = 0; i < 256; i++)
+ stackreq[i] = 1;
+
+ stackreq[JAVA_NOP] = 0;
+ stackreq[JAVA_ISTORE] = 0;
+ stackreq[JAVA_LSTORE] = 0;
+ stackreq[JAVA_FSTORE] = 0;
+ stackreq[JAVA_DSTORE] = 0;
+ stackreq[JAVA_ASTORE] = 0;
+ stackreq[JAVA_ISTORE_0] = 0;
+ stackreq[JAVA_ISTORE_1] = 0;
+ stackreq[JAVA_ISTORE_2] = 0;
+ stackreq[JAVA_ISTORE_3] = 0;
+ stackreq[JAVA_LSTORE_0] = 0;
+ stackreq[JAVA_LSTORE_1] = 0;
+ stackreq[JAVA_LSTORE_2] = 0;
+ stackreq[JAVA_LSTORE_3] = 0;
+ stackreq[JAVA_FSTORE_0] = 0;
+ stackreq[JAVA_FSTORE_1] = 0;
+ stackreq[JAVA_FSTORE_2] = 0;
+ stackreq[JAVA_FSTORE_3] = 0;
+ stackreq[JAVA_DSTORE_0] = 0;
+ stackreq[JAVA_DSTORE_1] = 0;
+ stackreq[JAVA_DSTORE_2] = 0;
+ stackreq[JAVA_DSTORE_3] = 0;
+ stackreq[JAVA_ASTORE_0] = 0;
+ stackreq[JAVA_ASTORE_1] = 0;
+ stackreq[JAVA_ASTORE_2] = 0;
+ stackreq[JAVA_ASTORE_3] = 0;
+ stackreq[JAVA_IASTORE] = 0;
+ stackreq[JAVA_LASTORE] = 0;
+ stackreq[JAVA_FASTORE] = 0;
+ stackreq[JAVA_DASTORE] = 0;
+ stackreq[JAVA_AASTORE] = 0;
+ stackreq[JAVA_BASTORE] = 0;
+ stackreq[JAVA_CASTORE] = 0;
+ stackreq[JAVA_SASTORE] = 0;
+ stackreq[JAVA_POP] = 0;
+ stackreq[JAVA_POP2] = 0;
+ stackreq[JAVA_IFEQ] = 0;
+ stackreq[JAVA_IFNE] = 0;
+ stackreq[JAVA_IFLT] = 0;
+ stackreq[JAVA_IFGE] = 0;
+ stackreq[JAVA_IFGT] = 0;
+ stackreq[JAVA_IFLE] = 0;
+ stackreq[JAVA_IF_ICMPEQ] = 0;
+ stackreq[JAVA_IF_ICMPNE] = 0;
+ stackreq[JAVA_IF_ICMPLT] = 0;
+ stackreq[JAVA_IF_ICMPGE] = 0;
+ stackreq[JAVA_IF_ICMPGT] = 0;
+ stackreq[JAVA_IF_ICMPLE] = 0;
+ stackreq[JAVA_IF_ACMPEQ] = 0;
+ stackreq[JAVA_IF_ACMPNE] = 0;
+ stackreq[JAVA_GOTO] = 0;
+ stackreq[JAVA_RET] = 0;
+ stackreq[JAVA_TABLESWITCH] = 0;
+ stackreq[JAVA_LOOKUPSWITCH] = 0;
+ stackreq[JAVA_IRETURN] = 0;
+ stackreq[JAVA_LRETURN] = 0;
+ stackreq[JAVA_FRETURN] = 0;
+ stackreq[JAVA_DRETURN] = 0;
+ stackreq[JAVA_ARETURN] = 0;
+ stackreq[JAVA_RETURN] = 0;
+ stackreq[JAVA_PUTSTATIC] = 0;
+ stackreq[JAVA_PUTFIELD] = 0;
+ stackreq[JAVA_MONITORENTER] = 0;
+ stackreq[JAVA_MONITOREXIT] = 0;
+ stackreq[JAVA_WIDE] = 0;
+ stackreq[JAVA_IFNULL] = 0;
+ stackreq[JAVA_IFNONNULL] = 0;
+ stackreq[JAVA_GOTO_W] = 0;
+ stackreq[JAVA_BREAKPOINT] = 0;
+
+ /* we need one dummy stack slot for IINC in order to */
+ /* avoid that the modified local variable is */
+ /* kept on the stack (see stack.c, ICMD_IINC) */
+ stackreq[JAVA_IINC] = 1;
+
+ stackreq[JAVA_SWAP] = 2;
+ stackreq[JAVA_DUP2] = 2;
+ stackreq[JAVA_DUP_X1] = 3;
+ stackreq[JAVA_DUP_X2] = 4;
+ stackreq[JAVA_DUP2_X1] = 3;
+ stackreq[JAVA_DUP2_X2] = 4;
+
+ /* initialize stack analysis subsystem */
+
+ (void) stack_init();
+
+ /* initialize codegen subsystem */
+
+ codegen_init();
+}
+
+
+/* jit_close *******************************************************************
+
+ Close the JIT subsystem.
+
+*******************************************************************************/
+
+void jit_close(void)
+{
+ /* do nothing */
+}
+
/* dummy function, used when there is no JavaVM code available */
-static functionptr do_nothing_function()
+static u1 *do_nothing_function(void)
{
return NULL;
}
*******************************************************************************/
-static functionptr jit_compile_intern(methodinfo *m, codegendata *cd,
- registerdata *rd, loopdata *ld,
- t_inlining_globals *id);
+static u1 *jit_compile_intern(methodinfo *m, codegendata *cd, registerdata *rd,
+ loopdata *ld, t_inlining_globals *id);
-functionptr jit_compile(methodinfo *m)
+u1 *jit_compile(methodinfo *m)
{
- functionptr r;
+ u1 *r;
codegendata *cd;
registerdata *rd;
loopdata *ld;
count_jit_calls++;
#endif
- /* this is the case if a native function is called by jni */
-
- if (m->flags & ACC_NATIVE)
- return (functionptr) m->stubroutine;
-
#if defined(USE_THREADS)
/* enter a monitor on the method */
count_methods++;
#endif
- /* 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 = (functionptr) do_nothing_function;
-
- return m->entrypoint; /* return empty method */
- }
-
#if defined(STATISTICS)
/* measure time */
ld = DNEW(loopdata);
id = DNEW(t_inlining_globals);
+#if defined(USE_INLINING)
/* RTA static analysis must be called before inlining */
if (opt_rt)
RT_jit_parse(m); /* will be called just once */
XTA_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);
+#endif
- /* initialize the register allocator */
- reg_setup(m, rd, id);
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (!opt_intrp)
+# endif
+ /* initialize the register allocator */
+ reg_setup(m, rd, id);
+#endif
/* setup the codegendata memory */
codegen_setup(m, cd, id);
/* free some memory */
- reg_free(m, rd);
- codegen_free(m, cd);
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (!opt_intrp)
+# endif
+ codegen_free(m, cd);
+#endif
/* clear pointers to dump memory area */
*******************************************************************************/
-static functionptr jit_compile_intern(methodinfo *m, codegendata *cd,
- registerdata *rd, loopdata *ld,
- t_inlining_globals *id)
+static u1 *jit_compile_intern(methodinfo *m, codegendata *cd, registerdata *rd,
+ loopdata *ld, t_inlining_globals *id)
{
-#ifdef LSRA
- bool old_opt_lsra;
-#endif
-
-
/* print log message for compiled method */
if (compileverbose)
/* initialize the static function's class */
- if (m->flags & ACC_STATIC && !m->class->initialized) {
+ if ((m->flags & ACC_STATIC) && !m->class->initialized) {
if (initverbose)
log_message_class("Initialize class ", m->class);
return NULL;
}
+ /* handle native methods and create a native stub */
+
+ if (m->flags & ACC_NATIVE) {
+ functionptr f;
+
+#if defined(ENABLE_STATICVM)
+ f = native_findfunction(m->class->name, m->name, m->descriptor,
+ (m->flags & ACC_STATIC));
+ if (!f)
+ return NULL;
+#else
+
+ f = NULL;
+#endif
+
+ m->entrypoint = codegen_createnativestub(f, m);
+
+ return m->entrypoint;
+ }
+
+ /* 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 = (u1 *) (ptrint) do_nothing_function;
+
+ return m->entrypoint; /* return empty method */
+ }
+
/* initialisation of variables and subsystems */
m->isleafmethod = true;
if (opt_stat) {
count_tryblocks += m->exceptiontablelength;
count_javacodesize += m->jcodelength + 18;
- count_javaexcsize += m->exceptiontablelength * POINTERSIZE;
+ count_javaexcsize += m->exceptiontablelength * SIZEOF_VOID_P;
}
#endif
log_message_method("Parsing: ", m);
/* call parse pass */
+
if (!parse(m, cd, id)) {
if (compileverbose)
log_message_method("Exception while parsing: ", m);
}
/* call stack analysis pass */
+
if (!analyse_stack(m, cd, rd)) {
if (compileverbose)
log_message_method("Exception while analysing: ", m);
analyseGraph(m, ld);
optimize_loops(m, cd, ld);
}
-
-#ifdef SPECIALMEMUSE
-/* preregpass(m, rd); */
-#endif
- if (compileverbose)
- log_message_method("Allocating registers: ", m);
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (!opt_intrp) {
+# endif
+ if (compileverbose)
+ log_message_method("Allocating registers: ", m);
- /* allocate registers */
+ /* allocate registers */
#ifdef LSRA
- old_opt_lsra=opt_lsra;
- if (opt_lsra) {
- if (!lsra(m, cd, rd, id)) {
- opt_lsra = false;
-/* log_message_method("Regalloc Fallback: ", m); */
- regalloc( m, cd, rd );
- } else {
+ if (opt_lsra) {
+ lsra(m, cd, rd, id);
#ifdef STATISTICS
if (opt_stat) count_methods_allocated_by_lsra++;
#endif
-/* log_message_method("Regalloc LSRA: ", m); */
- }
- }
- else
+ } else
#endif /* LSRA */
- {
+ {
#ifdef STATISTICS
- if (opt_stat)
-#ifdef LSRA
- if (!opt_lsra)
-#endif
+ if (opt_stat)
count_locals_conflicts += (cd->maxlocals-1)*(cd->maxlocals);
#endif
- regalloc(m, cd, rd);
- }
+ regalloc(m, cd, rd);
+ }
#ifdef STATISTICS
- if (opt_stat)
- reg_make_statistics(m, cd, rd);
+ if (opt_stat)
+ reg_make_statistics(m, cd, rd);
#endif
- if (compileverbose) {
- log_message_method("Allocating registers done: ", m);
- log_message_method("Generating code: ", m);
+ if (compileverbose)
+ log_message_method("Allocating registers done: ", m);
+# if defined(ENABLE_INTRP)
}
+# endif
+#endif /* defined(ENABLE_JIT) */
+
+ if (compileverbose)
+ log_message_method("Generating code: ", m);
/* now generate the machine code */
- codegen(m, cd, rd);
+
+ if (!codegen(m, cd, rd)) {
+ if (compileverbose)
+ log_message_method("Exception while generating code: ", m);
+
+ return NULL;
+ }
if (compileverbose)
log_message_method("Generating code done: ", m);
/* intermediate and assembly code listings */
- if (showintermediate) {
+ if (opt_showintermediate) {
show_icmd_method(m, cd, rd);
- } else if (showdisassemble) {
- disassemble((void *) ((long) m->mcode + cd->dseglen),
- m->mcodelength - cd->dseglen);
+ } else if (opt_showdisassemble) {
+ disassemble((u1 *) (ptrint) m->entrypoint,
+ (u1 *) (ptrint) m->entrypoint + (m->mcodelength - cd->dseglen));
}
- if (showddatasegment)
+ if (opt_showddatasegment)
dseg_display(m, cd);
- if (compileverbose) {
+ if (compileverbose)
log_message_method("Compiling done: ", m);
- printf("%p - %p\n",(void *) ((long) m->mcode + cd->dseglen),(void *) ((long) m->mcode + m->mcodelength));
- }
-#ifdef LSRA
- opt_lsra=old_opt_lsra;
-#endif
/* 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 *********************/
-
-void jit_init(void)
-{
- s4 i;
-
-#if defined(USEBUILTINTABLE)
- sort_builtintable();
-#endif
-
-#if defined(__ALPHA__)
- has_ext_instr_set = ! has_no_x_instr_set();
-#endif
-
- for (i = 0; i < 256; i++)
- stackreq[i] = 1;
-
- stackreq[JAVA_NOP] = 0;
- stackreq[JAVA_ISTORE] = 0;
- stackreq[JAVA_LSTORE] = 0;
- stackreq[JAVA_FSTORE] = 0;
- stackreq[JAVA_DSTORE] = 0;
- stackreq[JAVA_ASTORE] = 0;
- stackreq[JAVA_ISTORE_0] = 0;
- stackreq[JAVA_ISTORE_1] = 0;
- stackreq[JAVA_ISTORE_2] = 0;
- stackreq[JAVA_ISTORE_3] = 0;
- stackreq[JAVA_LSTORE_0] = 0;
- stackreq[JAVA_LSTORE_1] = 0;
- stackreq[JAVA_LSTORE_2] = 0;
- stackreq[JAVA_LSTORE_3] = 0;
- stackreq[JAVA_FSTORE_0] = 0;
- stackreq[JAVA_FSTORE_1] = 0;
- stackreq[JAVA_FSTORE_2] = 0;
- stackreq[JAVA_FSTORE_3] = 0;
- stackreq[JAVA_DSTORE_0] = 0;
- stackreq[JAVA_DSTORE_1] = 0;
- stackreq[JAVA_DSTORE_2] = 0;
- stackreq[JAVA_DSTORE_3] = 0;
- stackreq[JAVA_ASTORE_0] = 0;
- stackreq[JAVA_ASTORE_1] = 0;
- stackreq[JAVA_ASTORE_2] = 0;
- stackreq[JAVA_ASTORE_3] = 0;
- stackreq[JAVA_IASTORE] = 0;
- stackreq[JAVA_LASTORE] = 0;
- stackreq[JAVA_FASTORE] = 0;
- stackreq[JAVA_DASTORE] = 0;
- stackreq[JAVA_AASTORE] = 0;
- stackreq[JAVA_BASTORE] = 0;
- stackreq[JAVA_CASTORE] = 0;
- stackreq[JAVA_SASTORE] = 0;
- stackreq[JAVA_POP] = 0;
- stackreq[JAVA_POP2] = 0;
- stackreq[JAVA_IINC] = 0;
- stackreq[JAVA_IFEQ] = 0;
- stackreq[JAVA_IFNE] = 0;
- stackreq[JAVA_IFLT] = 0;
- stackreq[JAVA_IFGE] = 0;
- stackreq[JAVA_IFGT] = 0;
- stackreq[JAVA_IFLE] = 0;
- stackreq[JAVA_IF_ICMPEQ] = 0;
- stackreq[JAVA_IF_ICMPNE] = 0;
- stackreq[JAVA_IF_ICMPLT] = 0;
- stackreq[JAVA_IF_ICMPGE] = 0;
- stackreq[JAVA_IF_ICMPGT] = 0;
- stackreq[JAVA_IF_ICMPLE] = 0;
- stackreq[JAVA_IF_ACMPEQ] = 0;
- stackreq[JAVA_IF_ACMPNE] = 0;
- stackreq[JAVA_GOTO] = 0;
- stackreq[JAVA_RET] = 0;
- stackreq[JAVA_TABLESWITCH] = 0;
- stackreq[JAVA_LOOKUPSWITCH] = 0;
- stackreq[JAVA_IRETURN] = 0;
- stackreq[JAVA_LRETURN] = 0;
- stackreq[JAVA_FRETURN] = 0;
- stackreq[JAVA_DRETURN] = 0;
- stackreq[JAVA_ARETURN] = 0;
- stackreq[JAVA_RETURN] = 0;
- stackreq[JAVA_PUTSTATIC] = 0;
- stackreq[JAVA_PUTFIELD] = 0;
- stackreq[JAVA_MONITORENTER] = 0;
- stackreq[JAVA_MONITOREXIT] = 0;
- stackreq[JAVA_WIDE] = 0;
- stackreq[JAVA_IFNULL] = 0;
- stackreq[JAVA_IFNONNULL] = 0;
- stackreq[JAVA_GOTO_W] = 0;
- stackreq[JAVA_BREAKPOINT] = 0;
-
- stackreq[JAVA_SWAP] = 2;
- stackreq[JAVA_DUP2] = 2;
- stackreq[JAVA_DUP_X1] = 3;
- stackreq[JAVA_DUP_X2] = 4;
- stackreq[JAVA_DUP2_X1] = 3;
- stackreq[JAVA_DUP2_X2] = 4;
-
- /* initialize the codegen stuff */
- codegen_init();
-}
-
-
-void jit_close()
-{
-}
-
-
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where