f204dc7e5c48b2c175b5f0a66cd147a5c1746a22
[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: 1997/11/05
15
16 *******************************************************************************/
17
18 #include <signal.h>
19
20 #include "global.h"
21 #include "tables.h"
22 #include "loader.h"
23 #include "jit.h"
24 #include "builtin.h"
25 #include "native.h"
26 #include "asmpart.h"
27
28 #include "threads/thread.h"
29
30 /* include compiler data types ************************************************/ 
31
32 #include "jit/jitdef.h"
33 #include "narray/loop.h"
34
35
36 /* global switches ************************************************************/
37 int num_compiled_m = 0;
38 int myCount;
39
40 bool compileverbose =  false;
41 bool showstack = false;
42 bool showdisassemble = false; 
43 bool showddatasegment = false; 
44 bool showintermediate = false;
45 int  optimizelevel = 0;
46
47 bool useinlining = false;
48 bool inlinevirtuals = false;
49 bool inlineexceptions = false;
50 bool inlineparamopt = false;
51 bool inlineoutsiders = false;
52
53 bool checkbounds = true;
54 bool checknull = true;
55 bool checkfloats = true;
56 bool checksync = true;
57 bool opt_loops = false;
58
59 bool getcompilingtime = false;
60 long compilingtime = 0;
61
62 int  has_ext_instr_set = 0;
63
64 bool statistics = false;         
65
66 int count_jit_calls = 0;
67 int count_methods = 0;
68 int count_spills = 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;
96 int count_calls = 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;
118
119
120
121 /* global compiler variables **************************************************/
122
123                                 /* data about the currently compiled method   */
124
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                      */
131         
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;
139
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   */
145
146 static int instr_count;         /* number of JavaVM instructions              */
147 static instruction *instr;      /* points to intermediate code instructions   */
148
149 static int stack_count;         /* number of stack elements                   */
150 static stackelement *stack;     /* points to intermediate code instructions   */
151
152 static bool isleafmethod;       /* true if a method doesn't call subroutines  */
153
154 static basicblock *last_block;  /* points to the end of the BB list           */
155
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          */
158
159 static chain *uninitializedclasses;  
160                                 
161
162 /* include compiler subsystems ************************************************/
163
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                        */
175
176
177 /* dummy function, used when there is no JavaVM code available                */
178
179 static void* do_nothing_function() 
180 {
181         return NULL;
182 }
183
184
185 #ifdef OLD_COMPILER
186 extern bool newcompiler;
187 methodptr compiler_compile (methodinfo *m); /* compile method with old compiler*/
188 #endif
189
190
191 /* jit_compile *****************************************************************
192
193         jit_compile, new version of compiler, translates one method to machine code
194
195 *******************************************************************************/
196
197 methodptr jit_compile(methodinfo *m)
198 {
199         int  dumpsize, i, j, k;
200         long starttime = 0;
201         long stoptime  = 0;
202         basicblock *b;
203         instruction *ip;
204         stackptr sp;
205
206         basicblock *bptr;
207         stackptr sptr;
208         int cnt;
209
210
211
212 #ifdef OLD_COMPILER
213         if (!newcompiler) {
214                 return compiler_compile(m);
215                 }
216 #endif
217
218         /* if method has been already compiled return immediately */
219
220         count_jit_calls++;
221
222         if (m->entrypoint)
223                 return m->entrypoint;
224
225         count_methods++;
226
227         intsDisable();      /* disable interrupts */
228         
229
230         /* mark start of dump memory area */
231
232         dumpsize = dump_size ();
233
234         /* measure time */
235
236         if (getcompilingtime)
237                 starttime = getcputime();
238
239         /* if there is no javacode print error message and return empty method    */
240
241         if (! m->jcode) {
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);
247                 dolog();
248                 intsRestore();                             /* enable interrupts again */
249                 return (methodptr) do_nothing_function;    /* return empty method     */
250                 }
251
252         /* print log message for compiled method */
253
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);
260                 dolog ();
261                 }
262
263
264         /* initialisation of variables and subsystems */
265
266         isleafmethod = true;
267
268         method = m;
269         class = m->class;
270         descriptor = m->descriptor;
271         maxstack = m->maxstack;
272         maxlocals = m->maxlocals;
273         jcodelength = m->jcodelength;
274         jcode = m->jcode;
275         exceptiontablelength = m->exceptiontablelength;
276         raw_extable = m->exceptiontable;
277
278 #ifdef STATISTICS
279         count_tryblocks += exceptiontablelength;
280         count_javacodesize += jcodelength + 18;
281         count_javaexcsize += exceptiontablelength * POINTERSIZE;
282 #endif
283
284         /* initialise parameter type descriptor */
285
286         descriptor2types (m);
287         mreturntype = m->returntype;
288         mparamcount = m->paramcount;
289         mparamtypes = m->paramtypes;
290
291         /* initialize class list with class the compiled method belongs to */
292
293         uninitializedclasses = chain_new(); 
294         compiler_addinitclass (m->class);
295
296
297         /* call the compiler passes ***********************************************/
298         
299         reg_init();
300
301         if (useinlining) inlining_init();
302
303         local_init();
304
305         mcode_init();
306
307         parse();
308
309         analyse_stack();
310    
311         if (opt_loops) {
312                 depthFirst();                   
313 #ifdef LOOP_DEBUG
314                 resultPass1();                  
315                 fflush(stdout);
316 #endif 
317                 analyseGraph();         
318 #ifdef LOOP_DEBUG
319                 resultPass2(); 
320                 fflush(stdout);
321 #endif 
322                 optimize_loops();
323 #ifdef LOOP_DEBUG
324                 /* resultPass3(); */
325 #endif 
326         }
327    
328 #ifdef SPECIALMEMUSE
329         preregpass();
330 #endif
331         
332 #ifdef LOOP_DEBUG
333         printf("Allocating registers  ");
334         fflush(stdout);
335 #endif 
336         interface_regalloc();
337 #ifdef LOOP_DEBUG
338         printf(".");
339         fflush(stdout);
340 #endif 
341         allocate_scratch_registers();
342 #ifdef LOOP_DEBUG
343         printf(".");
344         fflush(stdout); 
345 #endif 
346         local_regalloc();
347 #ifdef LOOP_DEBUG
348         printf(". done\n");
349
350         printf("Generating MCode ... ");
351         fflush(stdout);
352 #endif 
353         gen_mcode();
354 #ifdef LOOP_DEBUG
355         printf("done\n");
356         fflush(stdout);
357 #endif 
358
359         /* intermediate and assembly code listings ********************************/
360                 
361         if (showintermediate)
362                 show_icmd_method();
363         else if (showdisassemble)
364                 disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
365
366         if (showddatasegment)
367                 dseg_display((void*) (m->mcode));
368
369         /* release dump area */
370
371         dump_release (dumpsize);
372
373         /* measure time */
374
375         if (getcompilingtime) {
376                 stoptime = getcputime();
377                 compilingtime += (stoptime-starttime); 
378                 }
379
380         /* initialize all used classes */
381         /* because of reentrant code global variables are not allowed here        */
382
383         {
384         chain *ul = uninitializedclasses;   /* list of uninitialized classes      */ 
385         classinfo *c;                       /* single class                       */
386
387         while ((c = chain_first(ul)) != NULL) {
388                 chain_remove (ul);
389                 class_init (c);                         /* may again call the compiler        */
390                 }
391         chain_free (ul);
392         }
393
394         intsRestore();    /* enable interrupts again */
395
396         /* return pointer to the methods entry point */
397         
398         return m -> entrypoint;
399
400
401 /* functions for compiler initialisation and finalisation *********************/
402
403 #ifdef USEBUILTINTABLE
404 static int stdopcompare(const void *a, const void *b)
405 {
406         stdopdescriptor *o1 = (stdopdescriptor *) a;
407         stdopdescriptor *o2 = (stdopdescriptor *) b;
408         return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode);
409 }
410
411 static inline void testsort()
412 {
413         int len;
414
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);
419 }
420 #endif
421
422 void jit_init ()
423 {
424         int i;
425
426 #ifdef USEBUILTINTABLE
427         testsort();
428 #endif
429
430 #if defined(__ALPHA__)
431         has_ext_instr_set = ! has_no_x_instr_set();
432 #endif
433
434         for (i = 0; i < 256; i++)
435                 stackreq[i] = 1;
436
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;
507
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;
514         
515         for (i = 0; i < 256; i++) stdopdescriptors[i] = NULL;
516
517         for (i = 0; i < sizeof(stdopdescriptortable)/sizeof(stdopdescriptor); i++) {
518                 
519                 if (stdopdescriptortable[i].isfloat && checkfloats) {
520                         stdopdescriptortable[i].supported = false;
521                         }
522
523                 stdopdescriptors[stdopdescriptortable[i].opcode] = 
524                    &(stdopdescriptortable[i]);
525                 }
526
527         init_exceptions();
528 }
529
530
531 void jit_close()
532 {
533         mcode_close();
534         reg_close();
535 }
536
537
538 /*
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  * ---------------------------------------------------------------------
543  * Local variables:
544  * mode: c
545  * indent-tabs-mode: t
546  * c-basic-offset: 4
547  * tab-width: 4
548  * End:
549  */