* Removed all Id tags.
[cacao.git] / src / vm / jit / jit.c
index 8760d2328ef60b95ad1b3df41c554a4e384c0f1c..b8d8cdc2e36c6080ff19684e74aff8934b453390 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/jit.c - calls the code generation functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-
-   Changes: Edwin Steiner
-            Christian Thalinger
-            Christian Ullrich
-
-   $Id: jit.c 5667 2006-10-04 15:14:19Z edwin $
-
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
 
+#include "vm/types.h"
+
 #include "mm/memory.h"
+
 #include "native/native.h"
+
 #include "toolbox/logging.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#else
-# include "threads/none/lock.h"
-#endif
+#include "threads/lock-common.h"
+#include "threads/threads-common.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/jit/asmpart.h"
 
 # include "vm/jit/cfg.h"
 #include "vm/jit/disass.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/md.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/reg.h"
 
-# include "vm/jit/reorder.h"
-
 #include "vm/jit/show.h"
 #include "vm/jit/stack.h"
 
 # include "vm/jit/optimizing/ssa.h"
 #endif
 
-
-#if defined(ENABLE_IFCONV)
-# include "vm/jit/ifconv/ifconv.h"
+#if defined(ENABLE_INLINING)
+# include "vm/jit/inline/inline.h"
 #endif
 
 #include "vm/jit/loop/analyze.h"
 #include "vm/jit/loop/graph.h"
 #include "vm/jit/loop/loop.h"
-#include "vm/jit/verify/typecheck.h"
-#include "vm/rt-timing.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
+#if defined(ENABLE_IFCONV)
+# include "vm/jit/optimizing/ifconv.h"
 #endif
 
+#include "vm/jit/optimizing/reorder.h"
+
+#include "vm/jit/verify/typecheck.h"
+
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+#include "vmcore/rt-timing.h"
+#include "vmcore/statistics.h"
+
 
 /* debug macros ***************************************************************/
 
 #endif
 
  
