-/* vm/jit/jit.c - calls the code generation functions
+/* src/vm/jit/jit.c - calls the code generation functions
Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
Reinhard Grafl
Changes: Edwin Steiner
+ Christian Thalinger
- $Id: jit.c 1892 2005-01-31 17:05:53Z twisti $
+ $Id: jit.c 3327 2005-10-04 18:49:56Z twisti $
*/
-#include "codegen.h"
-#include "disass.h"
-#include "types.h"
+#include "config.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/global.h"
+#include "vm/initialize.h"
#include "vm/loader.h"
+#include "vm/method.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 ICMD_ACONST 1 /* val.a = constant */
1,
#define JAVA_ICONST_M1 2
-#define ICMD_NULLCHECKPOP 2
+#define ICMD_CHECKNULL 2
1,
#define JAVA_ICONST_0 3
#define ICMD_ICONST 3 /* val.i = constant */
#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,
1,
#define ICMD_SASTORECONST 211
1,
+#define ICMD_PUTSTATICCONST 212
+ 1,
+#define ICMD_PUTFIELDCONST 213
+ 1,
+#define ICMD_IMULPOW2 214
+ 1,
+#define ICMD_LMULPOW2 215
+ 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,1,1,1,1,
char *icmd_names[256] = {
"NOP ", /* 0 */
"ACONST ", /* 1 */
- "NULLCHECKPOP ", /* ICONST_M1 2 */
+ "CHECKNULL ", /* ICONST_M1 2 */
"ICONST ", /* 3 */
"UNDEF4 ", /* ICONST_1 4 */
"IDIVPOW2 ", /* ICONST_2 5 */
"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 */
"BASTORECONST ", /* 209 */
"CASTORECONST ", /* 210 */
"SASTORECONST ", /* 211 */
+ "PUTSTATICCONST ", /* 212 */
+ "PUTFIELDCONST ", /* 213 */
+ "IMULPOW2 ", /* 214 */
+ "LMULPOW2 ", /* 215 */
+ "ARRAYCHECKCAST ", /* 216 */
- "UNDEF212", "UNDEF213", "UNDEF214", "UNDEF215",
- "UNDEF216", "UNDEF217", "UNDEF218", "UNDEF219", "UNDEF220",
+ "UNDEF217", "UNDEF218", "UNDEF219", "UNDEF220",
"UNDEF221", "UNDEF222", "UNDEF223", "UNDEF224", "UNDEF225",
"UNDEF226", "UNDEF227", "UNDEF228", "UNDEF229", "UNDEF230",
"UNDEF231", "UNDEF232", "UNDEF233", "UNDEF234", "UNDEF235",
"INLINE_START ", /* 251 */
"INLINE_END ", /* 252 */
- "BUILTIN3 ", /* 253 */
- "BUILTIN2 ", /* 254 */
- "BUILTIN1 " /* 255 */
+ "UNDEF253", "UNDEF254",
+
+ "BUILTIN " /* 255 */
};
};
-#if defined(USEBUILTINTABLE)
-
-#if 0
-stdopdescriptor builtintable[] = {
- { ICMD_LCMP, TYPE_LONG, TYPE_LONG, TYPE_INT, ICMD_BUILTIN2,
- (functionptr) builtin_lcmp , SUPPORT_LONG && SUPPORT_LONG_CMP, false },
- { ICMD_LAND, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_land , SUPPORT_LONG && SUPPORT_LONG_LOG, false },
- { ICMD_LOR, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_lor , SUPPORT_LONG && SUPPORT_LONG_LOG, false },
- { ICMD_LXOR, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_lxor , SUPPORT_LONG && SUPPORT_LONG_LOG, false },
- { ICMD_LSHL, TYPE_LONG, TYPE_INT, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_lshl , SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
- { ICMD_LSHR, TYPE_LONG, TYPE_INT, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_lshr, SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
- { ICMD_LUSHR, TYPE_LONG, TYPE_INT, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_lushr, SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
- { ICMD_LADD, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_ladd , SUPPORT_LONG && SUPPORT_LONG_ADD, false },
- { ICMD_LSUB, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_lsub , SUPPORT_LONG && SUPPORT_LONG_ADD, false },
- { ICMD_LNEG, TYPE_LONG, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1,
- (functionptr) builtin_lneg, SUPPORT_LONG && SUPPORT_LONG_ADD, true },
- { ICMD_LMUL, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2,
- (functionptr) builtin_lmul , SUPPORT_LONG && SUPPORT_LONG_MUL, false },
- { ICMD_I2F, TYPE_INT, TYPE_VOID, TYPE_FLOAT, ICMD_BUILTIN1,
- (functionptr) builtin_i2f, SUPPORT_FLOAT && SUPPORT_IFCVT, true },
- { ICMD_I2D, TYPE_INT, TYPE_VOID, TYPE_DOUBLE, ICMD_BUILTIN1,
- (functionptr) builtin_i2d, SUPPORT_DOUBLE && SUPPORT_IFCVT, true },
- { ICMD_L2F, TYPE_LONG, TYPE_VOID, TYPE_FLOAT, ICMD_BUILTIN1,
- (functionptr) builtin_l2f, SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT, true },
- { ICMD_L2D, TYPE_LONG, TYPE_VOID, TYPE_DOUBLE, ICMD_BUILTIN1,
- (functionptr) builtin_l2d, SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT, true },
- { ICMD_F2L, TYPE_FLOAT, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1,
- (functionptr) builtin_f2l, SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_ICVT, true },
- { ICMD_D2L, TYPE_DOUBLE, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1,
- (functionptr) builtin_d2l, SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_ICVT, true },
- { ICMD_F2I, TYPE_FLOAT, TYPE_VOID, TYPE_INT, ICMD_BUILTIN1,
- (functionptr) builtin_f2i, SUPPORT_FLOAT && SUPPORT_FICVT, true },
- { ICMD_D2I, TYPE_DOUBLE, TYPE_VOID, TYPE_INT, ICMD_BUILTIN1,
- (functionptr) builtin_d2i, SUPPORT_DOUBLE && SUPPORT_FICVT, true },
- { 255, 0, 0, 0, 0, NULL, true, false },
-};
+/* 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
-static int builtintablelen;
+ for (i = 0; i < 256; i++)
+ stackreq[i] = 1;
-#endif /* USEBUILTINTABLE */
+ 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 stack analysis subsystem */
-#define EXTABLEN
-/* \
- { \
- printf("PARSE method name ="); \
- utf_display(m->class->name); \
- printf("."); \
- method_display(m); \
- printf(" exceptiontablelength %d\n",m->exceptiontablelength); \
- fflush(stdout); \
- }
-*/
+ (void) stack_init();
-/*****************************************************************************
- TABLE OF BUILTIN FUNCTIONS
-
- This table lists the builtin functions which are used inside
- BUILTIN* opcodes.
-
- 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 "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"},
-
- {ICMD_LAND , BUILTIN_land ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_LOG,false,"land"},
- {ICMD_LOR , BUILTIN_lor ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_LOG,false,"lor"},
- {ICMD_LXOR , BUILTIN_lxor ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_LOG,false,"lxor"},
-
- {ICMD_LSHL , BUILTIN_lshl ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshl"},
- {ICMD_LSHR , BUILTIN_lshr ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshr"},
- {ICMD_LUSHR, BUILTIN_lushr,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lushr"},
-
- {ICMD_LADD , BUILTIN_ladd ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_ADD,false,"ladd"},
- {ICMD_LSUB , BUILTIN_lsub ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lsub"},
- {ICMD_LNEG , BUILTIN_lneg ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lneg"},
- {ICMD_LMUL , BUILTIN_lmul ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_LONG && SUPPORT_LONG_MUL,false,"lmul"},
-
- {ICMD_I2F , BUILTIN_i2f ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_FLOAT ,
- SUPPORT_FLOAT && SUPPORT_IFCVT,true ,"i2f"},
- {ICMD_I2D , BUILTIN_i2d ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_DOUBLE,
- SUPPORT_DOUBLE && SUPPORT_IFCVT,true ,"i2d"},
- {ICMD_L2F , BUILTIN_l2f ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_FLOAT ,
- SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT,true ,"l2f"},
- {ICMD_L2D , BUILTIN_l2d ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_DOUBLE,
- SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT,true ,"l2d"},
- {ICMD_F2L , BUILTIN_f2l ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"f2l"},
- {ICMD_D2L , BUILTIN_d2l ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,
- SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"d2l"},
- {ICMD_F2I , BUILTIN_f2i ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_INT ,
- 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"},
-
- { ICMD_FADD , BUILTIN_fadd , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fadd" },
- { ICMD_FSUB , BUILTIN_fsub , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fsub" },
- { ICMD_FMUL , BUILTIN_fmul , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fmul" },
- { ICMD_FDIV , BUILTIN_fdiv , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fdiv" },
- { ICMD_FNEG , BUILTIN_fneg , ICMD_BUILTIN1, TYPE_FLT, TYPE_VOID , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fneg" },
- { ICMD_FCMPL, BUILTIN_fcmpl , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_INT, SUPPORT_FLOAT, true, "fcmpl" },
- { ICMD_FCMPG, BUILTIN_fcmpg , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_INT, SUPPORT_FLOAT, true, "fcmpg" },
-
- { ICMD_DADD , BUILTIN_dadd , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "dadd" },
- { ICMD_DSUB , BUILTIN_dsub , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "dsub" },
- { ICMD_DMUL , BUILTIN_dmul , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "dmul" },
- { ICMD_DDIV , BUILTIN_ddiv , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "ddiv" },
- { ICMD_DNEG , BUILTIN_dneg , ICMD_BUILTIN1, TYPE_DBL, TYPE_VOID , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "dneg" },
- { ICMD_DCMPL, BUILTIN_dcmpl , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_INT, SUPPORT_DOUBLE, true, "dcmpl" },
- { ICMD_DCMPG, BUILTIN_dcmpg , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_INT, SUPPORT_DOUBLE, true, "dcmpg" },
-
- { ICMD_F2D, BUILTIN_f2d , ICMD_BUILTIN1, TYPE_FLT, TYPE_VOID , TYPE_VOID , TYPE_DBL, SUPPORT_FLOAT && SUPPORT_DOUBLE, true, "f2d" },
- { ICMD_D2F, BUILTIN_d2f , ICMD_BUILTIN1, TYPE_DBL, TYPE_VOID , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT && SUPPORT_DOUBLE, true, "d2f" },
-#endif
+ /* initialize codegen subsystem */
- /* this record marks the end of the automatically replaced opcodes */
- {255,NULL,0,0,0,0,0,0,0,"<INVALID>"},
+ codegen_init();
+}
- /* 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_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"},
- {255,BUILTIN_newarray_double ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_double"},
- {255,BUILTIN_newarray_byte ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_byte"},
- {255,BUILTIN_newarray_short ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_short"},
- {255,BUILTIN_newarray_int ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_int"},
- {255,BUILTIN_newarray_long ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_long"},
-#if defined(USE_THREADS)
- {255,BUILTIN_monitorenter ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_VOID ,0,0,"monitorenter"},
- {255,BUILTIN_monitorexit ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_VOID ,0,0,"monitorexit"},
-#endif
-#if !SUPPORT_DIVISION
- {255,BUILTIN_idiv ,ICMD_BUILTIN2,TYPE_INT ,TYPE_INT ,TYPE_VOID ,TYPE_INT ,0,0,"idiv"},
- {255,BUILTIN_irem ,ICMD_BUILTIN2,TYPE_INT ,TYPE_INT ,TYPE_VOID ,TYPE_INT ,0,0,"irem"},
-#endif
-#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
- {255,BUILTIN_ldiv ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,0,0,"ldiv"},
- {255,BUILTIN_lrem ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,0,0,"lrem"},
-#endif
- {255,BUILTIN_frem ,ICMD_BUILTIN2,TYPE_FLOAT ,TYPE_FLOAT ,TYPE_VOID ,TYPE_FLOAT ,0,0,"frem"},
- {255,BUILTIN_drem ,ICMD_BUILTIN2,TYPE_DOUBLE,TYPE_DOUBLE,TYPE_VOID ,TYPE_DOUBLE,0,0,"drem"},
+/* jit_close *******************************************************************
- /* this record marks the end of the list */
- { 0,NULL,0,0,0,0,0,0,0,"<END>"}
-};
+ Close the JIT subsystem.
+*******************************************************************************/
+
+void jit_close(void)
+{
+ /* do nothing */
+}
-/* include compiler subsystems ************************************************/
/* dummy function, used when there is no JavaVM code available */
-static functionptr do_nothing_function()
+static functionptr do_nothing_function(void)
{
return NULL;
}
t_inlining_globals *id;
s4 dumpsize;
+#if defined(STATISTICS)
if (opt_stat)
count_jit_calls++;
-
- /* this is the case if a native function is called by jni */
-
- if (m->flags & ACC_NATIVE)
- return (functionptr) m->stubroutine;
+#endif
#if defined(USE_THREADS)
/* enter a monitor on the method */
return m->entrypoint;
}
+#if defined(STATISTICS)
if (opt_stat)
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 */
if (getcompilingtime)
compilingtime_start();
+#endif
/* mark start of dump memory area */
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 */
dump_release(dumpsize);
+#if defined(STATISTICS)
/* measure time */
if (getcompilingtime)
compilingtime_stop();
+#endif
/* define in options.h; Used in main.c, jit.c & inline.c */
#ifdef INAFTERMAIN
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);
- if (!class_init(m->class))
+ if (!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 = (functionptr) do_nothing_function;
+
+ return m->entrypoint; /* return empty method */
}
/* initialisation of variables and subsystems */
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
/* initialise parameter type descriptor */
- descriptor2types(m);
+ method_descriptor2types(m);
/* call the compiler passes ***********************************************/
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 {
+#ifdef STATISTICS
+ if (opt_stat) count_methods_allocated_by_lsra++;
+#endif
+ /* log_message_method("Regalloc LSRA: ", m); */
+ }
+ }
+ else
+#endif /* LSRA */
+ {
+#ifdef STATISTICS
+ if (opt_stat)
#ifdef LSRA
- if (opt_lsra)
- lsra(m, cd, rd, ld, id);
- else
+ if (!opt_lsra)
+#endif
+ count_locals_conflicts += (cd->maxlocals-1)*(cd->maxlocals);
+#endif
+ regalloc(m, cd, rd);
+ }
+
+#ifdef STATISTICS
+ if (opt_stat)
+ reg_make_statistics(m, cd, rd);
#endif
- regalloc(m, cd, rd);
- 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 (compileverbose)
/* 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)
log_message_method("Compiling done: ", m);
+#ifdef LSRA
+ opt_lsra=old_opt_lsra;
+#endif
/* return pointer to the methods entry point */
return m->entrypoint;
}
-/* functions for compiler initialisation and finalisation *********************/
-
-#ifdef USEBUILTINTABLE
-
-static int stdopcompare(const void *a, const void *b)
-{
- builtin_descriptor *o1 = (builtin_descriptor *) a;
- builtin_descriptor *o2 = (builtin_descriptor *) 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);
-}
-
-static inline void sort_builtintable()
-{
- int len;
-
- len = 0;
- while (builtin_desc[len].opcode != 255) len++;
- qsort(builtin_desc, len, sizeof(builtin_descriptor), stdopcompare);
-
- for (--len; len>=0 && builtin_desc[len].supported; len--);
- builtintablelen = ++len;
-}
-
-
-builtin_descriptor *find_builtin(int icmd)
-{
- builtin_descriptor *first = builtin_desc;
- builtin_descriptor *last = builtin_desc + builtintablelen;
- int len = last - first;
- int half;
- builtin_descriptor *middle;
-
- while (len > 0) {
- half = len / 2;
- middle = first + half;
- if (middle->opcode < icmd) {
- first = middle + 1;
- len -= half + 1;
- } else
- len = half;
- }
- return first != last ? first : NULL;
-}
-
-#endif
-
-
-
-void jit_init()
-{
- s4 i;
-
-#ifdef 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