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"
31 /* global switches ************************************************************/
33 bool compileverbose = false;
34 bool showstack = false;
35 bool showdisassemble = false;
36 bool showddatasegment = false;
37 bool showintermediate = false;
38 int optimizelevel = 0;
40 bool checkbounds = true;
41 bool checknull = true;
42 bool checkfloats = true;
43 bool checksync = true;
45 bool getcompilingtime = false;
46 long compilingtime = 0;
48 int has_ext_instr_set = 0;
50 bool statistics = false;
52 int count_jit_calls = 0;
53 int count_methods = 0;
55 int count_pcmd_activ = 0;
56 int count_pcmd_drop = 0;
57 int count_pcmd_zero = 0;
58 int count_pcmd_const_store = 0;
59 int count_pcmd_const_alu = 0;
60 int count_pcmd_const_bra = 0;
61 int count_pcmd_load = 0;
62 int count_pcmd_move = 0;
63 int count_load_instruction = 0;
64 int count_pcmd_store = 0;
65 int count_pcmd_store_comb = 0;
66 int count_dup_instruction = 0;
67 int count_pcmd_op = 0;
68 int count_pcmd_mem = 0;
69 int count_pcmd_met = 0;
70 int count_pcmd_bra = 0;
71 int count_pcmd_table = 0;
72 int count_pcmd_return = 0;
73 int count_pcmd_returnx = 0;
74 int count_check_null = 0;
75 int count_check_bound = 0;
76 int count_max_basic_blocks = 0;
77 int count_basic_blocks = 0;
78 int count_javainstr = 0;
79 int count_max_javainstr = 0;
80 int count_javacodesize = 0;
81 int count_javaexcsize = 0;
83 int count_tryblocks = 0;
84 int count_code_len = 0;
85 int count_data_len = 0;
86 int count_cstub_len = 0;
87 int count_nstub_len = 0;
88 int count_max_new_stack = 0;
89 int count_upper_bound_new_stack = 0;
90 static int count_block_stack_init[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
91 int *count_block_stack = count_block_stack_init;
92 static int count_analyse_iterations_init[5] = {0, 0, 0, 0, 0};
93 int *count_analyse_iterations = count_analyse_iterations_init;
94 static int count_method_bb_distribution_init[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
95 int *count_method_bb_distribution = count_method_bb_distribution_init;
96 static int count_block_size_distribution_init[18] = {0, 0, 0, 0, 0,
97 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
98 int *count_block_size_distribution = count_block_size_distribution_init;
99 static int count_store_length_init[21] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
101 int *count_store_length = count_store_length_init;
102 static int count_store_depth_init[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
103 int *count_store_depth = count_store_depth_init;
106 /* include compiler data types ************************************************/
108 #include "jit/jitdef.h"
111 /* global compiler variables **************************************************/
113 /* data about the currently compiled method */
115 static classinfo *class; /* class the compiled method belongs to */
116 static methodinfo *method; /* pointer to method info of compiled method */
117 static unicode *descriptor; /* type descriptor of compiled method */
118 static u2 mparamcount; /* number of parameters (incl. this) */
119 static u1 *mparamtypes; /* types of all parameters (TYPE_INT, ...) */
120 static u2 mreturntype; /* return type of method */
122 static int maxstack; /* maximal JavaVM stack size */
123 static int maxlocals; /* maximal number of local JavaVM variables */
124 static int jcodelength; /* length of JavaVM-codes */
125 static u1 *jcode; /* pointer to start of JavaVM-code */
126 static int exceptiontablelength;/* length of exception table */
127 static exceptiontable *extable; /* pointer to start of exception table */
129 static int block_count; /* number of basic blocks */
130 static basicblock *block; /* points to basic block array */
131 static int *block_index; /* a table which contains for every byte of */
132 /* JavaVM code a basic block index if at this */
133 /* byte there is the start of a basic block */
135 static int instr_count; /* number of JavaVM instructions */
136 static instruction *instr; /* points to intermediate code instructions */
138 static int stack_count; /* number of stack elements */
139 static stackelement *stack; /* points to intermediate code instructions */
141 static bool isleafmethod; /* true if a method doesn't call subroutines */
143 /* list of all classes used by the compiled method which have to be */
144 /* initialised (if not already done) before execution of this method */
146 static chain *uninitializedclasses;
149 /* include compiler subsystems ************************************************/
151 #include "sysdep/ngen.h" /* code generator header file */
152 #include "sysdep/disass.c" /* disassembler (for debug purposes only) */
153 #include "jit/mcode.c" /* code generation tool functions */
154 #include "jit/parse.c" /* parsing of JavaVM code */
155 #include "jit/reg.c" /* register allocation and support routines */
156 #include "jit/stack.c" /* analysing the stack operations */
157 #include "sysdep/ngen.c" /* code generator */
162 /* dummy function, used when there is no JavaVM code available */
164 static void* do_nothing_function()
171 extern bool newcompiler;
172 methodptr compiler_compile (methodinfo *m); /* compile method with old compiler*/
176 /* jit_compile *****************************************************************
178 jit_compile, new version of compiler, translates one method to machine code
180 *******************************************************************************/
182 methodptr jit_compile(methodinfo *m)
190 return compiler_compile(m);
194 /* if method has been already compiled return immediately */
199 return m->entrypoint;
203 intsDisable(); /* disable interrupts */
206 /* mark start of dump memory area */
208 dumpsize = dump_size ();
212 if (getcompilingtime)
213 starttime = getcputime();
215 /* if there is no javacode print error message and return empty method */
218 sprintf(logtext, "No code given for: ");
219 unicode_sprint(logtext+strlen(logtext), m->class->name);
220 strcpy(logtext+strlen(logtext), ".");
221 unicode_sprint(logtext+strlen(logtext), m->name);
222 unicode_sprint(logtext+strlen(logtext), m->descriptor);
224 intsRestore(); /* enable interrupts again */
225 return (methodptr) do_nothing_function; /* return empty method */
228 /* print log message for compiled method */
230 if (compileverbose) {
231 sprintf(logtext, "Compiling: ");
232 unicode_sprint(logtext+strlen(logtext), m->class->name);
233 strcpy(logtext+strlen(logtext), ".");
234 unicode_sprint(logtext+strlen(logtext), m->name);
235 unicode_sprint(logtext+strlen(logtext), m->descriptor);
240 /* initialisation of variables and subsystems */
246 descriptor = m->descriptor;
247 maxstack = m->maxstack;
248 maxlocals = m->maxlocals;
249 jcodelength = m->jcodelength;
251 exceptiontablelength = m->exceptiontablelength;
252 extable = m->exceptiontable;
255 count_tryblocks += exceptiontablelength;
256 count_javacodesize += jcodelength + 18;
257 count_javaexcsize += exceptiontablelength * 8;
260 /* initialise parameter type descriptor */
262 descriptor2types (m);
263 mreturntype = m->returntype;
264 mparamcount = m->paramcount;
265 mparamtypes = m->paramtypes;
267 /* initialize class list with class the compiled method belongs to */
269 uninitializedclasses = chain_new();
270 compiler_addinitclass (m->class);
273 /* call the compiler passes ***********************************************/
283 interface_regalloc();
285 allocate_scratch_registers();
292 /* intermediate and assembly code listings ********************************/
294 if (showintermediate)
296 else if (showdisassemble)
297 disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
299 if (showddatasegment)
300 dseg_display((void*) (m->mcode));
304 /* release dump area */
306 dump_release (dumpsize);
310 if (getcompilingtime) {
311 stoptime = getcputime();
312 compilingtime += (stoptime-starttime);
315 /* initialize all used classes */
316 /* because of reentrant code global variables are not allowed here */
319 chain *ul = uninitializedclasses; /* list of uninitialized classes */
320 classinfo *c; /* single class */
322 while ((c = chain_first(ul)) != NULL) {
324 class_init (c); /* may again call the compiler */
329 intsRestore(); /* enable interrupts again */
331 /* return pointer to the methods entry point */
333 return m -> entrypoint;
337 /* functions for compiler initialisation and finalisation *********************/
343 has_ext_instr_set = ! has_no_x_instr_set();
345 for (i = 0; i < 256; i++)
348 stackreq[JAVA_NOP] = 0;
349 stackreq[JAVA_ISTORE] = 0;
350 stackreq[JAVA_LSTORE] = 0;
351 stackreq[JAVA_FSTORE] = 0;
352 stackreq[JAVA_DSTORE] = 0;
353 stackreq[JAVA_ASTORE] = 0;
354 stackreq[JAVA_ISTORE_0] = 0;
355 stackreq[JAVA_ISTORE_1] = 0;
356 stackreq[JAVA_ISTORE_2] = 0;
357 stackreq[JAVA_ISTORE_3] = 0;
358 stackreq[JAVA_LSTORE_0] = 0;
359 stackreq[JAVA_LSTORE_1] = 0;
360 stackreq[JAVA_LSTORE_2] = 0;
361 stackreq[JAVA_LSTORE_3] = 0;
362 stackreq[JAVA_FSTORE_0] = 0;
363 stackreq[JAVA_FSTORE_1] = 0;
364 stackreq[JAVA_FSTORE_2] = 0;
365 stackreq[JAVA_FSTORE_3] = 0;
366 stackreq[JAVA_DSTORE_0] = 0;
367 stackreq[JAVA_DSTORE_1] = 0;
368 stackreq[JAVA_DSTORE_2] = 0;
369 stackreq[JAVA_DSTORE_3] = 0;
370 stackreq[JAVA_ASTORE_0] = 0;
371 stackreq[JAVA_ASTORE_1] = 0;
372 stackreq[JAVA_ASTORE_2] = 0;
373 stackreq[JAVA_ASTORE_3] = 0;
374 stackreq[JAVA_IASTORE] = 0;
375 stackreq[JAVA_LASTORE] = 0;
376 stackreq[JAVA_FASTORE] = 0;
377 stackreq[JAVA_DASTORE] = 0;
378 stackreq[JAVA_AASTORE] = 0;
379 stackreq[JAVA_BASTORE] = 0;
380 stackreq[JAVA_CASTORE] = 0;
381 stackreq[JAVA_SASTORE] = 0;
382 stackreq[JAVA_POP] = 0;
383 stackreq[JAVA_POP2] = 0;
384 stackreq[JAVA_IINC] = 0;
385 stackreq[JAVA_IFEQ] = 0;
386 stackreq[JAVA_IFNE] = 0;
387 stackreq[JAVA_IFLT] = 0;
388 stackreq[JAVA_IFGE] = 0;
389 stackreq[JAVA_IFGT] = 0;
390 stackreq[JAVA_IFLE] = 0;
391 stackreq[JAVA_IF_ICMPEQ] = 0;
392 stackreq[JAVA_IF_ICMPNE] = 0;
393 stackreq[JAVA_IF_ICMPLT] = 0;
394 stackreq[JAVA_IF_ICMPGE] = 0;
395 stackreq[JAVA_IF_ICMPGT] = 0;
396 stackreq[JAVA_IF_ICMPLE] = 0;
397 stackreq[JAVA_IF_ACMPEQ] = 0;
398 stackreq[JAVA_IF_ACMPNE] = 0;
399 stackreq[JAVA_GOTO] = 0;
400 stackreq[JAVA_RET] = 0;
401 stackreq[JAVA_TABLESWITCH] = 0;
402 stackreq[ICMD_LOOKUPSWITCH] = 0;
403 stackreq[JAVA_IRETURN] = 0;
404 stackreq[JAVA_LRETURN] = 0;
405 stackreq[JAVA_FRETURN] = 0;
406 stackreq[JAVA_DRETURN] = 0;
407 stackreq[JAVA_ARETURN] = 0;
408 stackreq[JAVA_RETURN] = 0;
409 stackreq[JAVA_PUTSTATIC] = 0;
410 stackreq[JAVA_PUTFIELD] = 0;
411 stackreq[JAVA_MONITORENTER] = 0;
412 stackreq[ICMD_MONITOREXIT] = 0;
413 stackreq[JAVA_WIDE] = 0;
414 stackreq[JAVA_IFNULL] = 0;
415 stackreq[JAVA_IFNONNULL] = 0;
416 stackreq[JAVA_GOTO_W] = 0;
417 stackreq[JAVA_BREAKPOINT] = 0;
419 stackreq[JAVA_SWAP] = 2;
420 stackreq[JAVA_DUP2] = 2;
421 stackreq[JAVA_DUP_X1] = 3;
422 stackreq[JAVA_DUP_X2] = 4;
423 stackreq[JAVA_DUP2_X1] = 3;
424 stackreq[JAVA_DUP2_X2] = 4;
426 for (i = 0; i < 256; i++) stdopdescriptors[i] = NULL;
428 for (i = 0; i < sizeof(stdopdescriptortable)/sizeof(stdopdescriptor); i++) {
430 if (stdopdescriptortable[i].isfloat && checkfloats) {
431 stdopdescriptortable[i].supported = false;
434 stdopdescriptors[stdopdescriptortable[i].opcode] =
435 &(stdopdescriptortable[i]);
450 * These are local overrides for various environment variables in Emacs.
451 * Please do not remove this and leave it at the end of the file, where
452 * Emacs will automagically detect them.
453 * ---------------------------------------------------------------------
456 * indent-tabs-mode: t