Also check for printing floats correctly (fp test)
[cacao.git] / jit.c
1 /* jit.c ***********************************************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties.
6
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.
10
11         Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
12                  Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
13
14         Last Change: $Id: jit.c 528 2003-10-23 20:48:19Z stefan $
15
16 *******************************************************************************/
17
18 #include "global.h"    /* we define _GNU_SOURCE there */
19
20 #include <signal.h>
21
22 #include "tables.h"
23 #include "loader.h"
24 #include "jit.h"
25 #include "builtin.h"
26 #include "native.h"
27 #include "asmpart.h"
28
29 #include "threads/thread.h"
30
31 /* include compiler data types ************************************************/ 
32
33 #include "jit/jitdef.h"
34 #include "narray/loop.h"
35
36
37 /* global switches ************************************************************/
38 int num_compiled_m = 0;
39 int myCount;
40
41 bool compileverbose =  false;
42 bool showstack = false;
43 bool showdisassemble = false; 
44 bool showddatasegment = false; 
45 bool showintermediate = false;
46 int  optimizelevel = 0;
47
48 bool useinlining = false;
49 bool inlinevirtuals = false;
50 bool inlineexceptions = false;
51 bool inlineparamopt = false;
52 bool inlineoutsiders = false;
53
54 bool checkbounds = true;
55 bool checknull = true;
56 bool checkfloats = true;
57 bool checksync = true;
58 bool opt_loops = false;
59
60 bool getcompilingtime = false;
61 long compilingtime = 0;
62
63 int  has_ext_instr_set = 0;
64
65 bool statistics = false;         
66
67 int count_jit_calls = 0;
68 int count_methods = 0;
69 int count_spills = 0;
70 int count_pcmd_activ = 0;
71 int count_pcmd_drop = 0;
72 int count_pcmd_zero = 0;
73 int count_pcmd_const_store = 0;
74 int count_pcmd_const_alu = 0;
75 int count_pcmd_const_bra = 0;
76 int count_pcmd_load = 0;
77 int count_pcmd_move = 0;
78 int count_load_instruction = 0;
79 int count_pcmd_store = 0;
80 int count_pcmd_store_comb = 0;
81 int count_dup_instruction = 0;
82 int count_pcmd_op = 0;
83 int count_pcmd_mem = 0;
84 int count_pcmd_met = 0;
85 int count_pcmd_bra = 0;
86 int count_pcmd_table = 0;
87 int count_pcmd_return = 0;
88 int count_pcmd_returnx = 0;
89 int count_check_null = 0;
90 int count_check_bound = 0;
91 int count_max_basic_blocks = 0;
92 int count_basic_blocks = 0;
93 int count_javainstr = 0;
94 int count_max_javainstr = 0;
95 int count_javacodesize = 0;
96 int count_javaexcsize = 0;
97 int count_calls = 0;
98 int count_tryblocks = 0;
99 int count_code_len = 0;
100 int count_data_len = 0;
101 int count_cstub_len = 0;
102 int count_nstub_len = 0;
103 int count_max_new_stack = 0;
104 int count_upper_bound_new_stack = 0;
105 static int count_block_stack_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0};
106 int *count_block_stack = count_block_stack_init;
107 static int count_analyse_iterations_init[5] = {0, 0, 0, 0, 0};
108 int *count_analyse_iterations = count_analyse_iterations_init;
109 static int count_method_bb_distribution_init[9] = {0, 0, 0, 0, 0,  0, 0, 0, 0};
110 int *count_method_bb_distribution = count_method_bb_distribution_init;
111 static int count_block_size_distribution_init[18] = {0, 0, 0, 0, 0,
112         0, 0, 0, 0, 0,   0, 0, 0, 0, 0,   0, 0, 0};
113 int *count_block_size_distribution = count_block_size_distribution_init;
114 static int count_store_length_init[21] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
115                                           0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0};
116 int *count_store_length = count_store_length_init;
117 static int count_store_depth_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,   0};
118 int *count_store_depth = count_store_depth_init;
119
120
121
122 /* global compiler variables **************************************************/
123
124                                 /* data about the currently compiled method   */
125
126 static classinfo  *class;       /* class the compiled method belongs to       */
127 static methodinfo *method;      /* pointer to method info of compiled method  */
128 static utf        *descriptor;  /* type descriptor of compiled method         */
129 static int         mparamcount; /* number of parameters (incl. this)          */
130 static u1         *mparamtypes; /* types of all parameters (TYPE_INT, ...)    */
131 static int         mreturntype; /* return type of method                      */
132         
133 static int maxstack;            /* maximal JavaVM stack size                  */
134 static int maxlocals;           /* maximal number of local JavaVM variables   */
135 static int jcodelength;         /* length of JavaVM-codes                     */
136 static u1 *jcode;               /* pointer to start of JavaVM-code            */
137 static int exceptiontablelength;/* length of exception table                  */
138 static xtable *extable;         /* pointer to start of exception table        */
139 static exceptiontable *raw_extable;
140
141 static int block_count;         /* number of basic blocks                     */
142 static basicblock *block;       /* points to basic block array                */
143 static int *block_index;        /* a table which contains for every byte of   */
144                                 /* JavaVM code a basic block index if at this */
145                                 /* byte there is the start of a basic block   */
146
147 static int instr_count;         /* number of JavaVM instructions              */
148 static instruction *instr;      /* points to intermediate code instructions   */
149
150 static int stack_count;         /* number of stack elements                   */
151 static stackelement *stack;     /* points to intermediate code instructions   */
152
153 static bool isleafmethod;       /* true if a method doesn't call subroutines  */
154
155 static basicblock *last_block;  /* points to the end of the BB list           */
156
157 /* list of all classes used by the compiled method which have to be           */
158 /* initialised (if not already done) before execution of this method          */
159
160 static chain *uninitializedclasses;  
161                                 
162
163 /* include compiler subsystems ************************************************/
164
165 #include "ngen.h"        /* code generator header file                 */ 
166 #include "disass.c"      /* disassembler (for debug purposes only)     */ 
167 #include "jit/mcode.c"          /* code generation tool functions             */ 
168 #include "jit/parse.c"          /* parsing of JavaVM code                     */ 
169 #include "jit/reg.c"            /* register allocation and support routines   */ 
170 #include "jit/stack.c"          /* analysing the stack operations             */ 
171 #include "ngen.c"        /* code generator                             */ 
172 #include "narray/graph.c"       /* array bound removal                        */
173 #include "narray/loop.c"        /* array bound removal                        */
174 #include "narray/tracing.c"     /* array bound removal                        */
175 #include "narray/analyze.c"     /* array bound removal                        */
176
177
178 /* dummy function, used when there is no JavaVM code available                */
179
180 static void* do_nothing_function() 
181 {
182         return NULL;
183 }
184
185
186 /* jit_compile *****************************************************************
187
188         jit_compile, new version of compiler, translates one method to machine code
189
190 *******************************************************************************/
191
192 methodptr jit_compile(methodinfo *m)
193 {
194         int dumpsize;
195         long starttime = 0;
196         long stoptime  = 0;
197
198         count_jit_calls++;
199
200         /* if method has been already compiled return immediately */
201
202         if (m->entrypoint)
203                 return m->entrypoint;
204
205         count_methods++;
206
207         intsDisable();      /* disable interrupts */
208         
209
210         /* mark start of dump memory area */
211
212         dumpsize = dump_size ();
213
214         /* measure time */
215
216         if (getcompilingtime)
217                 starttime = getcputime();
218
219         /* if there is no javacode print error message and return empty method    */
220
221         if (! m->jcode) {
222                 sprintf(logtext, "No code given for: ");
223                 utf_sprint(logtext+strlen(logtext), m->class->name);
224                 strcpy(logtext+strlen(logtext), ".");
225                 utf_sprint(logtext+strlen(logtext), m->name);
226                 utf_sprint(logtext+strlen(logtext), m->descriptor);
227                 dolog();
228                 intsRestore();                             /* enable interrupts again */
229                 return (methodptr) do_nothing_function;    /* return empty method     */
230                 }
231
232         /* print log message for compiled method */
233
234         if (compileverbose) {
235                 sprintf(logtext, "Compiling: ");
236                 utf_sprint(logtext+strlen(logtext), m->class->name);
237                 strcpy(logtext+strlen(logtext), ".");
238                 utf_sprint(logtext+strlen(logtext), m->name);
239                 utf_sprint(logtext+strlen(logtext), m->descriptor);
240                 dolog ();
241                 }
242
243
244         /* initialisation of variables and subsystems */
245
246         isleafmethod = true;
247
248         method = m;
249         class = m->class;
250         descriptor = m->descriptor;
251         maxstack = m->maxstack;
252         maxlocals = m->maxlocals;
253         jcodelength = m->jcodelength;
254         jcode = m->jcode;
255         exceptiontablelength = m->exceptiontablelength;
256         raw_extable = m->exceptiontable;
257
258 #ifdef STATISTICS
259         count_tryblocks += exceptiontablelength;
260         count_javacodesize += jcodelength + 18;
261         count_javaexcsize += exceptiontablelength * POINTERSIZE;
262 #endif
263
264         /* initialise parameter type descriptor */
265
266         descriptor2types (m);
267         mreturntype = m->returntype;
268         mparamcount = m->paramcount;
269         mparamtypes = m->paramtypes;
270
271         /* initialize class list with class the compiled method belongs to */
272
273         uninitializedclasses = chain_new(); 
274         compiler_addinitclass (m->class);
275
276
277         /* call the compiler passes ***********************************************/
278         
279         reg_init();
280
281         if (useinlining) inlining_init();
282
283         local_init();
284
285         mcode_init();
286
287         parse();
288
289         analyse_stack();
290    
291         if (opt_loops) {
292                 depthFirst();                   
293
294 #ifdef LOOP_DEBUG
295                 resultPass1();                  
296                 fflush(stdout);
297 #endif 
298
299                 analyseGraph();         
300
301 #ifdef LOOP_DEBUG
302                 resultPass2(); 
303                 fflush(stdout);
304 #endif 
305
306                 optimize_loops();
307
308 #ifdef LOOP_DEBUG
309                 /* resultPass3(); */
310 #endif 
311         }
312    
313 #ifdef SPECIALMEMUSE
314         preregpass();
315 #endif
316         
317 #ifdef LOOP_DEBUG
318         printf("Allocating registers  ");
319         fflush(stdout);
320 #endif 
321
322         interface_regalloc();
323
324 #ifdef LOOP_DEBUG
325         printf(".");
326         fflush(stdout);
327 #endif 
328
329         allocate_scratch_registers();
330
331 #ifdef LOOP_DEBUG
332         printf(".");
333         fflush(stdout); 
334 #endif 
335
336         local_regalloc();
337
338 #ifdef LOOP_DEBUG
339         printf(". done\n");
340
341         printf("Generating MCode ... ");
342         fflush(stdout);
343 #endif 
344
345         gen_mcode();
346
347 #ifdef LOOP_DEBUG
348         printf("done\n");
349         fflush(stdout);
350 #endif 
351
352         /* intermediate and assembly code listings ********************************/
353                 
354         if (showintermediate)
355                 show_icmd_method();
356         else if (showdisassemble)
357                 disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
358
359         if (showddatasegment)
360                 dseg_display((void*) (m->mcode));
361
362         /* release dump area */
363
364         dump_release (dumpsize);
365
366         /* measure time */
367
368         if (getcompilingtime) {
369                 stoptime = getcputime();
370                 compilingtime += (stoptime-starttime); 
371                 }
372
373         /* initialize all used classes */
374         /* because of reentrant code global variables are not allowed here        */
375
376         {
377         chain *ul = uninitializedclasses;   /* list of uninitialized classes      */ 
378         classinfo *c;                       /* single class                       */
379
380         while ((c = chain_first(ul)) != NULL) {
381                 chain_remove (ul);
382                 class_init (c);                         /* may again call the compiler        */
383                 }
384         chain_free (ul);
385         }
386
387         intsRestore();    /* enable interrupts again */
388
389         /* return pointer to the methods entry point */
390         
391         return m -> entrypoint;
392
393
394 /* functions for compiler initialisation and finalisation *********************/
395
396 #ifdef USEBUILTINTABLE
397 static int stdopcompare(const void *a, const void *b)
398 {
399         stdopdescriptor *o1 = (stdopdescriptor *) a;
400         stdopdescriptor *o2 = (stdopdescriptor *) b;
401         return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
402 }
403
404 static inline void testsort()
405 {
406         int len;
407
408         len = sizeof(stdopdescriptortable)/sizeof(stdopdescriptor);
409         qsort(stdopdescriptortable, len, sizeof(stdopdescriptor), stdopcompare);
410         len = sizeof(builtintable)/sizeof(stdopdescriptor);
411         qsort(builtintable, len, sizeof(stdopdescriptor), stdopcompare);
412 }
413 #endif
414
415 void jit_init ()
416 {
417         int i;
418
419 #ifdef USEBUILTINTABLE
420         testsort();
421 #endif
422
423 #if defined(__ALPHA__)
424         has_ext_instr_set = ! has_no_x_instr_set();
425 #endif
426
427         for (i = 0; i < 256; i++)
428                 stackreq[i] = 1;
429
430         stackreq[JAVA_NOP]          = 0;
431         stackreq[JAVA_ISTORE]       = 0;
432         stackreq[JAVA_LSTORE]       = 0;
433         stackreq[JAVA_FSTORE]       = 0;
434         stackreq[JAVA_DSTORE]       = 0;
435         stackreq[JAVA_ASTORE]       = 0;
436         stackreq[JAVA_ISTORE_0]     = 0;
437         stackreq[JAVA_ISTORE_1]     = 0;
438         stackreq[JAVA_ISTORE_2]     = 0;
439         stackreq[JAVA_ISTORE_3]     = 0;
440         stackreq[JAVA_LSTORE_0]     = 0;
441         stackreq[JAVA_LSTORE_1]     = 0;
442         stackreq[JAVA_LSTORE_2]     = 0;
443         stackreq[JAVA_LSTORE_3]     = 0;
444         stackreq[JAVA_FSTORE_0]     = 0;
445         stackreq[JAVA_FSTORE_1]     = 0;
446         stackreq[JAVA_FSTORE_2]     = 0;
447         stackreq[JAVA_FSTORE_3]     = 0;
448         stackreq[JAVA_DSTORE_0]     = 0;
449         stackreq[JAVA_DSTORE_1]     = 0;
450         stackreq[JAVA_DSTORE_2]     = 0;
451         stackreq[JAVA_DSTORE_3]     = 0;
452         stackreq[JAVA_ASTORE_0]     = 0;
453         stackreq[JAVA_ASTORE_1]     = 0;
454         stackreq[JAVA_ASTORE_2]     = 0;
455         stackreq[JAVA_ASTORE_3]     = 0;
456         stackreq[JAVA_IASTORE]      = 0;
457         stackreq[JAVA_LASTORE]      = 0;
458         stackreq[JAVA_FASTORE]      = 0;
459         stackreq[JAVA_DASTORE]      = 0;
460         stackreq[JAVA_AASTORE]      = 0;
461         stackreq[JAVA_BASTORE]      = 0;
462         stackreq[JAVA_CASTORE]      = 0;
463         stackreq[JAVA_SASTORE]      = 0;
464         stackreq[JAVA_POP]          = 0;
465         stackreq[JAVA_POP2]         = 0;
466         stackreq[JAVA_IINC]         = 0;
467         stackreq[JAVA_IFEQ]         = 0;
468         stackreq[JAVA_IFNE]         = 0;
469         stackreq[JAVA_IFLT]         = 0;
470         stackreq[JAVA_IFGE]         = 0;
471         stackreq[JAVA_IFGT]         = 0;
472         stackreq[JAVA_IFLE]         = 0;
473         stackreq[JAVA_IF_ICMPEQ]    = 0;
474         stackreq[JAVA_IF_ICMPNE]    = 0;
475         stackreq[JAVA_IF_ICMPLT]    = 0;
476         stackreq[JAVA_IF_ICMPGE]    = 0;
477         stackreq[JAVA_IF_ICMPGT]    = 0;
478         stackreq[JAVA_IF_ICMPLE]    = 0;
479         stackreq[JAVA_IF_ACMPEQ]    = 0;
480         stackreq[JAVA_IF_ACMPNE]    = 0;
481         stackreq[JAVA_GOTO]         = 0;
482         stackreq[JAVA_RET]          = 0;
483         stackreq[JAVA_TABLESWITCH]  = 0;
484         stackreq[JAVA_LOOKUPSWITCH] = 0;
485         stackreq[JAVA_IRETURN]      = 0;
486         stackreq[JAVA_LRETURN]      = 0;
487         stackreq[JAVA_FRETURN]      = 0;
488         stackreq[JAVA_DRETURN]      = 0;
489         stackreq[JAVA_ARETURN]      = 0;
490         stackreq[JAVA_RETURN]       = 0;
491         stackreq[JAVA_PUTSTATIC]    = 0;
492         stackreq[JAVA_PUTFIELD]     = 0;
493         stackreq[JAVA_MONITORENTER] = 0;
494         stackreq[JAVA_MONITOREXIT]  = 0;
495         stackreq[JAVA_WIDE]         = 0;
496         stackreq[JAVA_IFNULL]       = 0;
497         stackreq[JAVA_IFNONNULL]    = 0;
498         stackreq[JAVA_GOTO_W]       = 0;
499         stackreq[JAVA_BREAKPOINT]   = 0;
500
501         stackreq[JAVA_SWAP] = 2;
502         stackreq[JAVA_DUP2] = 2;
503         stackreq[JAVA_DUP_X1] = 3;
504         stackreq[JAVA_DUP_X2] = 4;
505         stackreq[JAVA_DUP2_X1] = 3;
506         stackreq[JAVA_DUP2_X2] = 4;
507         
508         init_exceptions();
509 }
510
511
512 void jit_close()
513 {
514         mcode_close();
515         reg_close();
516 }
517
518
519 /*
520  * These are local overrides for various environment variables in Emacs.
521  * Please do not remove this and leave it at the end of the file, where
522  * Emacs will automagically detect them.
523  * ---------------------------------------------------------------------
524  * Local variables:
525  * mode: c
526  * indent-tabs-mode: t
527  * c-basic-offset: 4
528  * tab-width: 4
529  * End:
530  */