1 /* jit.c ***********************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties.
7 Contains the functions which translates a JavaVM method into native code.
8 This is the new version of the compiler which is a lot faster and has new
9 exception handling schemes. The main function is new_comp.
11 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
12 Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
14 Last Change: 1997/11/05
16 *******************************************************************************/
28 #include "threads/thread.h"
30 /* include compiler data types ************************************************/
32 #include "jit/jitdef.h"
33 #include "narray/loop.h"
36 /* global switches ************************************************************/
37 int num_compiled_m = 0;
40 bool compileverbose = false;
41 bool showstack = false;
42 bool showdisassemble = false;
43 bool showddatasegment = false;
44 bool showintermediate = false;
45 int optimizelevel = 0;
47 bool useinlining = false;
48 bool inlinevirtuals = false;
49 bool inlineexceptions = false;
50 bool inlineparamopt = false;
51 bool inlineoutsiders = false;
53 bool checkbounds = true;
54 bool checknull = true;
55 bool checkfloats = true;
56 bool checksync = true;
57 bool opt_loops = false;
59 bool getcompilingtime = false;
60 long compilingtime = 0;
62 int has_ext_instr_set = 0;
64 bool statistics = false;
66 int count_jit_calls = 0;
67 int count_methods = 0;
69 int count_pcmd_activ = 0;
70 int count_pcmd_drop = 0;
71 int count_pcmd_zero = 0;
72 int count_pcmd_const_store = 0;
73 int count_pcmd_const_alu = 0;
74 int count_pcmd_const_bra = 0;
75 int count_pcmd_load = 0;
76 int count_pcmd_move = 0;
77 int count_load_instruction = 0;
78 int count_pcmd_store = 0;
79 int count_pcmd_store_comb = 0;
80 int count_dup_instruction = 0;
81 int count_pcmd_op = 0;
82 int count_pcmd_mem = 0;
83 int count_pcmd_met = 0;
84 int count_pcmd_bra = 0;
85 int count_pcmd_table = 0;
86 int count_pcmd_return = 0;
87 int count_pcmd_returnx = 0;
88 int count_check_null = 0;
89 int count_check_bound = 0;
90 int count_max_basic_blocks = 0;
91 int count_basic_blocks = 0;
92 int count_javainstr = 0;
93 int count_max_javainstr = 0;
94 int count_javacodesize = 0;
95 int count_javaexcsize = 0;
97 int count_tryblocks = 0;
98 int count_code_len = 0;
99 int count_data_len = 0;
100 int count_cstub_len = 0;
101 int count_nstub_len = 0;
102 int count_max_new_stack = 0;
103 int count_upper_bound_new_stack = 0;
104 static int count_block_stack_init[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
105 int *count_block_stack = count_block_stack_init;
106 static int count_analyse_iterations_init[5] = {0, 0, 0, 0, 0};
107 int *count_analyse_iterations = count_analyse_iterations_init;
108 static int count_method_bb_distribution_init[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
109 int *count_method_bb_distribution = count_method_bb_distribution_init;
110 static int count_block_size_distribution_init[18] = {0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
112 int *count_block_size_distribution = count_block_size_distribution_init;
113 static int count_store_length_init[21] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
115 int *count_store_length = count_store_length_init;
116 static int count_store_depth_init[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
117 int *count_store_depth = count_store_depth_init;
121 /* global compiler variables **************************************************/
123 /* data about the currently compiled method */
125 static classinfo *class; /* class the compiled method belongs to */
126 static methodinfo *method; /* pointer to method info of compiled method */
127 static utf *descriptor; /* type descriptor of compiled method */
128 static int mparamcount; /* number of parameters (incl. this) */
129 static u1 *mparamtypes; /* types of all parameters (TYPE_INT, ...) */
130 static int mreturntype; /* return type of method */
132 static int maxstack; /* maximal JavaVM stack size */
133 static int maxlocals; /* maximal number of local JavaVM variables */
134 static int jcodelength; /* length of JavaVM-codes */
135 static u1 *jcode; /* pointer to start of JavaVM-code */
136 static int exceptiontablelength;/* length of exception table */
137 static xtable *extable; /* pointer to start of exception table */
138 static exceptiontable *raw_extable;
140 static int block_count; /* number of basic blocks */
141 static basicblock *block; /* points to basic block array */
142 static int *block_index; /* a table which contains for every byte of */
143 /* JavaVM code a basic block index if at this */
144 /* byte there is the start of a basic block */
146 static int instr_count; /* number of JavaVM instructions */
147 static instruction *instr; /* points to intermediate code instructions */
149 static int stack_count; /* number of stack elements */
150 static stackelement *stack; /* points to intermediate code instructions */
152 static bool isleafmethod; /* true if a method doesn't call subroutines */
154 static basicblock *last_block; /* points to the end of the BB list */
156 /* list of all classes used by the compiled method which have to be */
157 /* initialised (if not already done) before execution of this method */
159 static chain *uninitializedclasses;
162 /* include compiler subsystems ************************************************/
164 #include "ngen.h" /* code generator header file */
165 #include "disass.c" /* disassembler (for debug purposes only) */
166 #include "jit/mcode.c" /* code generation tool functions */
167 #include "jit/parse.c" /* parsing of JavaVM code */
168 #include "jit/reg.c" /* register allocation and support routines */
169 #include "jit/stack.c" /* analysing the stack operations */
170 #include "ngen.c" /* code generator */
171 #include "narray/graph.c" /* array bound removal */
172 #include "narray/loop.c" /* array bound removal */
173 #include "narray/tracing.c" /* array bound removal */
174 #include "narray/analyze.c" /* array bound removal */
177 /* dummy function, used when there is no JavaVM code available */
179 static void* do_nothing_function()
186 extern bool newcompiler;
187 methodptr compiler_compile (methodinfo *m); /* compile method with old compiler*/
191 /* jit_compile *****************************************************************
193 jit_compile, new version of compiler, translates one method to machine code
195 *******************************************************************************/
197 methodptr jit_compile(methodinfo *m)
199 int dumpsize, i, j, k;
214 return compiler_compile(m);
218 /* if method has been already compiled return immediately */
223 return m->entrypoint;
227 intsDisable(); /* disable interrupts */
230 /* mark start of dump memory area */
232 dumpsize = dump_size ();
236 if (getcompilingtime)
237 starttime = getcputime();
239 /* if there is no javacode print error message and return empty method */
242 sprintf(logtext, "No code given for: ");
243 utf_sprint(logtext+strlen(logtext), m->class->name);
244 strcpy(logtext+strlen(logtext), ".");
245 utf_sprint(logtext+strlen(logtext), m->name);
246 utf_sprint(logtext+strlen(logtext), m->descriptor);
248 intsRestore(); /* enable interrupts again */
249 return (methodptr) do_nothing_function; /* return empty method */
252 /* print log message for compiled method */
254 if (compileverbose) {
255 sprintf(logtext, "Compiling: ");
256 utf_sprint(logtext+strlen(logtext), m->class->name);
257 strcpy(logtext+strlen(logtext), ".");
258 utf_sprint(logtext+strlen(logtext), m->name);
259 utf_sprint(logtext+strlen(logtext), m->descriptor);
264 /* initialisation of variables and subsystems */
270 descriptor = m->descriptor;
271 maxstack = m->maxstack;
272 maxlocals = m->maxlocals;
273 jcodelength = m->jcodelength;
275 exceptiontablelength = m->exceptiontablelength;
276 raw_extable = m->exceptiontable;
279 count_tryblocks += exceptiontablelength;
280 count_javacodesize += jcodelength + 18;
281 count_javaexcsize += exceptiontablelength * POINTERSIZE;
284 /* initialise parameter type descriptor */
286 descriptor2types (m);
287 mreturntype = m->returntype;
288 mparamcount = m->paramcount;
289 mparamtypes = m->paramtypes;
291 /* initialize class list with class the compiled method belongs to */
293 uninitializedclasses = chain_new();
294 compiler_addinitclass (m->class);
297 /* call the compiler passes ***********************************************/
301 if (useinlining) inlining_init();
333 printf("Allocating registers ");
336 interface_regalloc();
341 allocate_scratch_registers();
350 printf("Generating MCode ... ");
359 /* intermediate and assembly code listings ********************************/
361 if (showintermediate)
363 else if (showdisassemble)
364 disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
366 if (showddatasegment)
367 dseg_display((void*) (m->mcode));
369 /* release dump area */
371 dump_release (dumpsize);
375 if (getcompilingtime) {
376 stoptime = getcputime();
377 compilingtime += (stoptime-starttime);
380 /* initialize all used classes */
381 /* because of reentrant code global variables are not allowed here */
384 chain *ul = uninitializedclasses; /* list of uninitialized classes */
385 classinfo *c; /* single class */
387 while ((c = chain_first(ul)) != NULL) {
389 class_init (c); /* may again call the compiler */
394 intsRestore(); /* enable interrupts again */
396 /* return pointer to the methods entry point */
398 return m -> entrypoint;
401 /* functions for compiler initialisation and finalisation *********************/
403 #ifdef USEBUILTINTABLE
404 static int stdopcompare(const void *a, const void *b)
406 stdopdescriptor *o1 = (stdopdescriptor *) a;
407 stdopdescriptor *o2 = (stdopdescriptor *) b;
408 return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
411 static inline void testsort()
415 len = sizeof(stdopdescriptortable)/sizeof(stdopdescriptor);
416 qsort(stdopdescriptortable, len, sizeof(stdopdescriptor), stdopcompare);
417 len = sizeof(builtintable)/sizeof(stdopdescriptor);
418 qsort(builtintable, len, sizeof(stdopdescriptor), stdopcompare);
426 #ifdef USEBUILTINTABLE
430 #if defined(__ALPHA__)
431 has_ext_instr_set = ! has_no_x_instr_set();
434 for (i = 0; i < 256; i++)
437 stackreq[JAVA_NOP] = 0;
438 stackreq[JAVA_ISTORE] = 0;
439 stackreq[JAVA_LSTORE] = 0;
440 stackreq[JAVA_FSTORE] = 0;
441 stackreq[JAVA_DSTORE] = 0;
442 stackreq[JAVA_ASTORE] = 0;
443 stackreq[JAVA_ISTORE_0] = 0;
444 stackreq[JAVA_ISTORE_1] = 0;
445 stackreq[JAVA_ISTORE_2] = 0;
446 stackreq[JAVA_ISTORE_3] = 0;
447 stackreq[JAVA_LSTORE_0] = 0;
448 stackreq[JAVA_LSTORE_1] = 0;
449 stackreq[JAVA_LSTORE_2] = 0;
450 stackreq[JAVA_LSTORE_3] = 0;
451 stackreq[JAVA_FSTORE_0] = 0;
452 stackreq[JAVA_FSTORE_1] = 0;
453 stackreq[JAVA_FSTORE_2] = 0;
454 stackreq[JAVA_FSTORE_3] = 0;
455 stackreq[JAVA_DSTORE_0] = 0;
456 stackreq[JAVA_DSTORE_1] = 0;
457 stackreq[JAVA_DSTORE_2] = 0;
458 stackreq[JAVA_DSTORE_3] = 0;
459 stackreq[JAVA_ASTORE_0] = 0;
460 stackreq[JAVA_ASTORE_1] = 0;
461 stackreq[JAVA_ASTORE_2] = 0;
462 stackreq[JAVA_ASTORE_3] = 0;
463 stackreq[JAVA_IASTORE] = 0;
464 stackreq[JAVA_LASTORE] = 0;
465 stackreq[JAVA_FASTORE] = 0;
466 stackreq[JAVA_DASTORE] = 0;
467 stackreq[JAVA_AASTORE] = 0;
468 stackreq[JAVA_BASTORE] = 0;
469 stackreq[JAVA_CASTORE] = 0;
470 stackreq[JAVA_SASTORE] = 0;
471 stackreq[JAVA_POP] = 0;
472 stackreq[JAVA_POP2] = 0;
473 stackreq[JAVA_IINC] = 0;
474 stackreq[JAVA_IFEQ] = 0;
475 stackreq[JAVA_IFNE] = 0;
476 stackreq[JAVA_IFLT] = 0;
477 stackreq[JAVA_IFGE] = 0;
478 stackreq[JAVA_IFGT] = 0;
479 stackreq[JAVA_IFLE] = 0;
480 stackreq[JAVA_IF_ICMPEQ] = 0;
481 stackreq[JAVA_IF_ICMPNE] = 0;
482 stackreq[JAVA_IF_ICMPLT] = 0;
483 stackreq[JAVA_IF_ICMPGE] = 0;
484 stackreq[JAVA_IF_ICMPGT] = 0;
485 stackreq[JAVA_IF_ICMPLE] = 0;
486 stackreq[JAVA_IF_ACMPEQ] = 0;
487 stackreq[JAVA_IF_ACMPNE] = 0;
488 stackreq[JAVA_GOTO] = 0;
489 stackreq[JAVA_RET] = 0;
490 stackreq[JAVA_TABLESWITCH] = 0;
491 stackreq[JAVA_LOOKUPSWITCH] = 0;
492 stackreq[JAVA_IRETURN] = 0;
493 stackreq[JAVA_LRETURN] = 0;
494 stackreq[JAVA_FRETURN] = 0;
495 stackreq[JAVA_DRETURN] = 0;
496 stackreq[JAVA_ARETURN] = 0;
497 stackreq[JAVA_RETURN] = 0;
498 stackreq[JAVA_PUTSTATIC] = 0;
499 stackreq[JAVA_PUTFIELD] = 0;
500 stackreq[JAVA_MONITORENTER] = 0;
501 stackreq[JAVA_MONITOREXIT] = 0;
502 stackreq[JAVA_WIDE] = 0;
503 stackreq[JAVA_IFNULL] = 0;
504 stackreq[JAVA_IFNONNULL] = 0;
505 stackreq[JAVA_GOTO_W] = 0;
506 stackreq[JAVA_BREAKPOINT] = 0;
508 stackreq[JAVA_SWAP] = 2;
509 stackreq[JAVA_DUP2] = 2;
510 stackreq[JAVA_DUP_X1] = 3;
511 stackreq[JAVA_DUP_X2] = 4;
512 stackreq[JAVA_DUP2_X1] = 3;
513 stackreq[JAVA_DUP2_X2] = 4;
515 for (i = 0; i < 256; i++) stdopdescriptors[i] = NULL;
517 for (i = 0; i < sizeof(stdopdescriptortable)/sizeof(stdopdescriptor); i++) {
519 if (stdopdescriptortable[i].isfloat && checkfloats) {
520 stdopdescriptortable[i].supported = false;
523 stdopdescriptors[stdopdescriptortable[i].opcode] =
524 &(stdopdescriptortable[i]);
539 * These are local overrides for various environment variables in Emacs.
540 * Please do not remove this and leave it at the end of the file, where
541 * Emacs will automagically detect them.
542 * ---------------------------------------------------------------------
545 * indent-tabs-mode: t