/* jit/jit.h - code generation header
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
- M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
- P. Tomsich, J. Wenninger
+ Copyright (C) 1996-2005 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
This file is part of CACAO.
Changes: Christian Thalinger
- $Id: jit.h 557 2003-11-02 22:51:59Z twisti $
+ $Id: jit.h 1735 2004-12-07 14:33:27Z twisti $
*/
#ifndef _JIT_H
#define _JIT_H
-#include "global.h"
-#include "toolbox/chain.h"
-
-
-/**************************** resolve typedef-cycles **************************/
+/* resolve typedef cycles *****************************************************/
typedef struct stackelement stackelement;
typedef stackelement *stackptr;
typedef struct basicblock basicblock;
typedef struct instruction instruction;
typedef struct subroutineinfo subroutineinfo;
-typedef struct varinfo varinfo;
-typedef struct branchref branchref;
-typedef struct jumpref jumpref;
-typedef struct dataref dataref;
-typedef varinfo *varinfoptr;
+#include "toolbox/chain.h"
+#include "vm/global.h"
+#include "vm/builtin.h"
+#include "vm/jit/codegen.inc.h"
+#include "vm/jit/verify/typeinfo.h"
+
+
+/**************************** resolve typedef-cycles **************************/
+
/************************** stack element structure ***************************/
/* slot types */
-#define TYPE_INT 0 /* the stack slot types must numbered in the */
-#define TYPE_LNG 1 /* same order as the ICMD_Ixxx to ICMD_Axxx */
-#define TYPE_FLT 2 /* instructions (LOAD and STORE) */
-#define TYPE_DBL 3 /* integer, long, float, double, address */
-#define TYPE_ADR 4
+/* Unified these with longer names. Maybe someday use only
+ * one set of names? -Edwin
+ */
+/*#define TYPE_INT 0*/ /* the stack slot types must numbered in the */
+#define TYPE_LNG TYPE_LONG /*1*/ /* same order as the ICMD_Ixxx to ICMD_Axxx */
+#define TYPE_FLT TYPE_FLOAT /*2*/ /* instructions (LOAD and STORE) */
+#define TYPE_DBL TYPE_DOUBLE /*3*/ /* integer, long, float, double, address */
+#define TYPE_ADR TYPE_ADDRESS /*4*/
#define IS_INT_LNG_TYPE(a) (!((a)&TYPE_FLT))
#define IS_FLT_DBL_TYPE(a) ((a)&TYPE_FLT)
struct stackelement {
stackptr prev; /* pointer to next element towards bottom */
- int type; /* slot type of stack element */
- int flags; /* flags (SAVED, INMEMORY) */
- int varkind; /* kind of variable or register */
- int varnum; /* number of variable */
- int regoff; /* register number or memory offset */
+ s4 type; /* slot type of stack element */
+#ifdef CACAO_TYPECHECK
+ typeinfo typeinfo; /* info on reference types */
+#endif
+ s4 flags; /* flags (SAVED, INMEMORY) */
+ s4 varkind; /* kind of variable or register */
+ s4 varnum; /* number of variable */
+ s4 regoff; /* register number or memory offset */
};
/**************************** instruction structure ***************************/
struct instruction {
- stackptr dst; /* stack index of destination operand stack */
- u2 opc; /* opcode of intermediate code command */
- s4 op1; /* first operand, usually variable number */
-
- union {
- s4 i; /* integer operand */
- s8 l; /* long operand */
- float f; /* float operand */
- double d; /* double operand */
- void *a; /* address operand */
- } val; /* immediate constant */
-
- void *target; /* used for targets of branches and jumps */
- /* and as address for list of targets for */
- /* statements */
+ stackptr dst; /* stack index of destination operand stack */
+ u2 opc; /* opcode of intermediate code command */
+ s4 op1; /* first operand, usually variable number */
+ imm_union val; /* immediate constant */
+ void *target; /* used for targets of branches and jumps */
+ /* and as address for list of targets for */
+ /* statements */
+ u2 line; /* line number in source file */
+ methodinfo *method; /* needed for inlining. can't be done on */
+ /* basic block level, since an inlined */
+ /* function doesn't necessarily start */
+ /* a new block */
};
#define BBUNDEF -1
#define BBREACHED 0
#define BBFINISHED 1
+#define BBTYPECHECK_UNDEF 2
+#define BBTYPECHECK_REACHED 3
#define BBTYPE_STD 0 /* standard basic block type */
#define BBTYPE_EXH 1 /* exception handler basic block type */
#define BBTYPE_SBR 2 /* subroutine basic block type */
-struct basicblock {
+
+struct basicblock {
int flags; /* used during stack analysis, init with -1 */
int type; /* basic block type (std, xhandler, subroutine*/
instruction *iinstr; /* pointer to intermediate code instructions */
int indepth; /* stack depth at begin of basic block */
int outdepth; /* stack depth end of basic block */
int pre_count; /* count of predecessor basic blocks */
- branchref *branchrefs; /* list of branches to be patched */
+ struct branchref *branchrefs; /* list of branches to be patched */
basicblock *next; /* used to build a BB list (instead of array) */
int lflags; /* used during loop copying, init with 0 */
};
-/************************* pseudo variable structure **************************/
-
-struct varinfo {
- int type; /* basic type of variable */
- int flags; /* flags (SAVED, INMEMORY) */
- int regoff; /* register number or memory offset */
-};
-
-typedef varinfo varinfo5[5];
-
-
-/***************** forward references in branch instructions ******************/
-
-struct branchref {
- s4 branchpos; /* patching position in code segment */
- branchref *next; /* next element in branchref list */
-};
-
-
-/******************** forward references in tables ***************************/
-
-struct jumpref {
- s4 tablepos; /* patching position in data segment */
- basicblock *target; /* target basic block */
- jumpref *next; /* next element in jumpref list */
-};
-
-
-struct dataref {
- u1 *pos; /* patching position in generated code */
- dataref *next; /* next element in dataref list */
-};
+/********** op1 values for ACONST instructions ********************************/
+#define ACONST_LOAD 0 /* ACONST_NULL or LDC instruction */
+#define ACONST_BUILTIN 1 /* constant argument for a builtin function call */
/********** JavaVM operation codes (sorted) and instruction lengths ***********/
#define ICMD_ICONST 3 /* val.i = constant */
#define JAVA_ICONST_1 4
-#define ICMD_IREM0X10001 4
#define JAVA_ICONST_2 5
#define ICMD_IDIVPOW2 5 /* val.i = constant */
#define JAVA_ICONST_4 7
#define JAVA_ICONST_5 8
-#define ICMD_LREM0X10001 8
#define JAVA_LCONST_0 9
#define ICMD_LCONST 9 /* val.l = constant */
#define JAVA_BREAKPOINT 202
+#define ICMD_CHECKEXCEPTION 203 /* check for an exception */
+
+#define ICMD_IASTORECONST 204
+
+#define ICMD_LASTORECONST 205
+
+#define ICMD_FASTORECONST 206
+
+#define ICMD_DASTORECONST 207
+
+#define ICMD_AASTORECONST 208
+#define ICMD_BASTORECONST 209
+
+#define ICMD_CASTORECONST 210
+
+#define ICMD_SASTORECONST 211
+
+#define ICMD_INLINE_START 251 /* before the first instruction of an inlined method */
+#define ICMD_INLINE_END 252 /* after the last instruction of an inlined method */
#define ICMD_BUILTIN3 253 /* internal opcode */
#define ICMD_BUILTIN2 254 /* internal opcode */
#define ICMD_BUILTIN1 255 /* internal opcode */
/******************* description of JavaVM instructions ***********************/
#if defined(USEBUILTINTABLE)
-typedef struct {
- u1 opcode;
- u1 type_s1;
- u1 type_s2;
- u1 type_d;
- int icmd;
- functionptr builtin;
- bool supported;
- bool isfloat;
-} stdopdescriptor;
-
-static 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_MULDIV, false },
- { ICMD_FREM, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, ICMD_BUILTIN2,
- (functionptr) builtin_frem, SUPPORT_FLOAT && SUPPORT_FMOD, true },
- { ICMD_DREM, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE, ICMD_BUILTIN2,
- (functionptr) builtin_drem, SUPPORT_DOUBLE && SUPPORT_FMOD, true },
- { 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_FCVT, true },
- { ICMD_D2L, TYPE_DOUBLE, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1,
- (functionptr) builtin_d2l, SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_FCVT, 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 },
-};
+
+builtin_descriptor *find_builtin(int opcode);
#endif /* USEBUILTINTABLE */
/***************************** register info block ****************************/
-extern int nregdescint[]; /* description of integer registers */
-extern int nregdescfloat[]; /* description of floating point registers */
-
-extern int nreg_parammode;
-
-
-/* compiler switches (set by main function) ***********************************/
-
-extern bool runverbose; /* trace all method invocation */
-extern bool compileverbose; /* trace compiler actions */
-extern bool showdisassemble; /* generate disassembler listing */
-extern bool showddatasegment; /* generate data segment listing */
-extern bool showintermediate; /* generate intermediate code listing */
-extern int optimizelevel; /* optimzation level (0 = no optimization) */
-
-extern bool useinlining; /* use method inlining */
-extern bool inlinevirtuals; /* inline unique virtual methods */
-extern bool inlineexceptions; /* inline methods, that contain excptions */
-extern bool inlineparamopt; /* optimize parameter passing to inlined methods */
-extern bool inlineoutsiders; /* inline methods, that are not member of the invoker's class */
-
-
-extern bool checkbounds; /* check array bounds */
-extern bool opt_loops; /* optimize array accesses in loops */
-extern bool checknull; /* check null pointers */
-extern bool opt_noieee; /* don't implement ieee compliant floats */
-extern bool checksync; /* do synchronization */
-
-extern bool getcompilingtime; /* compute compile time */
-extern long compilingtime; /* accumulated compile time */
-
-extern int has_ext_instr_set; /* has instruction set extensions */
-
-extern bool statistics;
-
-extern int count_jit_calls;
-extern int count_methods;
-extern int count_spills;
-extern int count_pcmd_activ;
-extern int count_pcmd_drop;
-extern int count_pcmd_zero;
-extern int count_pcmd_const_store;
-extern int count_pcmd_const_alu;
-extern int count_pcmd_const_bra;
-extern int count_pcmd_load;
-extern int count_pcmd_move;
-extern int count_load_instruction;
-extern int count_pcmd_store;
-extern int count_pcmd_store_comb;
-extern int count_dup_instruction;
-extern int count_pcmd_op;
-extern int count_pcmd_mem;
-extern int count_pcmd_met;
-extern int count_pcmd_bra;
-extern int count_pcmd_table;
-extern int count_pcmd_return;
-extern int count_pcmd_returnx;
-extern int count_check_null;
-extern int count_check_bound;
-extern int count_max_basic_blocks;
-extern int count_basic_blocks;
-extern int count_max_javainstr;
-extern int count_javainstr;
-extern int count_javacodesize;
-extern int count_javaexcsize;
-extern int count_calls;
-extern int count_tryblocks;
-extern int count_code_len;
-extern int count_data_len;
-extern int count_cstub_len;
-extern int count_nstub_len;
-extern int count_max_new_stack;
-extern int count_upper_bound_new_stack;
-extern int *count_block_stack;
-extern int *count_analyse_iterations;
-extern int *count_method_bb_distribution;
-extern int *count_block_size_distribution;
-extern int *count_store_length;
-extern int *count_store_depth;
-
-
-/* global compiler variables */
-
-extern classinfo *class; /* class the compiled method belongs to */
-extern methodinfo *method; /* pointer to method info of compiled method */
-extern int mparamcount; /* number of parameters (incl. this) */
-extern u1 *mparamtypes; /* types of all parameters (TYPE_INT, ...) */
-
-extern int maxstack; /* maximal JavaVM stack size */
-extern int maxlocals; /* maximal number of local JavaVM variables */
-extern int jcodelength; /* length of JavaVM-codes */
-extern u1 *jcode; /* pointer to start of JavaVM-code */
-extern int exceptiontablelength;/* length of exception table */
-extern xtable *extable; /* pointer to start of exception table */
-extern exceptiontable *raw_extable;
-
-extern int block_count; /* number of basic blocks */
-extern basicblock *block; /* points to basic block array */
-extern int *block_index; /* a table which contains for every byte of */
- /* JavaVM code a basic block index if at this */
- /* byte there is the start of a basic block */
-
-extern int instr_count; /* number of JavaVM instructions */
-extern instruction *instr; /* points to intermediate code instructions */
-
-extern int stack_count; /* number of stack elements */
-extern stackelement *stack; /* points to intermediate code instructions */
-
-extern bool isleafmethod; /* true if a method doesn't call subroutines */
-
-extern basicblock *last_block; /* points to the end of the BB list */
-
-/* list of all classes used by the compiled method which have to be */
-/* initialised (if not already done) before execution of this method */
-extern chain *uninitializedclasses;
-
extern int stackreq[256];
+#if defined(__I386__)
+extern bool method_uses_ecx;
+extern bool method_uses_edx;
+#endif
+
+
/* function prototypes */
-methodptr jit_compile (methodinfo *m); /* compile a method with jit compiler */
+functionptr jit_compile(methodinfo *m); /* compile a method with jit compiler */
void jit_init(); /* compiler initialisation */
void jit_close(); /* compiler finalisation */
+void compile_all_class_methods(classinfo *c);
+
u1 *createcompilerstub(methodinfo *m);
u1 *createnativestub(functionptr f, methodinfo *m);