-/* global switches ************************************************************/
+/* the ICMD table ************************************************************/
+
+#if !defined(NDEBUG)
+#define N(name)  name,
+#else
+#define N(name)
+#endif
+
+/* abbreviations for flags */
+
+#define PEI     ICMDTABLE_PEI
+#define CALLS   ICMDTABLE_CALLS
+
+/* some machine dependent values */
+
+#if SUPPORT_DIVISION
+#define IDIV_CALLS  0
+#else
+#define IDIV_CALLS  ICMDTABLE_CALLS
+#endif
+
+#if (SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
+#define LDIV_CALLS  0
+#else
+#define LDIV_CALLS  ICMDTABLE_CALLS
+#endif
+
+/* include the actual table */
+
+icmdtable_entry_t icmd_table[256] = {
+#include <vm/jit/icmdtable.inc>
+};
+
+#undef N
+#undef PEI
+#undef CALLS
+
+/* XXX hack until the old "PEI" definition is removed */
+#define PEI 1
+
+
+/* stackelement requirements of Java opcodes **********************************/
 
 int stackreq[256] = {
        0,    /* JAVA_NOP                         0 */
@@ -206,12 +239,12 @@ int stackreq[256] = {
        0,    /* JAVA_POP                        87 */
        0,    /* JAVA_POP2                       88 */
        1,    /* JAVA_DUP                        89 */
-       3,    /* JAVA_DUP_X1                     90 */
-       4,    /* JAVA_DUP_X2                     91 */
+       1+3,  /* JAVA_DUP_X1                     90 */
+       2+4,  /* JAVA_DUP_X2                     91 */
        2,    /* JAVA_DUP2                       92 */
-       3,    /* JAVA_DUP2_X1                    93 */
-       4,    /* JAVA_DUP2_X2                    94 */
-       2,    /* JAVA_SWAP                       95 */
+       2+5,  /* JAVA_DUP2_X1                    93 */
+       3+6,  /* JAVA_DUP2_X2                    94 */
+       1+2,  /* JAVA_SWAP                       95 */
        1,    /* JAVA_IADD                       96 */
        1,    /* JAVA_LADD                       97 */
        1,    /* JAVA_FADD                       98 */
@@ -374,6 +407,8 @@ int stackreq[256] = {
        1,    /* JAVA_UNDEF255                  255 */
 };
 
+
+/* size in bytes of Java opcodes **********************************************/
                                 
 int jcommandsize[256] = {
 
@@ -621,263 +656,7 @@ int jcommandsize[256] = {
 };
 
 
-char *icmd_names[256] = {
-       "NOP            ", /*               0 */
-       "ACONST         ", /*               1 */
-       "CHECKNULL      ", /* ICONST_M1     2 */
-       "ICONST         ", /*               3 */
-       "CHECKNULL_POP  ", /* ICONST_1      4 */
-       "IDIVPOW2       ", /* ICONST_2      5 */
-       "LDIVPOW2       ", /* ICONST_3      6 */
-       "UNDEF7         ", /* ICONST_4      7 */
-       "UNDEF8         ", /* ICONST_5      8 */
-       "LCONST         ", /*               9 */
-       "LCMPCONST      ", /* LCONST_1     10 */
-       "FCONST         ", /*              11 */
-       "UNDEF12        ", /* FCONST_1     12 */
-       "UNDEF13        ", /* FCONST_2     13 */
-       "DCONST         ", /*              14 */
-       "COPY           ", /* DCONST_1     15 */
-       "MOVE           ", /* BIPUSH       16 */
-       "UNDEF17        ", /* SIPUSH       17 */
-       "UNDEF18        ", /* LDC1         18 */
-       "UNDEF19        ", /* LDC2         19 */
-       "UNDEF20        ", /* LDC2W        20 */
-       "ILOAD          ", /*              21 */
-       "LLOAD          ", /*              22 */
-       "FLOAD          ", /*              23 */
-       "DLOAD          ", /*              24 */
-       "ALOAD          ", /*              25 */
-       "IADDCONST      ", /* ILOAD_0      26 */
-       "ISUBCONST      ", /* ILOAD_1      27 */
-       "IMULCONST      ", /* ILOAD_2      28 */
-       "IANDCONST      ", /* ILOAD_3      29 */
-       "IORCONST       ", /* LLOAD_0      30 */
-       "IXORCONST      ", /* LLOAD_1      31 */
-       "ISHLCONST      ", /* LLOAD_2      32 */
-       "ISHRCONST      ", /* LLOAD_3      33 */
-       "IUSHRCONST     ", /* FLOAD_0      34 */
-       "IREMPOW2       ", /* FLOAD_1      35 */
-       "LADDCONST      ", /* FLOAD_2      36 */
-       "LSUBCONST      ", /* FLOAD_3      37 */
-       "LMULCONST      ", /* DLOAD_0      38 */
-       "LANDCONST      ", /* DLOAD_1      39 */
-       "LORCONST       ", /* DLOAD_2      40 */
-       "LXORCONST      ", /* DLOAD_3      41 */
-       "LSHLCONST      ", /* ALOAD_0      42 */
-       "LSHRCONST      ", /* ALOAD_1      43 */
-       "LUSHRCONST     ", /* ALOAD_2      44 */
-       "LREMPOW2       ", /* ALOAD_3      45 */
-       "IALOAD         ", /*              46 */
-       "LALOAD         ", /*              47 */
-       "FALOAD         ", /*              48 */
-       "DALOAD         ", /*              49 */
-       "AALOAD         ", /*              50 */
-       "BALOAD         ", /*              51 */
-       "CALOAD         ", /*              52 */
-       "SALOAD         ", /*              53 */
-       "ISTORE         ", /*              54 */
-       "LSTORE         ", /*              55 */
-       "FSTORE         ", /*              56 */
-       "DSTORE         ", /*              57 */
-       "ASTORE         ", /*              58 */
-       "IF_LEQ         ", /* ISTORE_0     59 */
-       "IF_LNE         ", /* ISTORE_1     60 */
-       "IF_LLT         ", /* ISTORE_2     61 */
-       "IF_LGE         ", /* ISTORE_3     62 */
-       "IF_LGT         ", /* LSTORE_0     63 */
-       "IF_LLE         ", /* LSTORE_1     64 */
-       "IF_LCMPEQ      ", /* LSTORE_2     65 */
-       "IF_LCMPNE      ", /* LSTORE_3     66 */
-       "IF_LCMPLT      ", /* FSTORE_0     67 */
-       "IF_LCMPGE      ", /* FSTORE_1     68 */
-       "IF_LCMPGT      ", /* FSTORE_2     69 */
-       "IF_LCMPLE      ", /* FSTORE_3     70 */
-       "UNDEF71        ", /* DSTORE_0     71 */
-       "UNDEF72        ", /* DSTORE_1     72 */
-       "UNDEF73        ", /* DSTORE_2     73 */
-       "UNDEF74        ", /* DSTORE_3     74 */
-       "UNDEF75        ", /* ASTORE_0     75 */
-       "UNDEF76        ", /* ASTORE_1     76 */
-       "UNDEF77        ", /* ASTORE_2     77 */
-       "UNDEF78        ", /* ASTORE_3     78 */
-       "IASTORE        ", /*              79 */
-       "LASTORE        ", /*              80 */
-       "FASTORE        ", /*              81 */
-       "DASTORE        ", /*              82 */
-       "AASTORE        ", /*              83 */
-       "BASTORE        ", /*              84 */
-       "CASTORE        ", /*              85 */
-       "SASTORE        ", /*              86 */
-       "POP            ", /*              87 */
-       "POP2           ", /*              88 */
-       "DUP            ", /*              89 */
-       "DUP_X1         ", /*              90 */
-       "DUP_X2         ", /*              91 */
-       "DUP2           ", /*              92 */
-       "DUP2_X1        ", /*              93 */
-       "DUP2_X2        ", /*              94 */
-       "SWAP           ", /*              95 */
-       "IADD           ", /*              96 */
-       "LADD           ", /*              97 */
-       "FADD           ", /*              98 */
-       "DADD           ", /*              99 */
-       "ISUB           ", /*             100 */
-       "LSUB           ", /*             101 */
-       "FSUB           ", /*             102 */
-       "DSUB           ", /*             103 */
-       "IMUL           ", /*             104 */
-       "LMUL           ", /*             105 */
-       "FMUL           ", /*             106 */
-       "DMUL           ", /*             107 */
-       "IDIV           ", /*             108 */
-       "LDIV           ", /*             109 */
-       "FDIV           ", /*             110 */
-       "DDIV           ", /*             111 */
-       "IREM           ", /*             112 */
-       "LREM           ", /*             113 */
-       "FREM           ", /*             114 */
-       "DREM           ", /*             115 */
-       "INEG           ", /*             116 */
-       "LNEG           ", /*             117 */
-       "FNEG           ", /*             118 */
-       "DNEG           ", /*             119 */
-       "ISHL           ", /*             120 */
-       "LSHL           ", /*             121 */
-       "ISHR           ", /*             122 */
-       "LSHR           ", /*             123 */
-       "IUSHR          ", /*             124 */
-       "LUSHR          ", /*             125 */
-       "IAND           ", /*             126 */
-       "LAND           ", /*             127 */
-       "IOR            ", /*             128 */
-       "LOR            ", /*             129 */
-       "IXOR           ", /*             130 */
-       "LXOR           ", /*             131 */
-       "IINC           ", /*             132 */
-       "I2L            ", /*             133 */
-       "I2F            ", /*             134 */
-       "I2D            ", /*             135 */
-       "L2I            ", /*             136 */
-       "L2F            ", /*             137 */
-       "L2D            ", /*             138 */
-       "F2I            ", /*             139 */
-       "F2L            ", /*             140 */
-       "F2D            ", /*             141 */
-       "D2I            ", /*             142 */
-       "D2L            ", /*             143 */
-       "D2F            ", /*             144 */
-       "INT2BYTE       ", /*             145 */
-       "INT2CHAR       ", /*             146 */
-       "INT2SHORT      ", /*             147 */
-       "LCMP           ", /*             148 */
-       "FCMPL          ", /*             149 */
-       "FCMPG          ", /*             150 */
-       "DCMPL          ", /*             151 */
-       "DCMPG          ", /*             152 */
-       "IFEQ           ", /*             153 */
-       "IFNE           ", /*             154 */
-       "IFLT           ", /*             155 */
-       "IFGE           ", /*             156 */
-       "IFGT           ", /*             157 */
-       "IFLE           ", /*             158 */
-       "IF_ICMPEQ      ", /*             159 */
-       "IF_ICMPNE      ", /*             160 */
-       "IF_ICMPLT      ", /*             161 */
-       "IF_ICMPGE      ", /*             162 */
-       "IF_ICMPGT      ", /*             163 */
-       "IF_ICMPLE      ", /*             164 */
-       "IF_ACMPEQ      ", /*             165 */
-       "IF_ACMPNE      ", /*             166 */
-       "GOTO           ", /*             167 */
-       "JSR            ", /*             168 */
-       "RET            ", /*             169 */
-       "TABLESWITCH    ", /*             170 */
-       "LOOKUPSWITCH   ", /*             171 */
-       "IRETURN        ", /*             172 */
-       "LRETURN        ", /*             173 */
-       "FRETURN        ", /*             174 */
-       "DRETURN        ", /*             175 */
-       "ARETURN        ", /*             176 */
-       "RETURN         ", /*             177 */
-       "GETSTATIC      ", /*             178 */
-       "PUTSTATIC      ", /*             179 */
-       "GETFIELD       ", /*             180 */
-       "PUTFIELD       ", /*             181 */
-       "INVOKEVIRTUAL  ", /*             182 */
-       "INVOKESPECIAL  ", /*             183 */
-       "INVOKESTATIC   ", /*             184 */
-       "INVOKEINTERFACE", /*             185 */
-       "UNDEF186       ", /* UNDEF186    186 */
-       "NEW            ", /*             187 */
-       "NEWARRAY       ", /*             188 */
-       "ANEWARRAY      ", /*             189 */
-       "ARRAYLENGTH    ", /*             190 */
-       "ATHROW         ", /*             191 */
-       "CHECKCAST      ", /*             192 */
-       "INSTANCEOF     ", /*             193 */
-       "MONITORENTER   ", /*             194 */
-       "MONITOREXIT    ", /*             195 */
-       "UNDEF196       ", /* WIDE        196 */
-       "MULTIANEWARRAY ", /*             197 */
-       "IFNULL         ", /*             198 */
-       "IFNONNULL      ", /*             199 */
-       "UNDEF200       ", /* GOTO_W      200 */
-       "UNDEF201       ", /* JSR_W       201 */
-       "UNDEF202       ", /* BREAKPOINT  202 */
-       "UNDEF203       ", /* UNDEF203    203 */
-       "IASTORECONST   ", /*             204 */
-       "LASTORECONST   ", /*             205 */
-       "FASTORECONST   ", /*             206 */
-       "DASTORECONST   ", /*             207 */
-       "AASTORECONST   ", /*             208 */
-       "BASTORECONST   ", /*             209 */
-       "CASTORECONST   ", /*             210 */
-       "SASTORECONST   ", /*             211 */
-       "PUTSTATICCONST ", /*             212 */
-       "PUTFIELDCONST  ", /*             213 */
-       "IMULPOW2       ", /*             214 */
-       "LMULPOW2       ", /*             215 */
-
-       "IF_FCMPEQ      ", /*             216 */
-       "IF_FCMPNE      ", /*             217 */
-
-       "IF_FCMPL_LT    ", /*             218 */
-       "IF_FCMPL_GE    ", /*             219 */
-       "IF_FCMPL_GT    ", /*             220 */
-       "IF_FCMPL_LE    ", /*             221 */
-
-       "IF_FCMPG_LT    ", /*             222 */
-       "IF_FCMPG_GE    ", /*             223 */
-       "IF_FCMPG_GT    ", /*             224 */
-       "IF_FCMPG_LE    ", /*             225 */
-
-       "IF_DCMPEQ      ", /*             226 */
-       "IF_DCMPNE      ", /*             227 */
-
-       "IF_DCMPL_LT    ", /*             228 */
-       "IF_DCMPL_GE    ", /*             229 */
-       "IF_DCMPL_GT    ", /*             230 */
-       "IF_DCMPL_LE    ", /*             231 */
-       
-       "IF_DCMPG_LT    ", /*             232 */
-       "IF_DCMPG_GE    ", /*             233 */
-       "IF_DCMPG_GT    ", /*             234 */
-       "IF_DCMPG_LE    ", /*             235 */
-       
-       "UNDEF236", "UNDEF237", "UNDEF238", "UNDEF239", "UNDEF240",
-       "UNDEF241", "UNDEF242", "UNDEF243", "UNDEF244", "UNDEF245",
-       "UNDEF246", "UNDEF247", "UNDEF248", "UNDEF249", "UNDEF250",
-
-       "INLINE_START   ", /*             251 */
-       "INLINE_END     ", /*             252 */
-       "INLINE_GOTO    ", /*             253 */
-
-       "UNDEF254",
-
-       "BUILTIN        "  /*             255 */
-};
-
+/* Java opcode names *********************************************************/
 
 char *opcode_names[256] = {
        "NOP            ", /*               0 */
@@ -1097,9 +876,6 @@ char *opcode_names[256] = {
        "UNDEF251", "UNDEF252", "UNDEF253", "UNDEF254", "UNDEF255"
 };
 
-int op_data[256][OP_DATA_SIZE];
-/* int op_needs_saved[256]; */
-/* int op_is_pei[256]; */
 
 /* jit_init ********************************************************************
 
@@ -1109,86 +885,11 @@ int op_data[256][OP_DATA_SIZE];
 
 void jit_init(void)
 {
-       s4 i;
-
-       for( i = 0; i < 256; i++) {
-               op_data[i][NEEDS_SAVED] = 0;
-               op_data[i][PEI] = 0;
-       }
-
-       op_data[ICMD_AASTORE  ][NEEDS_SAVED] = 1;
-#if !SUPPORT_DIVISION
-       op_data[ICMD_IDIV     ][NEEDS_SAVED] = 1;
-       op_data[ICMD_IREM     ][NEEDS_SAVED] = 1;
-#endif
-#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
-       op_data[ICMD_LDIV     ][NEEDS_SAVED] = 1;
-       op_data[ICMD_LREM     ][NEEDS_SAVED] = 1;
-#endif
-       op_data[ICMD_CHECKCAST][NEEDS_SAVED] = 1;
-
-       op_data[ICMD_BUILTIN        ][NEEDS_SAVED] = 1;
-       op_data[ICMD_INVOKESTATIC   ][NEEDS_SAVED] = 1;
-       op_data[ICMD_INVOKESPECIAL  ][NEEDS_SAVED] = 1;
-       op_data[ICMD_INVOKEVIRTUAL  ][NEEDS_SAVED] = 1;
-       op_data[ICMD_INVOKEINTERFACE][NEEDS_SAVED] = 1;
-       op_data[ICMD_MULTIANEWARRAY ][NEEDS_SAVED] = 1;
-
-       op_data[ICMD_ACONST][PEI] = 1; /* OutOfMemoryError */
-       op_data[ICMD_NEWARRAY][PEI] = 1; /* NegativeArraySizeException,OutOfMemoryError */
-       op_data[ICMD_ANEWARRAY][PEI] = 1; /* NegativeArraySizeException,OutOfMemoryError */
-       op_data[ICMD_MULTIANEWARRAY][PEI] = 1; /* NegativeArraySizeException,OutOfMemoryError */
-       op_data[ICMD_ARRAYLENGTH][PEI] = 1; /* NullPointerException */
-       op_data[ICMD_IALOAD][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_LALOAD][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_FALOAD][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_DALOAD][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_AALOAD][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_BALOAD][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_CALOAD][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_SALOAD][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_IASTORE][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_LASTORE][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_FASTORE][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_DASTORE][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_AASTORE][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       /* ArrayStoreException */
-       op_data[ICMD_BASTORE][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_CASTORE][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-       op_data[ICMD_SASTORE][PEI] = 1; /* NullPointerException, ArrayIndexOutOfBoundsException */
-
-       op_data[ICMD_IDIV][PEI] = 1; /* "/ by Zero" ArithmeticException */
-       op_data[ICMD_LDIV][PEI] = 1; /* "/ by Zero" ArithmeticException */
-       op_data[ICMD_IREM][PEI] = 1; /* "/ by Zero" ArithmeticException */
-       op_data[ICMD_LREM][PEI] = 1; /* "/ by Zero" ArithmeticException */
-
-       op_data[ICMD_PUTFIELD][PEI] = 1; /* NullPointerException, IncompatibleClassChangeError */
-       op_data[ICMD_GETFIELD][PEI] = 1; /* NullPointerException, IncompatibleClassChangeError */
-#if 0
-       op_data[ICMD_PUTFIELDCONST][PEI] = 1; /*NullPointerException, IncompatibleClassChangeError */
-       op_data[ICMD_GETFIELDCONST][PEI] = 1; /*NullPointerException, IncompatibleClassChangeError */
-#endif
-       op_data[ICMD_PUTSTATIC][PEI] = 1; /* IncompatibleClassChangeError */
-       op_data[ICMD_GETSTATIC][PEI] = 1; /* IncompatibleClassChangeError */
-
-       op_data[ICMD_BUILTIN][PEI] = 1; /* ?NullPointerException, StackOverflowError,? * */
-       op_data[ICMD_INVOKEVIRTUAL][PEI] = 1; /* NullPointerException, StackOverflowError, * */
-       op_data[ICMD_INVOKESPECIAL][PEI] = 1; /* NullPointerException, StackOverflowError, * */
-       op_data[ICMD_INVOKESTATIC][PEI] = 1; /* StackOverflowError, * */
-       op_data[ICMD_INVOKEINTERFACE][PEI] = 1; /* NullPointerException, StackOverflowError, * */
-
-       op_data[ICMD_ATHROW][PEI] = 1; /* NullPointerException, * */
-
-       op_data[ICMD_CHECKCAST][PEI] = 1; /* ClassCastException */
-
-       op_data[ICMD_MONITORENTER][PEI] = 1; /* NullPointerException */
-       op_data[ICMD_MONITOREXIT][PEI] = 1; /* NullPointerException */
-
-       op_data[ICMD_CHECKNULL][PEI] = 1; /* NullPointerException */
-
+#if defined(ENABLE_JIT)
        /* initialize stack analysis subsystem */
 
        (void) stack_init();
+#endif
 
        /* initialize show subsystem */
 
@@ -1199,6 +900,10 @@ void jit_init(void)
        /* initialize codegen subsystem */
 
        codegen_init();
+
+       /* initialize code subsystem */
+
+       (void) code_init();
 }
 
 
@@ -1228,7 +933,7 @@ static u1 *do_nothing_function(void)
 
 *******************************************************************************/
 
-static jitdata *jit_jitdata_new(methodinfo *m)
+jitdata *jit_jitdata_new(methodinfo *m)
 {
        jitdata *jd;
 
@@ -1249,8 +954,22 @@ static jitdata *jit_jitdata_new(methodinfo *m)
 
        /* initialize variables */
 
-       jd->flags        = 0;
-       jd->isleafmethod = true;
+       jd->flags                = 0;
+       jd->exceptiontable       = NULL;
+       jd->exceptiontablelength = 0;
+       jd->returncount          = 0;
+       jd->branchtoentry        = false;
+       jd->branchtoend          = false;
+       jd->returncount          = 0;
+       jd->returnblock          = NULL;
+       jd->maxlocals            = m->maxlocals;
+
+#if defined(ENABLE_THREADS)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               jd->isleafmethod = false;
+       else
+#endif
+               jd->isleafmethod = true;
 
        return jd;
 }
@@ -1332,14 +1051,21 @@ u1 *jit_compile(methodinfo *m)
                jd->flags |= JITDATA_FLAG_VERIFY;
 #endif
 
+#if defined(ENABLE_PROFILING)
        if (opt_prof)
                jd->flags |= JITDATA_FLAG_INSTRUMENT;
+#endif
 
 #if defined(ENABLE_IFCONV)
        if (opt_ifconv)
                jd->flags |= JITDATA_FLAG_IFCONV;
 #endif
 
+#if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
+       if (opt_inlining && opt_inline_debug_all)
+               jd->flags |= JITDATA_FLAG_INLINE;
+#endif
+
        if (opt_showintermediate)
                jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
 
@@ -1349,6 +1075,11 @@ u1 *jit_compile(methodinfo *m)
        if (opt_verbosecall)
                jd->flags |= JITDATA_FLAG_VERBOSECALL;
 
+#if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
+       if (opt_inlining)
+               jd->flags |= JITDATA_FLAG_COUNTDOWN;
+#endif
+
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (!opt_intrp)
@@ -1374,11 +1105,13 @@ u1 *jit_compile(methodinfo *m)
 
                code_codeinfo_free(jd->code);
 
+#if defined(ENABLE_PROFILING)
                /* Release memory for basic block profiling information. */
 
                if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
                        if (jd->code->bbfrequency != NULL)
                                MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
+#endif
        }
        else {
                DEBUG_JIT_COMPILEVERBOSE("Running: ");
@@ -1420,14 +1153,16 @@ u1 *jit_recompile(methodinfo *m)
 
        /* check for max. optimization level */
 
-       optlevel = m->code->optlevel;
+       optlevel = (m->code) ? m->code->optlevel : 0;
 
+#if 0
        if (optlevel == 1) {
 /*             log_message_method("not recompiling: ", m); */
                return NULL;
        }
+#endif
 
-       log_message_method("Recompiling start: ", m);
+       DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
 
        STATISTICS(count_jit_calls++);
 
@@ -1452,10 +1187,22 @@ u1 *jit_recompile(methodinfo *m)
 
        /* get the optimization flags for the current JIT run */
 
-       jd->flags |= JITDATA_FLAG_REORDER;
-       jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
-       jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
-/*     jd->flags |= JITDATA_FLAG_VERBOSECALL; */
+#if defined(ENABLE_VERIFIER)
+       jd->flags |= JITDATA_FLAG_VERIFY;
+#endif
+
+       /* jd->flags |= JITDATA_FLAG_REORDER; */
+       if (opt_showintermediate)
+               jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
+       if (opt_showdisassemble)
+               jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
+       if (opt_verbosecall)
+               jd->flags |= JITDATA_FLAG_VERBOSECALL;
+
+#if defined(ENABLE_INLINING)
+       if (opt_inlining)
+               jd->flags |= JITDATA_FLAG_INLINE;
+#endif
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
@@ -1493,7 +1240,7 @@ u1 *jit_recompile(methodinfo *m)
                compilingtime_stop();
 #endif
 
-       log_message_method("Recompiling done: ", m);
+       DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
 
        /* return pointer to the methods entry point */
 
@@ -1516,7 +1263,7 @@ static u1 *jit_compile_intern(jitdata *jd)
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start,time_checks,time_parse,time_stack,
                                        time_typecheck,time_loop,time_ifconv,time_alloc,
-                                       time_rplpoints,time_codegen;
+                                       time_codegen;
 #endif
        
        RT_TIMING_GET_TIME(time_start);
@@ -1534,6 +1281,10 @@ static u1 *jit_compile_intern(jitdata *jd)
 
        DEBUG_JIT_COMPILEVERBOSE("Compiling: ");
 
+#if defined(ENABLE_DEBUG_FILTER)
+       show_filters_apply(jd->m);
+#endif
+
        /* handle native methods and create a native stub */
 
        if (m->flags & ACC_NATIVE) {
@@ -1548,7 +1299,7 @@ static u1 *jit_compile_intern(jitdata *jd)
                f = NULL;
 #endif
 
-               code = codegen_createnativestub(f, m);
+               code = codegen_generate_stub_native(m, f);
 
                assert(!m->code); /* native methods are never recompiled */
                m->code = code;
@@ -1569,9 +1320,9 @@ static u1 *jit_compile_intern(jitdata *jd)
 
 #if defined(ENABLE_STATISTICS)
        if (opt_stat) {
-               count_tryblocks    += m->exceptiontablelength;
                count_javacodesize += m->jcodelength + 18;
-               count_javaexcsize  += m->exceptiontablelength * SIZEOF_VOID_P;
+               count_tryblocks    += jd->exceptiontablelength;
+               count_javaexcsize  += jd->exceptiontablelength * SIZEOF_VOID_P;
        }
 #endif
 
@@ -1616,7 +1367,7 @@ static u1 *jit_compile_intern(jitdata *jd)
                        return NULL;
 
 #ifdef ENABLE_VERIFIER
-               if (jd->flags & JITDATA_FLAG_VERIFY) {
+               if (JITDATA_HAS_FLAG_VERIFY(jd)) {
                        DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
 
                        /* call typecheck pass */
@@ -1636,24 +1387,40 @@ static u1 *jit_compile_intern(jitdata *jd)
                        depthFirst(jd);
                        analyseGraph(jd);
                        optimize_loops(jd);
+                       jit_renumber_basicblocks(jd);
                }
 #endif
                RT_TIMING_GET_TIME(time_loop);
 
 #if defined(ENABLE_IFCONV)
-               if (JITDATA_HAS_FLAG_IFCONV(jd))
+               if (JITDATA_HAS_FLAG_IFCONV(jd)) {
                        if (!ifconv_static(jd))
                                return NULL;
+                       jit_renumber_basicblocks(jd);
+               }
 #endif
                RT_TIMING_GET_TIME(time_ifconv);
 
+               /* inlining */
+
+#if defined(ENABLE_INLINING)
+               if (JITDATA_HAS_FLAG_INLINE(jd)) {
+                       if (!inline_inline(jd))
+                               return NULL;
+               }
+#endif
+
+#if defined(ENABLE_PROFILING)
                /* Basic block reordering.  I think this should be done after
                   if-conversion, as we could lose the ability to do the
                   if-conversion. */
 
-               if (JITDATA_HAS_FLAG_REORDER(jd))
+               if (JITDATA_HAS_FLAG_REORDER(jd)) {
                        if (!reorder(jd))
                                return NULL;
+                       jit_renumber_basicblocks(jd);
+               }
+#endif
 
                DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
 
@@ -1669,7 +1436,7 @@ static u1 *jit_compile_intern(jitdata *jd)
 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
 #if defined(ENABLE_SSA)
                /* allocate registers */
-               if ((opt_lsra) && (cd->exceptiontablelength == 0)) {
+               if ((opt_lsra) && (jd->exceptiontablelength == 0)) {
                        jd->ls = DNEW(lsradata);
                        lsra(jd);
 
@@ -1678,12 +1445,12 @@ static u1 *jit_compile_intern(jitdata *jd)
                } else
 # endif /* defined(ENABLE_SSA) */
                {
-                       STATISTICS(count_locals_conflicts += (cd->maxlocals - 1) * (cd->maxlocals));
+                       STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
 
                        regalloc(jd);
                }
 
-               STATISTICS(reg_make_statistics(jd));
+               STATISTICS(simplereg_make_statistics(jd));
 
                DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
 # if defined(ENABLE_INTRP)
@@ -1692,27 +1459,32 @@ static u1 *jit_compile_intern(jitdata *jd)
 #endif /* defined(ENABLE_JIT) */
        RT_TIMING_GET_TIME(time_alloc);
 
+#if defined(ENABLE_PROFILING)
        /* Allocate memory for basic block profiling information. This
           _must_ be done after loop optimization and register allocation,
           since they can change the basic block count. */
 
        if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
                code->bbfrequency = MNEW(u4, jd->basicblockcount);
+#endif
 
        DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
 
-       /* create the replacement points */
-#if 0
-       if (!replace_create_replacement_points(jd))
-               return NULL;
-#endif
-       RT_TIMING_GET_TIME(time_rplpoints);
-
        /* now generate the machine code */
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (opt_intrp) {
+#if defined(ENABLE_VERIFIER)
+               if (opt_verify) {
+                       DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
+
+                       if (!typecheck_stackbased(jd)) {
+                               DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
+                               return NULL;
+                       }
+               }
+#endif
                if (!intrp_codegen(jd)) {
                        DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
 
@@ -1721,7 +1493,7 @@ static u1 *jit_compile_intern(jitdata *jd)
        } else
 # endif
                {
-                       if (!codegen(jd)) {
+                       if (!codegen_generate(jd)) {
                                DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
 
                                return NULL;
@@ -1739,20 +1511,25 @@ static u1 *jit_compile_intern(jitdata *jd)
        DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
 
 #if !defined(NDEBUG)
-       /* intermediate and assembly code listings */
+#if defined(ENABLE_DEBUG_FILTER)
+       if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
+#endif
+       {
+               /* intermediate and assembly code listings */
                
-       if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
-               show_method(jd, SHOW_CODE);
-       }
-       else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
+               if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
+                       show_method(jd, SHOW_CODE);
+               }
+               else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
 # if defined(ENABLE_DISASSEMBLER)
-               DISASSEMBLE(code->entrypoint,
-                                       code->entrypoint + (code->mcodelength - cd->dseglen));
+                       DISASSEMBLE(code->entrypoint,
+                                               code->entrypoint + (code->mcodelength - cd->dseglen));
 # endif
-       }
+               }
 
-       if (opt_showddatasegment)
-               dseg_display(jd);
+               if (opt_showddatasegment)
+                       dseg_display(jd);
+       }
 #endif
 
        DEBUG_JIT_COMPILEVERBOSE("Compiling done: ");
@@ -1773,8 +1550,7 @@ static u1 *jit_compile_intern(jitdata *jd)
        RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
        RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
        RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
-       RT_TIMING_TIME_DIFF(time_alloc,time_rplpoints,RT_TIMING_JIT_RPLPOINTS);
-       RT_TIMING_TIME_DIFF(time_rplpoints,time_codegen,RT_TIMING_JIT_CODEGEN);
+       RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
        RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
 
        /* return pointer to the methods entry point */
@@ -1783,6 +1559,92 @@ static u1 *jit_compile_intern(jitdata *jd)
 } 
 
 
+/* jit_invalidate_code *********************************************************
+
+   Mark the compiled code of the given method as invalid and take care that
+   it is replaced if necessary.
+
+   XXX Not fully implemented, yet.
+
+*******************************************************************************/
+
+void jit_invalidate_code(methodinfo *m)
+{
+       codeinfo *code;
+
+       code = m->code;
+       if (code == NULL || CODE_IS_INVALID(code))
+               return;
+
+       CODE_SETFLAG_INVALID(code);
+
+       /* activate mappable replacement points */
+
+#if defined(ENABLE_REPLACEMENT)
+       replace_activate_replacement_points(code, true);
+#else
+       vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
+#endif
+}
+
+
+/* jit_request_optimization ****************************************************
+
+   Request optimization of the given method. If the code of the method is
+   unoptimized, it will be invalidated, so the next jit_get_current_code(m)
+   triggers an optimized recompilation.
+   If the method is already optimized, this function does nothing.
+
+   IN:
+       m................the method
+
+*******************************************************************************/
+
+void jit_request_optimization(methodinfo *m)
+{
+       codeinfo *code;
+
+       code = m->code;
+
+       if (code && code->optlevel == 0)
+               jit_invalidate_code(m);
+}
+
+
+/* jit_get_current_code ********************************************************
+
+   Get the currently valid code for the given method. If there is no valid
+   code, (re)compile the method.
+
+   IN:
+       m................the method
+
+   RETURN VALUE:
+       the codeinfo* for the current code, or
+          NULL if an exception has been thrown during recompilation.
+
+*******************************************************************************/
+
+codeinfo *jit_get_current_code(methodinfo *m)
+{
+       assert(m);
+
+       /* if we have valid code, return it */
+
+       if (m->code && CODE_IS_VALID(m->code))
+               return m->code;
+
+       /* otherwise: recompile */
+
+       if (!jit_recompile(m))
+               return NULL;
+
+       assert(m->code);
+
+       return m->code;
+}
+
+
 /* jit_asm_compile *************************************************************
 
    This method is called from asm_vm_call_method and does:
@@ -1795,6 +1657,7 @@ static u1 *jit_compile_intern(jitdata *jd)
 
 *******************************************************************************/
 
+#if defined(ENABLE_JIT)
 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
 {
        stackframeinfo  sfi;
@@ -1802,9 +1665,10 @@ u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
        u1             *pa;
        ptrint         *p;
 
-       /* create the stackframeinfo (XPC is equal to RA) */
+       /* create the stackframeinfo (subtract 1 from RA as it points to the */
+       /* instruction after the call)                                       */
 
-       stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
+       stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra-1);
 
        /* actually compile the method */
 
@@ -1835,6 +1699,7 @@ u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
 
        return entrypoint;
 }
+#endif /* defined(ENABLE_JIT) */
 
 
 /* jit_complement_condition ****************************************************
@@ -1876,6 +1741,64 @@ s4 jit_complement_condition(s4 opcode)
 }
 
 
+/* jit_renumber_basicblocks ****************************************************
+
+   Set the ->nr of all blocks so it increases when traversing ->next.
+
+   IN:
+       jitdata..........the current jitdata
+
+*******************************************************************************/
+
+void jit_renumber_basicblocks(jitdata *jd)
+{
+       s4          nr;
+       basicblock *bptr;
+
+       nr = 0;
+       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
+               bptr->nr = nr++;
+       }
+
+       /* we have one block more than jd->basicblockcount (the end marker) */
+
+       assert(nr == jd->basicblockcount + 1);
+}
+
+
+/* jit_check_basicblock_numbers ************************************************
+
+   Assert that the ->nr of the first block is zero and increases by 1 each
+   time ->next is traversed.
+   This function should be called before any analysis that relies on
+   the basicblock numbers.
+
+   IN:
+       jitdata..........the current jitdata
+
+   NOTE: Aborts with an assertion if the condition is not met!
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void jit_check_basicblock_numbers(jitdata *jd)
+{
+       s4          nr;
+       basicblock *bptr;
+
+       nr = 0;
+       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
+               assert(bptr->nr == nr);
+               nr++;
+       }
+
+       /* we have one block more than jd->basicblockcount (the end marker) */
+
+       assert(nr == jd->basicblockcount + 1);
+}
+#endif /* !defined(NDEBUG) */
+
+
 /*
  * 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