Changes: Edwin Steiner
Christian Thalinger
+ Christian Ullrich
- $Id: jit.c 2953 2005-07-09 13:38:42Z twisti $
+ $Id: jit.c 3744 2005-11-22 23:42:43Z twisti $
*/
#include "config.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/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"
#if defined(USE_INLINING)
-#include "vm/jit/inline/inline.h"
-#include "vm/jit/inline/parseRT.h"
-#include "vm/jit/inline/parseXTA.h"
+# 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"
#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 */
"PUTFIELDCONST ", /* 213 */
"IMULPOW2 ", /* 214 */
"LMULPOW2 ", /* 215 */
- "ARRAYCHECKCAST ", /* 216 */
- "UNDEF217", "UNDEF218", "UNDEF219", "UNDEF220",
+ "UNDEF216", "UNDEF217", "UNDEF218", "UNDEF219", "UNDEF220",
"UNDEF221", "UNDEF222", "UNDEF223", "UNDEF224", "UNDEF225",
"UNDEF226", "UNDEF227", "UNDEF228", "UNDEF229", "UNDEF230",
"UNDEF231", "UNDEF232", "UNDEF233", "UNDEF234", "UNDEF235",
};
-/* 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) (ptrint) 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 */
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;
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);
show_icmd_method(m, cd, rd);
} else if (opt_showdisassemble) {
- disassemble((void *) ((long) m->mcode + cd->dseglen),
- m->mcodelength - cd->dseglen);
+ disassemble((u1 *) (ptrint) m->entrypoint,
+ (u1 *) (ptrint) m->entrypoint + (m->mcodelength - cd->dseglen));
}
if (opt_showddatasegment)
if (compileverbose)
log_message_method("Compiling done: ", m);
-#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]));
- }
-}
-
-
-/* jit_init ********************************************************************
-
- XXX
-
-*******************************************************************************/
-
-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_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